diff options
-rw-r--r-- | procps/top.c | 119 |
1 files changed, 42 insertions, 77 deletions
diff --git a/procps/top.c b/procps/top.c index e4afafc4c..51b167171 100644 --- a/procps/top.c +++ b/procps/top.c @@ -696,111 +696,76 @@ static int topmem_sort(char *a, char *b) return inverted ? -n : n; } -/* Cut "NNNN" out of " NNNN kb" */ -static char *grab_number(char *str, const char *match, unsigned sz) -{ - if (strncmp(str, match, sz) == 0) { - str = skip_whitespace(str + sz); - (skip_non_whitespace(str))[0] = '\0'; - return xstrdup(str); - } - return NULL; -} - /* display header info (meminfo / loadavg) */ static void display_topmem_header(int scr_width, int *lines_rem_p) { + enum { + TOTAL = 0, MFREE, BUF, CACHE, + SWAPTOTAL, SWAPFREE, DIRTY, + MWRITE, ANON, MAP, SLAB, + NUM_FIELDS + }; + static const char match[NUM_FIELDS][11] = { + "\x09" "MemTotal:", // TOTAL + "\x08" "MemFree:", // MFREE + "\x08" "Buffers:", // BUF + "\x07" "Cached:", // CACHE + "\x0a" "SwapTotal:", // SWAPTOTAL + "\x09" "SwapFree:", // SWAPFREE + "\x06" "Dirty:", // DIRTY + "\x0a" "Writeback:", // MWRITE + "\x0a" "AnonPages:", // ANON + "\x07" "Mapped:", // MAP + "\x05" "Slab:", // SLAB + }; +//TODO? Note that fields always appear in the above order. +//Thus, as each new line read from /proc/meminfo, we can compare it *once* +//with match[last_matched+1], instead of looping thru all match[i]'s. +//If it matches, memorize its data and last_matched++ (and if == NUM_FIELDS, +//we're done with reading /proc/meminfo!); otherwise fgets next line. +//The code below is slower, but is robust against a case when /proc/meminfo +//gets reordered in the future. + char Z[NUM_FIELDS][sizeof(long long)*3]; char linebuf[128]; unsigned i; FILE *fp; - union { - struct { - /* 1 */ char *total; - /* 2 */ char *mfree; - /* 3 */ char *buf; - /* 4 */ char *cache; - /* 5 */ char *swaptotal; - /* 6 */ char *swapfree; - /* 7 */ char *dirty; - /* 8 */ char *mwrite; - /* 9 */ char *anon; - /* 10 */ char *map; - /* 11 */ char *slab; - } u; - char *str[11]; - } Z; -#define total Z.u.total -#define mfree Z.u.mfree -#define buf Z.u.buf -#define cache Z.u.cache -#define swaptotal Z.u.swaptotal -#define swapfree Z.u.swapfree -#define dirty Z.u.dirty -#define mwrite Z.u.mwrite -#define anon Z.u.anon -#define map Z.u.map -#define slab Z.u.slab -#define str Z.str memset(&Z, 0, sizeof(Z)); + for (i = 0; i < NUM_FIELDS; i++) + Z[i][0] = '?'; /* read memory info */ fp = xfopen_for_read("meminfo"); while (fgets(linebuf, sizeof(linebuf), fp)) { - char *p; - -#define SCAN(match, name) \ - p = grab_number(linebuf, match, sizeof(match)-1); \ - if (p) { name = p; continue; } - - SCAN("MemTotal:", total); - SCAN("MemFree:", mfree); - SCAN("Buffers:", buf); - SCAN("Cached:", cache); - SCAN("SwapTotal:", swaptotal); - SCAN("SwapFree:", swapfree); - SCAN("Dirty:", dirty); - SCAN("Writeback:", mwrite); - SCAN("AnonPages:", anon); - SCAN("Mapped:", map); - SCAN("Slab:", slab); -#undef SCAN + for (i = 0; i < NUM_FIELDS; i++) { + unsigned sz = (unsigned char)match[i][0]; + if (strncmp(linebuf, match[i] + 1, sz) == 0) { + /* Cut "NNNN" out of " NNNN kb" */ + char *s = skip_whitespace(linebuf + sz); + skip_non_whitespace(s)[0] = '\0'; + safe_strncpy(Z[i], s, sizeof(Z[i])); + break; + } + } } fclose(fp); -#define S(s) (s ? s : "0") snprintf(linebuf, sizeof(linebuf), "Mem total:%s anon:%s map:%s free:%s", - S(total), S(anon), S(map), S(mfree)); + Z[TOTAL], Z[ANON], Z[MAP], Z[MFREE]); printf(OPT_BATCH_MODE ? "%.*s\n" : "\033[H\033[J%.*s\n", scr_width, linebuf); snprintf(linebuf, sizeof(linebuf), " slab:%s buf:%s cache:%s dirty:%s write:%s", - S(slab), S(buf), S(cache), S(dirty), S(mwrite)); + Z[SLAB], Z[BUF], Z[CACHE], Z[DIRTY], Z[MWRITE]); printf("%.*s\n", scr_width, linebuf); snprintf(linebuf, sizeof(linebuf), "Swap total:%s free:%s", // TODO: % used? - S(swaptotal), S(swapfree)); + Z[SWAPTOTAL], Z[SWAPFREE]); printf("%.*s\n", scr_width, linebuf); (*lines_rem_p) -= 3; -#undef S - - for (i = 0; i < ARRAY_SIZE(str); i++) - free(str[i]); -#undef total -#undef free -#undef buf -#undef cache -#undef swaptotal -#undef swapfree -#undef dirty -#undef write -#undef anon -#undef map -#undef slab -#undef str } static void ulltoa6_and_space(unsigned long long ul, char buf[6]) |