]> granicus.if.org Git - procps-ng/commitdiff
library: make dynamic buffer management more efficient
authorJim Warner <james.warner@comcast.net>
Fri, 29 Mar 2013 05:00:00 +0000 (00:00 -0500)
committerCraig Small <csmall@enc.com.au>
Sun, 7 Apr 2013 07:35:49 +0000 (17:35 +1000)
When dynamic buffers were recently introduced for read
of the status, stat and statm subdirectories one extra
call to read() was required for end-of-file detection.

This patch avoids most all such extra calls to read().

Additionally, the frequency of memory reallocations is
reduced by overallocating each increase more than 25%.

Reference)s):
commit a45dace4b82c9cdcda7020ca5665153b1e81275f

Signed-off-by: Jim Warner <james.warner@comcast.net>
Signed-off-by: Craig Small <csmall@enc.com.au>
proc/readproc.c

index 652dc30e5ceb05ebb278c78c333de75507fc9050..d4210a73d996723ce1f6bbd2bc02655d093947f0 100644 (file)
@@ -534,28 +534,31 @@ static void statm2proc(const char* s, proc_t *restrict P) {
 
 static int file2str(const char *directory, const char *what, struct utlbuf_s *ub) {
  #define readMAX  4096
- #define buffMIN (tot_read + num + 1)  // +1 for the '\0' delimiter
+ #define buffMIN (tot_read + num + 1)       // +1 for the '\0' delimiter
+ #define buffGRW (30 + (buffMIN * 5) / 4)   // grow by more than 25%
     char path[PROCPATHLEN], chunk[readMAX];
-    int fd, num, tot_read = 0;
+    int fd, num, eof = 0, tot_read = 0;
 
     /* on first use we preallocate a buffer of minimum size to emulate
        former 'local static' behavior -- even if this read fails, that
-       buffer will likely soon be used for another sudirectory anyway */
+       buffer will likely soon be used for another subdirectory anyway */
     if (ub->buf) ub->buf[0] = '\0';
     else ub->buf = xcalloc((ub->siz = readMAX));
     sprintf(path, "%s/%s", directory, what);
     if (-1 == (fd = open(path, O_RDONLY, 0))) return -1;
-    while (0 < (num = read(fd, chunk, readMAX))) {
+    while (!eof && 0 < (num = read(fd, chunk, readMAX))) {
         if (ub->siz < buffMIN)
-            ub->buf = xrealloc(ub->buf, (ub->siz = buffMIN));
+            ub->buf = xrealloc(ub->buf, (ub->siz = buffGRW));
         memcpy(ub->buf + tot_read, chunk, num);
         tot_read += num;
+        eof = (num < readMAX);
     };
     ub->buf[tot_read] = '\0';
     close(fd);
     return tot_read;
  #undef readMAX
  #undef buffMIN
+ #undef buffGRW
 }
 
 static char** file2strvec(const char* directory, const char* what) {