[git commit master] top: code shrink

Denys Vlasenko vda.linux at googlemail.com
Sun Jun 6 06:24:39 UTC 2010


commit: http://git.busybox.net/busybox/commit/?id=87496aa08180cdfffed88f7802e46ab25f659890
branch: http://git.busybox.net/busybox/commit/?id=refs/heads/master

   text    data     bss     dec     hex filename
 853034     453    6820  860307   d2093 busybox_old
 852726     453    6820  859999   d1f5f busybox_unstripped

Signed-off-by: Maksym Kryzhanovskyy <xmaks at email.cz>
Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 procps/top.c |  119 ++++++++++++++++++++-------------------------------------
 1 files changed, 42 insertions(+), 77 deletions(-)

diff --git a/procps/top.c b/procps/top.c
index e4afafc..51b1671 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])
-- 
1.6.3.3



More information about the busybox-cvs mailing list