diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-09-25 11:11:37 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-09-25 11:11:37 +0000 |
commit | 35840ab204ee225a1498790a05c3565111ce99ce (patch) | |
tree | c781c488dd4a90d484fd1988bd699c4d8abe24e6 | |
parent | 864329d67427b441c7777ad511f5146486e8bce8 (diff) | |
download | busybox-w32-35840ab204ee225a1498790a05c3565111ce99ce.tar.gz busybox-w32-35840ab204ee225a1498790a05c3565111ce99ce.tar.bz2 busybox-w32-35840ab204ee225a1498790a05c3565111ce99ce.zip |
top: fixes to prev commit: '1' should toggle SMP view too;
"cpu ..." line should be parsed unconditionally
top: do not truncate loadavg string. More info -> better
-rw-r--r-- | procps/top.c | 58 |
1 files changed, 27 insertions, 31 deletions
diff --git a/procps/top.c b/procps/top.c index c881ad419..b481d395e 100644 --- a/procps/top.c +++ b/procps/top.c | |||
@@ -90,7 +90,7 @@ struct globals { | |||
90 | cmp_funcp sort_function[SORT_DEPTH]; | 90 | cmp_funcp sort_function[SORT_DEPTH]; |
91 | struct save_hist *prev_hist; | 91 | struct save_hist *prev_hist; |
92 | int prev_hist_count; | 92 | int prev_hist_count; |
93 | jiffy_counts_t jif, prev_jif; | 93 | jiffy_counts_t cur_jif, prev_jif; |
94 | /* int hist_iterations; */ | 94 | /* int hist_iterations; */ |
95 | unsigned total_pcpu; | 95 | unsigned total_pcpu; |
96 | /* unsigned long total_vsz; */ | 96 | /* unsigned long total_vsz; */ |
@@ -120,7 +120,7 @@ enum { LINE_BUF_SIZE = COMMON_BUFSIZE - offsetof(struct globals, line_buf) }; | |||
120 | #define sort_function (G.sort_function ) | 120 | #define sort_function (G.sort_function ) |
121 | #define prev_hist (G.prev_hist ) | 121 | #define prev_hist (G.prev_hist ) |
122 | #define prev_hist_count (G.prev_hist_count ) | 122 | #define prev_hist_count (G.prev_hist_count ) |
123 | #define jif (G.jif ) | 123 | #define cur_jif (G.cur_jif ) |
124 | #define prev_jif (G.prev_jif ) | 124 | #define prev_jif (G.prev_jif ) |
125 | #define cpu_jif (G.cpu_jif ) | 125 | #define cpu_jif (G.cpu_jif ) |
126 | #define cpu_prev_jif (G.cpu_prev_jif ) | 126 | #define cpu_prev_jif (G.cpu_prev_jif ) |
@@ -214,24 +214,21 @@ static void get_jiffy_counts(void) | |||
214 | { | 214 | { |
215 | FILE* fp = xfopen_for_read("stat"); | 215 | FILE* fp = xfopen_for_read("stat"); |
216 | 216 | ||
217 | #if !ENABLE_FEATURE_TOP_SMP_CPU | 217 | /* We need to parse cumulative counts even if SMP CPU display is on, |
218 | prev_jif = jif; | 218 | * they are used to calculate per process CPU% */ |
219 | if (read_cpu_jiffy(fp, &jif) < 4) | 219 | prev_jif = cur_jif; |
220 | if (read_cpu_jiffy(fp, &cur_jif) < 4) | ||
220 | bb_error_msg_and_die("can't read /proc/stat"); | 221 | bb_error_msg_and_die("can't read /proc/stat"); |
222 | |||
223 | #if !ENABLE_FEATURE_TOP_SMP_CPU | ||
221 | fclose(fp); | 224 | fclose(fp); |
222 | return; | 225 | return; |
223 | #else | 226 | #else |
224 | if (!smp_cpu_info) { /* user wants to see cumulative cpu info */ | 227 | if (!smp_cpu_info) { |
225 | prev_jif = jif; | ||
226 | if (read_cpu_jiffy(fp, &jif) < 4) | ||
227 | bb_error_msg_and_die("can't read /proc/stat"); | ||
228 | fclose(fp); | 228 | fclose(fp); |
229 | return; | 229 | return; |
230 | } | 230 | } |
231 | 231 | ||
232 | /* Discard first "cpu ..." line */ | ||
233 | fgets(line_buf, LINE_BUF_SIZE, fp); | ||
234 | |||
235 | if (!num_cpus) { | 232 | if (!num_cpus) { |
236 | /* First time here. How many CPUs? | 233 | /* First time here. How many CPUs? |
237 | * There will be at least 1 /proc/stat line with cpu%d | 234 | * There will be at least 1 /proc/stat line with cpu%d |
@@ -245,10 +242,6 @@ static void get_jiffy_counts(void) | |||
245 | if (num_cpus == 0) /* /proc/stat with only "cpu ..." line?! */ | 242 | if (num_cpus == 0) /* /proc/stat with only "cpu ..." line?! */ |
246 | smp_cpu_info = 0; | 243 | smp_cpu_info = 0; |
247 | 244 | ||
248 | /* TODO: need to cap num_cpus to a reasonable num | ||
249 | * on massively paralle machines so that we dont | ||
250 | * swamp the terminal with cpu "only" info | ||
251 | */ | ||
252 | cpu_prev_jif = xzalloc(sizeof(cpu_prev_jif[0]) * num_cpus); | 245 | cpu_prev_jif = xzalloc(sizeof(cpu_prev_jif[0]) * num_cpus); |
253 | 246 | ||
254 | /* Otherwise the first per cpu display shows all 100% idles */ | 247 | /* Otherwise the first per cpu display shows all 100% idles */ |
@@ -353,7 +346,7 @@ static char *fmt_100percent_8(char pbuf[8], unsigned value, unsigned total) | |||
353 | static void display_cpus(int scr_width, char *scrbuf, int *lines_rem_p) | 346 | static void display_cpus(int scr_width, char *scrbuf, int *lines_rem_p) |
354 | { | 347 | { |
355 | /* | 348 | /* |
356 | * xxx% = (jif.xxx - prev_jif.xxx) / (jif.total - prev_jif.total) * 100% | 349 | * xxx% = (cur_jif.xxx - prev_jif.xxx) / (cur_jif.total - prev_jif.total) * 100% |
357 | */ | 350 | */ |
358 | unsigned total_diff; | 351 | unsigned total_diff; |
359 | jiffy_counts_t *p_jif, *p_prev_jif; | 352 | jiffy_counts_t *p_jif, *p_prev_jif; |
@@ -379,7 +372,7 @@ static void display_cpus(int scr_width, char *scrbuf, int *lines_rem_p) | |||
379 | #if !ENABLE_FEATURE_TOP_SMP_CPU | 372 | #if !ENABLE_FEATURE_TOP_SMP_CPU |
380 | { | 373 | { |
381 | i = 1; | 374 | i = 1; |
382 | p_jif = &jif; | 375 | p_jif = &cur_jif; |
383 | p_prev_jif = &prev_jif; | 376 | p_prev_jif = &prev_jif; |
384 | #else | 377 | #else |
385 | /* Loop thru CPU(s) */ | 378 | /* Loop thru CPU(s) */ |
@@ -388,13 +381,12 @@ static void display_cpus(int scr_width, char *scrbuf, int *lines_rem_p) | |||
388 | n_cpu_lines = *lines_rem_p; | 381 | n_cpu_lines = *lines_rem_p; |
389 | 382 | ||
390 | for (i = 0; i < n_cpu_lines; i++) { | 383 | for (i = 0; i < n_cpu_lines; i++) { |
391 | /* set the real loop end */ | ||
392 | p_jif = &cpu_jif[i]; | 384 | p_jif = &cpu_jif[i]; |
393 | p_prev_jif = &cpu_prev_jif[i]; | 385 | p_prev_jif = &cpu_prev_jif[i]; |
394 | #endif | 386 | #endif |
395 | total_diff = CALC_TOT_DIFF; | 387 | total_diff = CALC_TOT_DIFF; |
396 | 388 | ||
397 | { /* Need block: CALC_STAT are declarations */ | 389 | { /* Need a block: CALC_STAT are declarations */ |
398 | CALC_STAT(usr); | 390 | CALC_STAT(usr); |
399 | CALC_STAT(sys); | 391 | CALC_STAT(sys); |
400 | CALC_STAT(nic); | 392 | CALC_STAT(nic); |
@@ -500,8 +492,9 @@ static unsigned long display_header(int scr_width, int *lines_rem_p) | |||
500 | 492 | ||
501 | /* read load average as a string */ | 493 | /* read load average as a string */ |
502 | buf[0] = '\0'; | 494 | buf[0] = '\0'; |
503 | open_read_close("loadavg", buf, sizeof("N.NN N.NN N.NN")-1); | 495 | open_read_close("loadavg", buf, sizeof(buf) - 1); |
504 | buf[sizeof("N.NN N.NN N.NN")-1] = '\0'; | 496 | buf[sizeof(buf) - 1] = '\n'; |
497 | *strchr(buf, '\n') = '\0'; | ||
505 | snprintf(scrbuf, scr_width, "Load average: %s", buf); | 498 | snprintf(scrbuf, scr_width, "Load average: %s", buf); |
506 | puts(scrbuf); | 499 | puts(scrbuf); |
507 | (*lines_rem_p)--; | 500 | (*lines_rem_p)--; |
@@ -561,7 +554,7 @@ static NOINLINE void display_process_list(int lines_rem, int scr_width) | |||
561 | } | 554 | } |
562 | pmem_half = (1U << pmem_shift) / (ENABLE_FEATURE_TOP_DECIMALS? 20 : 2); | 555 | pmem_half = (1U << pmem_shift) / (ENABLE_FEATURE_TOP_DECIMALS? 20 : 2); |
563 | #if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE | 556 | #if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE |
564 | busy_jifs = jif.busy - prev_jif.busy; | 557 | busy_jifs = cur_jif.busy - prev_jif.busy; |
565 | /* This happens if there were lots of short-lived processes | 558 | /* This happens if there were lots of short-lived processes |
566 | * between two top updates (e.g. compilation) */ | 559 | * between two top updates (e.g. compilation) */ |
567 | if (total_pcpu < busy_jifs) total_pcpu = busy_jifs; | 560 | if (total_pcpu < busy_jifs) total_pcpu = busy_jifs; |
@@ -570,17 +563,17 @@ static NOINLINE void display_process_list(int lines_rem, int scr_width) | |||
570 | * CPU% = s->pcpu/sum(s->pcpu) * busy_cpu_ticks/total_cpu_ticks | 563 | * CPU% = s->pcpu/sum(s->pcpu) * busy_cpu_ticks/total_cpu_ticks |
571 | * (pcpu is delta of sys+user time between samples) | 564 | * (pcpu is delta of sys+user time between samples) |
572 | */ | 565 | */ |
573 | /* (jif.xxx - prev_jif.xxx) and s->pcpu are | 566 | /* (cur_jif.xxx - prev_jif.xxx) and s->pcpu are |
574 | * in 0..~64000 range (HZ*update_interval). | 567 | * in 0..~64000 range (HZ*update_interval). |
575 | * we assume that unsigned is at least 32-bit. | 568 | * we assume that unsigned is at least 32-bit. |
576 | */ | 569 | */ |
577 | pcpu_shift = 6; | 570 | pcpu_shift = 6; |
578 | pcpu_scale = (UPSCALE*64*(uint16_t)busy_jifs ? : 1); | 571 | pcpu_scale = (UPSCALE*64 * (uint16_t)busy_jifs ? : 1); |
579 | while (pcpu_scale < (1U<<(BITS_PER_INT-2))) { | 572 | while (pcpu_scale < (1U << (BITS_PER_INT-2))) { |
580 | pcpu_scale *= 4; | 573 | pcpu_scale *= 4; |
581 | pcpu_shift += 2; | 574 | pcpu_shift += 2; |
582 | } | 575 | } |
583 | pcpu_scale /= ( (uint16_t)(jif.total-prev_jif.total)*total_pcpu ? : 1); | 576 | pcpu_scale /= ( (uint16_t)(cur_jif.total - prev_jif.total) * total_pcpu ? : 1); |
584 | /* we want (s->pcpu * pcpu_scale) to never overflow */ | 577 | /* we want (s->pcpu * pcpu_scale) to never overflow */ |
585 | while (pcpu_scale >= 1024) { | 578 | while (pcpu_scale >= 1024) { |
586 | pcpu_scale /= 4; | 579 | pcpu_scale /= 4; |
@@ -630,7 +623,7 @@ static NOINLINE void display_process_list(int lines_rem, int scr_width) | |||
630 | read_cmdline(line_buf + col, scr_width - col - 1, s->pid, s->comm); | 623 | read_cmdline(line_buf + col, scr_width - col - 1, s->pid, s->comm); |
631 | fputs(line_buf, stdout); | 624 | fputs(line_buf, stdout); |
632 | /* printf(" %d/%d %lld/%lld", s->pcpu, total_pcpu, | 625 | /* printf(" %d/%d %lld/%lld", s->pcpu, total_pcpu, |
633 | jif.busy - prev_jif.busy, jif.total - prev_jif.total); */ | 626 | cur_jif.busy - prev_jif.busy, cur_jif.total - prev_jif.total); */ |
634 | s++; | 627 | s++; |
635 | } | 628 | } |
636 | /* printf(" %d", hist_iterations); */ | 629 | /* printf(" %d", hist_iterations); */ |
@@ -696,6 +689,7 @@ enum { NUM_SORT_FIELD = 7 }; | |||
696 | #define topmem ((topmem_status_t*)top) | 689 | #define topmem ((topmem_status_t*)top) |
697 | 690 | ||
698 | #if ENABLE_FEATURE_TOPMEM | 691 | #if ENABLE_FEATURE_TOPMEM |
692 | |||
699 | static int topmem_sort(char *a, char *b) | 693 | static int topmem_sort(char *a, char *b) |
700 | { | 694 | { |
701 | int n; | 695 | int n; |
@@ -864,6 +858,7 @@ static NOINLINE void display_topmem_process_list(int lines_rem, int scr_width) | |||
864 | #undef HDR_STR | 858 | #undef HDR_STR |
865 | #undef MIN_WIDTH | 859 | #undef MIN_WIDTH |
866 | } | 860 | } |
861 | |||
867 | #else | 862 | #else |
868 | void display_topmem_process_list(int lines_rem, int scr_width); | 863 | void display_topmem_process_list(int lines_rem, int scr_width); |
869 | int topmem_sort(char *a, char *b); | 864 | int topmem_sort(char *a, char *b); |
@@ -917,7 +912,7 @@ int top_main(int argc UNUSED_PARAM, char **argv) | |||
917 | #if ENABLE_FEATURE_TOP_SMP_CPU | 912 | #if ENABLE_FEATURE_TOP_SMP_CPU |
918 | /*num_cpus = 0;*/ | 913 | /*num_cpus = 0;*/ |
919 | /*smp_cpu_info = 0;*/ /* to start with show aggregate */ | 914 | /*smp_cpu_info = 0;*/ /* to start with show aggregate */ |
920 | cpu_jif = &jif; | 915 | cpu_jif = &cur_jif; |
921 | cpu_prev_jif = &prev_jif; | 916 | cpu_prev_jif = &prev_jif; |
922 | #endif | 917 | #endif |
923 | 918 | ||
@@ -1092,12 +1087,13 @@ int top_main(int argc UNUSED_PARAM, char **argv) | |||
1092 | inverted ^= 1; | 1087 | inverted ^= 1; |
1093 | #endif | 1088 | #endif |
1094 | #if ENABLE_FEATURE_TOP_SMP_CPU | 1089 | #if ENABLE_FEATURE_TOP_SMP_CPU |
1095 | if (c == 'c') { /* procps-2.0.18 uses 'C' */ | 1090 | /* procps-2.0.18 uses 'C', 3.2.7 uses '1' */ |
1091 | if (c == 'c' || c == '1') { | ||
1096 | /* User wants to toggle per cpu <> aggregate */ | 1092 | /* User wants to toggle per cpu <> aggregate */ |
1097 | if (smp_cpu_info) { | 1093 | if (smp_cpu_info) { |
1098 | free(cpu_prev_jif); | 1094 | free(cpu_prev_jif); |
1099 | free(cpu_jif); | 1095 | free(cpu_jif); |
1100 | cpu_jif = &jif; | 1096 | cpu_jif = &cur_jif; |
1101 | cpu_prev_jif = &prev_jif; | 1097 | cpu_prev_jif = &prev_jif; |
1102 | } else { | 1098 | } else { |
1103 | /* Prepare for xrealloc() */ | 1099 | /* Prepare for xrealloc() */ |