aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-06-10 17:11:59 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-06-10 17:11:59 +0000
commit5a65447e3090908b4bad645c84e37298ca7a7449 (patch)
tree1fb67f517a8519f92e5d5c9876685823dff5b236
parente8a0788b249cbac5bf5b2aa2d81bb8f6b29a7a4b (diff)
downloadbusybox-w32-5a65447e3090908b4bad645c84e37298ca7a7449.tar.gz
busybox-w32-5a65447e3090908b4bad645c84e37298ca7a7449.tar.bz2
busybox-w32-5a65447e3090908b4bad645c84e37298ca7a7449.zip
top: add config option and code for global CPU % display
-rw-r--r--docs/keep_data_small.txt10
-rw-r--r--libbb/procps.c11
-rw-r--r--procps/Config.in11
-rw-r--r--procps/top.c58
4 files changed, 70 insertions, 20 deletions
diff --git a/docs/keep_data_small.txt b/docs/keep_data_small.txt
index f88fe07b0..3ddbd81a4 100644
--- a/docs/keep_data_small.txt
+++ b/docs/keep_data_small.txt
@@ -43,6 +43,16 @@ takes 55k of memory on 64-bit x86 kernel.
43 43
44On 32-bit kernel we need ~26k per applet. 44On 32-bit kernel we need ~26k per applet.
45 45
46Script:
47
48i=1000; while test $i != 0; do
49 echo -n .
50 busybox sleep 30 &
51 i=$((i - 1))
52done
53echo
54wait
55
46(Data from NOMMU arches are sought. Provide 'size busybox' output too) 56(Data from NOMMU arches are sought. Provide 'size busybox' output too)
47 57
48 58
diff --git a/libbb/procps.c b/libbb/procps.c
index be0d61bd3..1e2495a5a 100644
--- a/libbb/procps.c
+++ b/libbb/procps.c
@@ -79,8 +79,15 @@ const char* get_cached_groupname(gid_t gid)
79 79
80static int read_to_buf(const char *filename, void *buf) 80static int read_to_buf(const char *filename, void *buf)
81{ 81{
82 ssize_t ret; 82 int fd;
83 ret = open_read_close(filename, buf, PROCPS_BUFSIZE-1); 83 /* open_read_close() would do two reads, checking for EOF.
84 * When you have 10000 /proc/$NUM/stat to read, it isn't desirable */
85 ssize_t ret = -1;
86 fd = open(filename, O_RDONLY);
87 if (fd >= 0) {
88 ret = read(fd, buf, PROCPS_BUFSIZE-1);
89 close(fd);
90 }
84 ((char *)buf)[ret > 0 ? ret : 0] = '\0'; 91 ((char *)buf)[ret > 0 ? ret : 0] = '\0';
85 return ret; 92 return ret;
86} 93}
diff --git a/procps/Config.in b/procps/Config.in
index e58b89f85..cd46a3448 100644
--- a/procps/Config.in
+++ b/procps/Config.in
@@ -102,11 +102,18 @@ config TOP
102 system. 102 system.
103 103
104config FEATURE_TOP_CPU_USAGE_PERCENTAGE 104config FEATURE_TOP_CPU_USAGE_PERCENTAGE
105 bool "Support showing CPU usage percentage (add 2k bytes)" 105 bool "Show CPU per-process usage percentage (adds 2k bytes)"
106 default y 106 default y
107 depends on TOP 107 depends on TOP
108 help 108 help
109 Make top display CPU usage. 109 Make top display CPU usage for each process.
110
111config FEATURE_TOP_CPU_GLOBAL_PERCENTS
112 bool "Show CPU global usage percentage (adds 1k byte)"
113 default y
114 depends on FEATURE_TOP_CPU_USAGE_PERCENTAGE
115 help
116 Makes top display "CPU: n.n% us n.n% sy n.n% ni..." line.
110 117
111config UPTIME 118config UPTIME
112 bool "uptime" 119 bool "uptime"
diff --git a/procps/top.c b/procps/top.c
index 948ab0315..6d8dfd880 100644
--- a/procps/top.c
+++ b/procps/top.c
@@ -221,7 +221,6 @@ static unsigned long display_generic(int scr_width)
221 char scrbuf[80]; 221 char scrbuf[80];
222 char *end; 222 char *end;
223 unsigned long total, used, mfree, shared, buffers, cached; 223 unsigned long total, used, mfree, shared, buffers, cached;
224 unsigned int needs_conversion = 1;
225 224
226 /* read memory info */ 225 /* read memory info */
227 fp = xfopen("meminfo", "r"); 226 fp = xfopen("meminfo", "r");
@@ -240,14 +239,20 @@ static unsigned long display_generic(int scr_width)
240 fgets(buf, sizeof(buf), fp); /* skip first line */ 239 fgets(buf, sizeof(buf), fp); /* skip first line */
241 240
242 fscanf(fp, "Mem: %lu %lu %lu %lu %lu %lu", 241 fscanf(fp, "Mem: %lu %lu %lu %lu %lu %lu",
243 &total, &used, &mfree, &shared, &buffers, &cached); 242 &total, &used, &mfree, &shared, &buffers, &cached);
243 /* convert to kilobytes */
244 used /= 1024;
245 mfree /= 1024;
246 shared /= 1024;
247 buffers /= 1024;
248 cached /= 1024;
249 total /= 1024;
244 } else { 250 } else {
245 /* 251 /*
246 * Revert to manual parsing, which incidentally already has the 252 * Revert to manual parsing, which incidentally already has the
247 * sizes in kilobytes. This should be safe for both 2.4 and 253 * sizes in kilobytes. This should be safe for both 2.4 and
248 * 2.6. 254 * 2.6.
249 */ 255 */
250 needs_conversion = 0;
251 256
252 fscanf(fp, "MemFree: %lu %s\n", &mfree, buf); 257 fscanf(fp, "MemFree: %lu %s\n", &mfree, buf);
253 258
@@ -273,16 +278,6 @@ static unsigned long display_generic(int scr_width)
273 if (end) end = strchr(end+1, ' '); 278 if (end) end = strchr(end+1, ' ');
274 if (end) *end = '\0'; 279 if (end) *end = '\0';
275 280
276 if (needs_conversion) {
277 /* convert to kilobytes */
278 used /= 1024;
279 mfree /= 1024;
280 shared /= 1024;
281 buffers /= 1024;
282 cached /= 1024;
283 total /= 1024;
284 }
285
286 /* output memory info and load average */ 281 /* output memory info and load average */
287 /* clear screen & go to top */ 282 /* clear screen & go to top */
288 if (scr_width > sizeof(scrbuf)) 283 if (scr_width > sizeof(scrbuf))
@@ -293,8 +288,39 @@ static unsigned long display_generic(int scr_width)
293 288
294 printf(OPT_BATCH_MODE ? "%s\n" : "\e[H\e[J%s\n", scrbuf); 289 printf(OPT_BATCH_MODE ? "%s\n" : "\e[H\e[J%s\n", scrbuf);
295 290
291 if (ENABLE_FEATURE_TOP_CPU_GLOBAL_PERCENTS) {
292 /*
293 * xxx% = (jif.xxx - prev_jif.xxx) / (jif.total - prev_jif.total) * 100%
294 */
295#define CALC_STAT(xxx) div_t xxx = div(1000 * (jif.xxx - prev_jif.xxx) / total_diff, 10)
296#define SHOW_STAT(xxx) xxx.quot, '0'+xxx.rem
297 unsigned total_diff = (jif.total - prev_jif.total ? : 1);
298 CALC_STAT(usr);
299 CALC_STAT(sys);
300 CALC_STAT(nic);
301 CALC_STAT(idle);
302 CALC_STAT(iowait);
303 CALC_STAT(irq);
304 CALC_STAT(softirq);
305 //CALC_STAT(steal);
306
307 snprintf(scrbuf, scr_width,
308 /* %3u.%c in practice almost never displays "100.0"
309 * and thus has implicit leading space: " 99.6" */
310 "CPU:%3u.%c%% us%3u.%c%% sy%3u.%c%% ni%3u.%c%% id%3u.%c%% wa%3u.%c%% hi%3u.%c%% si",
311 // %3u.%c%%st", - what is this 'steal' thing?
312 // I doubt anyone needs to know it
313 SHOW_STAT(usr), SHOW_STAT(sys), SHOW_STAT(nic), SHOW_STAT(idle),
314 SHOW_STAT(iowait), SHOW_STAT(irq), SHOW_STAT(softirq)
315 //, SHOW_STAT(steal)
316 );
317 puts(scrbuf);
318#undef SHOW_STAT
319#undef CALC_STAT
320 }
321
296 snprintf(scrbuf, scr_width, "Load average: %s", buf); 322 snprintf(scrbuf, scr_width, "Load average: %s", buf);
297 printf("%s\n", scrbuf); 323 puts(scrbuf);
298 324
299 return total; 325 return total;
300} 326}
@@ -479,7 +505,7 @@ int top_main(int argc, char **argv)
479 procps_status_t *p = NULL; 505 procps_status_t *p = NULL;
480 506
481 /* Default to 25 lines - 5 lines for status */ 507 /* Default to 25 lines - 5 lines for status */
482 lines = 24 - 3; 508 lines = 24 - 3 USE_FEATURE_TOP_CPU_GLOBAL_PERCENTS( - 1);
483 col = 79; 509 col = 79;
484#if ENABLE_FEATURE_USE_TERMIOS 510#if ENABLE_FEATURE_USE_TERMIOS
485 get_terminal_width_height(0, &col, &lines); 511 get_terminal_width_height(0, &col, &lines);
@@ -487,7 +513,7 @@ int top_main(int argc, char **argv)
487 sleep(interval); 513 sleep(interval);
488 continue; 514 continue;
489 } 515 }
490 lines -= 3; 516 lines -= 3 USE_FEATURE_TOP_CPU_GLOBAL_PERCENTS( + 1);
491#endif /* FEATURE_USE_TERMIOS */ 517#endif /* FEATURE_USE_TERMIOS */
492 518
493 /* read process IDs & status for all the processes */ 519 /* read process IDs & status for all the processes */