diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-06-10 17:11:59 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-06-10 17:11:59 +0000 |
commit | 5a65447e3090908b4bad645c84e37298ca7a7449 (patch) | |
tree | 1fb67f517a8519f92e5d5c9876685823dff5b236 | |
parent | e8a0788b249cbac5bf5b2aa2d81bb8f6b29a7a4b (diff) | |
download | busybox-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.txt | 10 | ||||
-rw-r--r-- | libbb/procps.c | 11 | ||||
-rw-r--r-- | procps/Config.in | 11 | ||||
-rw-r--r-- | procps/top.c | 58 |
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 | ||
44 | On 32-bit kernel we need ~26k per applet. | 44 | On 32-bit kernel we need ~26k per applet. |
45 | 45 | ||
46 | Script: | ||
47 | |||
48 | i=1000; while test $i != 0; do | ||
49 | echo -n . | ||
50 | busybox sleep 30 & | ||
51 | i=$((i - 1)) | ||
52 | done | ||
53 | echo | ||
54 | wait | ||
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 | ||
80 | static int read_to_buf(const char *filename, void *buf) | 80 | static 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 | ||
104 | config FEATURE_TOP_CPU_USAGE_PERCENTAGE | 104 | config 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 | |||
111 | config 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 | ||
111 | config UPTIME | 118 | config 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 */ |