4 |
* |
* |
5 |
* This is written specifically for the linux /proc/<PID>/stat(m) |
* This is written specifically for the linux /proc/<PID>/stat(m) |
6 |
* files format. |
* files format. |
7 |
|
* |
8 |
* This reads the PIDs of all processes and their status and shows |
* This reads the PIDs of all processes and their status and shows |
9 |
* the status of processes (first ones that fit to screen) at given |
* the status of processes (first ones that fit to screen) at given |
10 |
* intervals. |
* intervals. |
22 |
* - CPU where Process was last seen running |
* - CPU where Process was last seen running |
23 |
* (to see effect of sched_setaffinity() etc) |
* (to see effect of sched_setaffinity() etc) |
24 |
* - CPU Time Split (idle/IO/wait etc) PER CPU |
* - CPU Time Split (idle/IO/wait etc) PER CPU |
25 |
*/ |
* |
|
|
|
|
/* Original code Copyrights */ |
|
|
/* |
|
26 |
* Copyright (c) 1992 Branko Lankester |
* Copyright (c) 1992 Branko Lankester |
27 |
* Copyright (c) 1992 Roger Binns |
* Copyright (c) 1992 Roger Binns |
28 |
* Copyright (C) 1994-1996 Charles L. Blake. |
* Copyright (C) 1994-1996 Charles L. Blake. |
29 |
* Copyright (C) 1992-1998 Michael K. Johnson |
* Copyright (C) 1992-1998 Michael K. Johnson |
30 |
* May be distributed under the conditions of the |
* |
31 |
* GNU Library General Public License |
* Licensed under GPLv2, see file LICENSE in this tarball for details. |
32 |
*/ |
*/ |
33 |
|
|
34 |
#include "libbb.h" |
#include "libbb.h" |
50 |
} top_status_t; |
} top_status_t; |
51 |
|
|
52 |
typedef struct jiffy_counts_t { |
typedef struct jiffy_counts_t { |
53 |
unsigned long long usr,nic,sys,idle,iowait,irq,softirq,steal; |
/* Linux 2.4.x has only first four */ |
54 |
|
unsigned long long usr, nic, sys, idle; |
55 |
|
unsigned long long iowait, irq, softirq, steal; |
56 |
unsigned long long total; |
unsigned long long total; |
57 |
unsigned long long busy; |
unsigned long long busy; |
58 |
} jiffy_counts_t; |
} jiffy_counts_t; |
131 |
OPT_d = (1 << 0), |
OPT_d = (1 << 0), |
132 |
OPT_n = (1 << 1), |
OPT_n = (1 << 1), |
133 |
OPT_b = (1 << 2), |
OPT_b = (1 << 2), |
134 |
OPT_EOF = (1 << 3), /* pseudo: "we saw EOF in stdin" */ |
OPT_m = (1 << 3), |
135 |
|
OPT_EOF = (1 << 4), /* pseudo: "we saw EOF in stdin" */ |
136 |
}; |
}; |
137 |
#define OPT_BATCH_MODE (option_mask32 & OPT_b) |
#define OPT_BATCH_MODE (option_mask32 & OPT_b) |
138 |
|
|
182 |
return 0; |
return 0; |
183 |
} |
} |
184 |
|
|
|
/* NOINLINE so that complier doesn't unfold the call |
|
|
* causing multiple copies of the arithmatic instrns |
|
|
*/ |
|
185 |
static NOINLINE int read_cpu_jiffy(FILE *fp, jiffy_counts_t *p_jif) |
static NOINLINE int read_cpu_jiffy(FILE *fp, jiffy_counts_t *p_jif) |
186 |
{ |
{ |
187 |
#if !ENABLE_FEATURE_TOP_SMP_CPU |
#if !ENABLE_FEATURE_TOP_SMP_CPU |
188 |
static const char fmt[] = "cpu %lld %lld %lld %lld %lld %lld %lld %lld"; |
static const char fmt[] = "cpu %llu %llu %llu %llu %llu %llu %llu %llu"; |
189 |
#else |
#else |
190 |
static const char fmt[] = "cp%*s %lld %lld %lld %lld %lld %lld %lld %lld"; |
static const char fmt[] = "cp%*s %llu %llu %llu %llu %llu %llu %llu %llu"; |
191 |
#endif |
#endif |
192 |
int ret; |
int ret; |
193 |
|
|
348 |
unsigned total_diff; |
unsigned total_diff; |
349 |
jiffy_counts_t *p_jif, *p_prev_jif; |
jiffy_counts_t *p_jif, *p_prev_jif; |
350 |
int i; |
int i; |
351 |
|
# if ENABLE_FEATURE_TOP_SMP_CPU |
|
#if ENABLE_FEATURE_TOP_SMP_CPU |
|
352 |
int n_cpu_lines; |
int n_cpu_lines; |
353 |
#endif |
# endif |
354 |
|
|
355 |
/* using (unsigned) casts to make operations cheaper */ |
/* using (unsigned) casts to make operations cheaper */ |
356 |
#define CALC_TOT_DIFF ((unsigned)(p_jif->total - p_prev_jif->total) ? : 1) |
# define CALC_TOTAL_DIFF do { \ |
357 |
|
total_diff = (unsigned)(p_jif->total - p_prev_jif->total); \ |
358 |
|
if (total_diff == 0) total_diff = 1; \ |
359 |
|
} while (0) |
360 |
|
|
361 |
#if ENABLE_FEATURE_TOP_DECIMALS |
# if ENABLE_FEATURE_TOP_DECIMALS |
362 |
#define CALC_STAT(xxx) char xxx[8] |
# define CALC_STAT(xxx) char xxx[8] |
363 |
#define SHOW_STAT(xxx) fmt_100percent_8(xxx, (unsigned)(p_jif->xxx - p_prev_jif->xxx), total_diff) |
# define SHOW_STAT(xxx) fmt_100percent_8(xxx, (unsigned)(p_jif->xxx - p_prev_jif->xxx), total_diff) |
364 |
#define FMT "%s" |
# define FMT "%s" |
365 |
#else |
# else |
366 |
#define CALC_STAT(xxx) unsigned xxx = 100 * (unsigned)(p_jif->xxx - p_prev_jif->xxx) / total_diff |
# define CALC_STAT(xxx) unsigned xxx = 100 * (unsigned)(p_jif->xxx - p_prev_jif->xxx) / total_diff |
367 |
#define SHOW_STAT(xxx) xxx |
# define SHOW_STAT(xxx) xxx |
368 |
#define FMT "%4u%% " |
# define FMT "%4u%% " |
369 |
#endif |
# endif |
370 |
|
|
371 |
#if !ENABLE_FEATURE_TOP_SMP_CPU |
# if !ENABLE_FEATURE_TOP_SMP_CPU |
372 |
{ |
{ |
373 |
i = 1; |
i = 1; |
374 |
p_jif = &cur_jif; |
p_jif = &cur_jif; |
375 |
p_prev_jif = &prev_jif; |
p_prev_jif = &prev_jif; |
376 |
#else |
# else |
377 |
/* Loop thru CPU(s) */ |
/* Loop thru CPU(s) */ |
378 |
n_cpu_lines = smp_cpu_info ? num_cpus : 1; |
n_cpu_lines = smp_cpu_info ? num_cpus : 1; |
379 |
if (n_cpu_lines > *lines_rem_p) |
if (n_cpu_lines > *lines_rem_p) |
382 |
for (i = 0; i < n_cpu_lines; i++) { |
for (i = 0; i < n_cpu_lines; i++) { |
383 |
p_jif = &cpu_jif[i]; |
p_jif = &cpu_jif[i]; |
384 |
p_prev_jif = &cpu_prev_jif[i]; |
p_prev_jif = &cpu_prev_jif[i]; |
385 |
#endif |
# endif |
386 |
total_diff = CALC_TOT_DIFF; |
CALC_TOTAL_DIFF; |
387 |
|
|
388 |
{ /* Need a block: CALC_STAT are declarations */ |
{ /* Need a block: CALC_STAT are declarations */ |
389 |
CALC_STAT(usr); |
CALC_STAT(usr); |
397 |
|
|
398 |
snprintf(scrbuf, scr_width, |
snprintf(scrbuf, scr_width, |
399 |
/* Barely fits in 79 chars when in "decimals" mode. */ |
/* Barely fits in 79 chars when in "decimals" mode. */ |
400 |
#if ENABLE_FEATURE_TOP_SMP_CPU |
# if ENABLE_FEATURE_TOP_SMP_CPU |
401 |
"CPU%s:"FMT"usr"FMT"sys"FMT"nic"FMT"idle"FMT"io"FMT"irq"FMT"sirq", |
"CPU%s:"FMT"usr"FMT"sys"FMT"nic"FMT"idle"FMT"io"FMT"irq"FMT"sirq", |
402 |
(smp_cpu_info ? utoa(i) : ""), |
(smp_cpu_info ? utoa(i) : ""), |
403 |
#else |
# else |
404 |
"CPU:"FMT"usr"FMT"sys"FMT"nic"FMT"idle"FMT"io"FMT"irq"FMT"sirq", |
"CPU:"FMT"usr"FMT"sys"FMT"nic"FMT"idle"FMT"io"FMT"irq"FMT"sirq", |
405 |
#endif |
# endif |
406 |
SHOW_STAT(usr), SHOW_STAT(sys), SHOW_STAT(nic), SHOW_STAT(idle), |
SHOW_STAT(usr), SHOW_STAT(sys), SHOW_STAT(nic), SHOW_STAT(idle), |
407 |
SHOW_STAT(iowait), SHOW_STAT(irq), SHOW_STAT(softirq) |
SHOW_STAT(iowait), SHOW_STAT(irq), SHOW_STAT(softirq) |
408 |
/*, SHOW_STAT(steal) - what is this 'steal' thing? */ |
/*, SHOW_STAT(steal) - what is this 'steal' thing? */ |
411 |
puts(scrbuf); |
puts(scrbuf); |
412 |
} |
} |
413 |
} |
} |
414 |
#undef SHOW_STAT |
# undef SHOW_STAT |
415 |
#undef CALC_STAT |
# undef CALC_STAT |
416 |
#undef FMT |
# undef FMT |
417 |
*lines_rem_p -= i; |
*lines_rem_p -= i; |
418 |
} |
} |
419 |
#else /* !ENABLE_FEATURE_TOP_CPU_GLOBAL_PERCENTS */ |
#else /* !ENABLE_FEATURE_TOP_CPU_GLOBAL_PERCENTS */ |
420 |
#define display_cpus(scr_width, scrbuf, lines_rem) ((void)0) |
# define display_cpus(scr_width, scrbuf, lines_rem) ((void)0) |
421 |
#endif |
#endif |
422 |
|
|
423 |
static unsigned long display_header(int scr_width, int *lines_rem_p) |
static unsigned long display_header(int scr_width, int *lines_rem_p) |
514 |
* expensive divides with multiply and shift */ |
* expensive divides with multiply and shift */ |
515 |
unsigned pmem_shift, pmem_scale, pmem_half; |
unsigned pmem_shift, pmem_scale, pmem_half; |
516 |
#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE |
#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE |
517 |
|
unsigned tmp_unsigned; |
518 |
unsigned pcpu_shift, pcpu_scale, pcpu_half; |
unsigned pcpu_shift, pcpu_scale, pcpu_half; |
519 |
unsigned busy_jifs; |
unsigned busy_jifs; |
520 |
#endif |
#endif |
522 |
/* what info of the processes is shown */ |
/* what info of the processes is shown */ |
523 |
printf(OPT_BATCH_MODE ? "%.*s" : "\e[7m%.*s\e[0m", scr_width, |
printf(OPT_BATCH_MODE ? "%.*s" : "\e[7m%.*s\e[0m", scr_width, |
524 |
" PID PPID USER STAT VSZ %MEM" |
" PID PPID USER STAT VSZ %MEM" |
525 |
#if ENABLE_FEATURE_TOP_SMP_PROCESS |
IF_FEATURE_TOP_SMP_PROCESS(" CPU") |
526 |
" CPU" |
IF_FEATURE_TOP_CPU_USAGE_PERCENTAGE(" %CPU") |
|
#endif |
|
|
#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE |
|
|
" %CPU" |
|
|
#endif |
|
527 |
" COMMAND"); |
" COMMAND"); |
528 |
lines_rem--; |
lines_rem--; |
529 |
|
|
530 |
#if ENABLE_FEATURE_TOP_DECIMALS |
#if ENABLE_FEATURE_TOP_DECIMALS |
531 |
#define UPSCALE 1000 |
# define UPSCALE 1000 |
532 |
#define CALC_STAT(name, val) div_t name = div((val), 10) |
# define CALC_STAT(name, val) div_t name = div((val), 10) |
533 |
#define SHOW_STAT(name) name.quot, '0'+name.rem |
# define SHOW_STAT(name) name.quot, '0'+name.rem |
534 |
#define FMT "%3u.%c" |
# define FMT "%3u.%c" |
535 |
#else |
#else |
536 |
#define UPSCALE 100 |
# define UPSCALE 100 |
537 |
#define CALC_STAT(name, val) unsigned name = (val) |
# define CALC_STAT(name, val) unsigned name = (val) |
538 |
#define SHOW_STAT(name) name |
# define SHOW_STAT(name) name |
539 |
#define FMT "%4u%%" |
# define FMT "%4u%%" |
540 |
#endif |
#endif |
541 |
/* |
/* |
542 |
* MEM% = s->vsz/MemTotal |
* MEM% = s->vsz/MemTotal |
564 |
* we assume that unsigned is at least 32-bit. |
* we assume that unsigned is at least 32-bit. |
565 |
*/ |
*/ |
566 |
pcpu_shift = 6; |
pcpu_shift = 6; |
567 |
pcpu_scale = (UPSCALE*64 * (uint16_t)busy_jifs ? : 1); |
pcpu_scale = UPSCALE*64 * (uint16_t)busy_jifs; |
568 |
|
if (pcpu_scale == 0) |
569 |
|
pcpu_scale = 1; |
570 |
while (pcpu_scale < (1U << (BITS_PER_INT-2))) { |
while (pcpu_scale < (1U << (BITS_PER_INT-2))) { |
571 |
pcpu_scale *= 4; |
pcpu_scale *= 4; |
572 |
pcpu_shift += 2; |
pcpu_shift += 2; |
573 |
} |
} |
574 |
pcpu_scale /= ( (uint16_t)(cur_jif.total - prev_jif.total) * total_pcpu ? : 1); |
tmp_unsigned = (uint16_t)(cur_jif.total - prev_jif.total) * total_pcpu; |
575 |
|
if (tmp_unsigned != 0) |
576 |
|
pcpu_scale /= tmp_unsigned; |
577 |
/* we want (s->pcpu * pcpu_scale) to never overflow */ |
/* we want (s->pcpu * pcpu_scale) to never overflow */ |
578 |
while (pcpu_scale >= 1024) { |
while (pcpu_scale >= 1024) { |
579 |
pcpu_scale /= 4; |
pcpu_scale /= 4; |
602 |
/* PID PPID USER STAT VSZ %MEM [%CPU] COMMAND */ |
/* PID PPID USER STAT VSZ %MEM [%CPU] COMMAND */ |
603 |
col = snprintf(line_buf, scr_width, |
col = snprintf(line_buf, scr_width, |
604 |
"\n" "%5u%6u %-8.8s %s%s" FMT |
"\n" "%5u%6u %-8.8s %s%s" FMT |
605 |
#if ENABLE_FEATURE_TOP_SMP_PROCESS |
IF_FEATURE_TOP_SMP_PROCESS(" %3d") |
606 |
" %3d" |
IF_FEATURE_TOP_CPU_USAGE_PERCENTAGE(FMT) |
|
#endif |
|
|
#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE |
|
|
FMT |
|
|
#endif |
|
607 |
" ", |
" ", |
608 |
s->pid, s->ppid, get_cached_username(s->uid), |
s->pid, s->ppid, get_cached_username(s->uid), |
609 |
s->state, vsz_str_buf, |
s->state, vsz_str_buf, |
610 |
SHOW_STAT(pmem) |
SHOW_STAT(pmem) |
611 |
#if ENABLE_FEATURE_TOP_SMP_PROCESS |
IF_FEATURE_TOP_SMP_PROCESS(, s->last_seen_on_cpu) |
612 |
, s->last_seen_on_cpu |
IF_FEATURE_TOP_CPU_USAGE_PERCENTAGE(, SHOW_STAT(pcpu)) |
|
#endif |
|
|
#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE |
|
|
, SHOW_STAT(pcpu) |
|
|
#endif |
|
613 |
); |
); |
614 |
if ((int)(col + 1) < scr_width) |
if ((int)(col + 1) < scr_width) |
615 |
read_cmdline(line_buf + col, scr_width - col - 1, s->pid, s->comm); |
read_cmdline(line_buf + col, scr_width - col, s->pid, s->comm); |
616 |
fputs(line_buf, stdout); |
fputs(line_buf, stdout); |
617 |
/* printf(" %d/%d %lld/%lld", s->pcpu, total_pcpu, |
/* printf(" %d/%d %lld/%lld", s->pcpu, total_pcpu, |
618 |
cur_jif.busy - prev_jif.busy, cur_jif.total - prev_jif.total); */ |
cur_jif.busy - prev_jif.busy, cur_jif.total - prev_jif.total); */ |
620 |
} |
} |
621 |
/* printf(" %d", hist_iterations); */ |
/* printf(" %d", hist_iterations); */ |
622 |
bb_putchar(OPT_BATCH_MODE ? '\n' : '\r'); |
bb_putchar(OPT_BATCH_MODE ? '\n' : '\r'); |
623 |
fflush(stdout); |
fflush_all(); |
624 |
} |
} |
625 |
#undef UPSCALE |
#undef UPSCALE |
626 |
#undef SHOW_STAT |
#undef SHOW_STAT |
636 |
} |
} |
637 |
|
|
638 |
#if ENABLE_FEATURE_USE_TERMIOS |
#if ENABLE_FEATURE_USE_TERMIOS |
|
#include <termios.h> |
|
|
#include <signal.h> |
|
639 |
|
|
640 |
static void reset_term(void) |
static void reset_term(void) |
641 |
{ |
{ |
642 |
tcsetattr_stdin_TCSANOW(&initial_settings); |
tcsetattr_stdin_TCSANOW(&initial_settings); |
643 |
if (ENABLE_FEATURE_CLEAN_UP) { |
if (ENABLE_FEATURE_CLEAN_UP) { |
644 |
clearmems(); |
clearmems(); |
645 |
#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE |
# if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE |
646 |
free(prev_hist); |
free(prev_hist); |
647 |
#endif |
# endif |
648 |
} |
} |
649 |
} |
} |
650 |
|
|
844 |
s++; |
s++; |
845 |
} |
} |
846 |
bb_putchar(OPT_BATCH_MODE ? '\n' : '\r'); |
bb_putchar(OPT_BATCH_MODE ? '\n' : '\r'); |
847 |
fflush(stdout); |
fflush_all(); |
848 |
#undef HDR_STR |
#undef HDR_STR |
849 |
#undef MIN_WIDTH |
#undef MIN_WIDTH |
850 |
} |
} |
867 |
| PSSCAN_UTIME |
| PSSCAN_UTIME |
868 |
| PSSCAN_STATE |
| PSSCAN_STATE |
869 |
| PSSCAN_COMM |
| PSSCAN_COMM |
|
#if ENABLE_FEATURE_TOP_SMP_PROCESS |
|
870 |
| PSSCAN_CPU |
| PSSCAN_CPU |
|
#endif |
|
871 |
| PSSCAN_UIDGID, |
| PSSCAN_UIDGID, |
872 |
TOPMEM_MASK = 0 |
TOPMEM_MASK = 0 |
873 |
| PSSCAN_PID |
| PSSCAN_PID |
883 |
int lines_rem; |
int lines_rem; |
884 |
unsigned interval; |
unsigned interval; |
885 |
char *str_interval, *str_iterations; |
char *str_interval, *str_iterations; |
886 |
SKIP_FEATURE_TOPMEM(const) unsigned scan_mask = TOP_MASK; |
unsigned scan_mask = TOP_MASK; |
887 |
#if ENABLE_FEATURE_USE_TERMIOS |
#if ENABLE_FEATURE_USE_TERMIOS |
888 |
struct termios new_settings; |
struct termios new_settings; |
889 |
struct pollfd pfd[1]; |
struct pollfd pfd[1]; |
891 |
|
|
892 |
pfd[0].fd = 0; |
pfd[0].fd = 0; |
893 |
pfd[0].events = POLLIN; |
pfd[0].events = POLLIN; |
894 |
#endif /* FEATURE_USE_TERMIOS */ |
#endif |
895 |
|
|
896 |
INIT_G(); |
INIT_G(); |
897 |
|
|
905 |
#endif |
#endif |
906 |
|
|
907 |
/* all args are options; -n NUM */ |
/* all args are options; -n NUM */ |
908 |
opt_complementary = "-"; |
opt_complementary = "-"; /* options can be specified w/o dash */ |
909 |
col = getopt32(argv, "d:n:b", &str_interval, &str_iterations); |
col = getopt32(argv, "d:n:b"IF_FEATURE_TOPMEM("m"), &str_interval, &str_iterations); |
910 |
|
#if ENABLE_FEATURE_TOPMEM |
911 |
|
if (col & OPT_m) /* -m (busybox specific) */ |
912 |
|
scan_mask = TOPMEM_MASK; |
913 |
|
#endif |
914 |
if (col & OPT_d) { |
if (col & OPT_d) { |
915 |
/* work around for "-d 1" -> "-d -1" done by getopt32 */ |
/* work around for "-d 1" -> "-d -1" done by getopt32 |
916 |
|
* (opt_complementary == "-" does this) */ |
917 |
if (str_interval[0] == '-') |
if (str_interval[0] == '-') |
918 |
str_interval++; |
str_interval++; |
919 |
/* Need to limit it to not overflow poll timeout */ |
/* Need to limit it to not overflow poll timeout */ |
935 |
|
|
936 |
bb_signals(BB_FATAL_SIGS, sig_catcher); |
bb_signals(BB_FATAL_SIGS, sig_catcher); |
937 |
tcsetattr_stdin_TCSANOW(&new_settings); |
tcsetattr_stdin_TCSANOW(&new_settings); |
938 |
#endif /* FEATURE_USE_TERMIOS */ |
#endif |
939 |
|
|
940 |
#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE |
#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE |
941 |
sort_function[0] = pcpu_sort; |
sort_function[0] = pcpu_sort; |
943 |
sort_function[2] = time_sort; |
sort_function[2] = time_sort; |
944 |
#else |
#else |
945 |
sort_function[0] = mem_sort; |
sort_function[0] = mem_sort; |
946 |
#endif /* FEATURE_TOP_CPU_USAGE_PERCENTAGE */ |
#endif |
947 |
|
|
948 |
while (1) { |
while (1) { |
949 |
procps_status_t *p = NULL; |
procps_status_t *p = NULL; |
957 |
sleep(interval); |
sleep(interval); |
958 |
continue; |
continue; |
959 |
} |
} |
960 |
#endif /* FEATURE_USE_TERMIOS */ |
#endif |
961 |
if (col > LINE_BUF_SIZE-2) /* +2 bytes for '\n', NUL, */ |
if (col > LINE_BUF_SIZE-2) /* +2 bytes for '\n', NUL, */ |
962 |
col = LINE_BUF_SIZE-2; |
col = LINE_BUF_SIZE-2; |
963 |
|
|
964 |
/* read process IDs & status for all the processes */ |
/* read process IDs & status for all the processes */ |
965 |
while ((p = procps_scan(p, scan_mask)) != NULL) { |
while ((p = procps_scan(p, scan_mask)) != NULL) { |
966 |
int n; |
int n; |
967 |
if (scan_mask == TOP_MASK) { |
#if ENABLE_FEATURE_TOPMEM |
968 |
|
if (scan_mask != TOPMEM_MASK) |
969 |
|
#endif |
970 |
|
{ |
971 |
n = ntop; |
n = ntop; |
972 |
top = xrealloc_vector(top, 6, ntop++); |
top = xrealloc_vector(top, 6, ntop++); |
973 |
top[n].pid = p->pid; |
top[n].pid = p->pid; |
982 |
#if ENABLE_FEATURE_TOP_SMP_PROCESS |
#if ENABLE_FEATURE_TOP_SMP_PROCESS |
983 |
top[n].last_seen_on_cpu = p->last_seen_on_cpu; |
top[n].last_seen_on_cpu = p->last_seen_on_cpu; |
984 |
#endif |
#endif |
985 |
} else { /* TOPMEM */ |
} |
986 |
#if ENABLE_FEATURE_TOPMEM |
#if ENABLE_FEATURE_TOPMEM |
987 |
|
else { /* TOPMEM */ |
988 |
if (!(p->mapped_ro | p->mapped_rw)) |
if (!(p->mapped_ro | p->mapped_rw)) |
989 |
continue; /* kernel threads are ignored */ |
continue; /* kernel threads are ignored */ |
990 |
n = ntop; |
n = ntop; |
999 |
topmem[n].dirty = p->private_dirty + p->shared_dirty; |
topmem[n].dirty = p->private_dirty + p->shared_dirty; |
1000 |
topmem[n].dirty_sh = p->shared_dirty; |
topmem[n].dirty_sh = p->shared_dirty; |
1001 |
topmem[n].stack = p->stack; |
topmem[n].stack = p->stack; |
|
#endif |
|
1002 |
} |
} |
1003 |
|
#endif |
1004 |
} /* end of "while we read /proc" */ |
} /* end of "while we read /proc" */ |
1005 |
if (ntop == 0) { |
if (ntop == 0) { |
1006 |
bb_error_msg("no process info in /proc"); |
bb_error_msg("no process info in /proc"); |
1007 |
break; |
break; |
1008 |
} |
} |
1009 |
|
|
1010 |
if (scan_mask == TOP_MASK) { |
if (scan_mask != TOPMEM_MASK) { |
1011 |
#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE |
#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE |
1012 |
if (!prev_hist_count) { |
if (!prev_hist_count) { |
1013 |
do_stats(); |
do_stats(); |
1020 |
qsort(top, ntop, sizeof(top_status_t), (void*)mult_lvl_cmp); |
qsort(top, ntop, sizeof(top_status_t), (void*)mult_lvl_cmp); |
1021 |
#else |
#else |
1022 |
qsort(top, ntop, sizeof(top_status_t), (void*)(sort_function[0])); |
qsort(top, ntop, sizeof(top_status_t), (void*)(sort_function[0])); |
1023 |
#endif /* FEATURE_TOP_CPU_USAGE_PERCENTAGE */ |
#endif |
1024 |
} |
} |
1025 |
#if ENABLE_FEATURE_TOPMEM |
#if ENABLE_FEATURE_TOPMEM |
1026 |
else { /* TOPMEM */ |
else { /* TOPMEM */ |
1031 |
if (OPT_BATCH_MODE) { |
if (OPT_BATCH_MODE) { |
1032 |
lines_rem = INT_MAX; |
lines_rem = INT_MAX; |
1033 |
} |
} |
1034 |
if (scan_mask == TOP_MASK) |
if (scan_mask != TOPMEM_MASK) |
1035 |
display_process_list(lines_rem, col); |
display_process_list(lines_rem, col); |
1036 |
#if ENABLE_FEATURE_TOPMEM |
#if ENABLE_FEATURE_TOPMEM |
1037 |
else |
else |
1057 |
if (c == 'q') |
if (c == 'q') |
1058 |
break; |
break; |
1059 |
if (c == 'n') { |
if (c == 'n') { |
1060 |
USE_FEATURE_TOPMEM(scan_mask = TOP_MASK;) |
IF_FEATURE_TOPMEM(scan_mask = TOP_MASK;) |
1061 |
sort_function[0] = pid_sort; |
sort_function[0] = pid_sort; |
1062 |
} |
} |
1063 |
if (c == 'm') { |
if (c == 'm') { |
1064 |
USE_FEATURE_TOPMEM(scan_mask = TOP_MASK;) |
IF_FEATURE_TOPMEM(scan_mask = TOP_MASK;) |
1065 |
sort_function[0] = mem_sort; |
sort_function[0] = mem_sort; |
1066 |
#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE |
# if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE |
1067 |
sort_function[1] = pcpu_sort; |
sort_function[1] = pcpu_sort; |
1068 |
sort_function[2] = time_sort; |
sort_function[2] = time_sort; |
1069 |
#endif |
# endif |
1070 |
} |
} |
1071 |
#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE |
# if ENABLE_FEATURE_SHOW_THREADS |
1072 |
|
if (c == 'h' |
1073 |
|
IF_FEATURE_TOPMEM(&& scan_mask != TOPMEM_MASK) |
1074 |
|
) { |
1075 |
|
scan_mask ^= PSSCAN_TASKS; |
1076 |
|
} |
1077 |
|
# endif |
1078 |
|
# if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE |
1079 |
if (c == 'p') { |
if (c == 'p') { |
1080 |
USE_FEATURE_TOPMEM(scan_mask = TOP_MASK;) |
IF_FEATURE_TOPMEM(scan_mask = TOP_MASK;) |
1081 |
sort_function[0] = pcpu_sort; |
sort_function[0] = pcpu_sort; |
1082 |
sort_function[1] = mem_sort; |
sort_function[1] = mem_sort; |
1083 |
sort_function[2] = time_sort; |
sort_function[2] = time_sort; |
1084 |
} |
} |
1085 |
if (c == 't') { |
if (c == 't') { |
1086 |
USE_FEATURE_TOPMEM(scan_mask = TOP_MASK;) |
IF_FEATURE_TOPMEM(scan_mask = TOP_MASK;) |
1087 |
sort_function[0] = time_sort; |
sort_function[0] = time_sort; |
1088 |
sort_function[1] = mem_sort; |
sort_function[1] = mem_sort; |
1089 |
sort_function[2] = pcpu_sort; |
sort_function[2] = pcpu_sort; |
1090 |
} |
} |
1091 |
#if ENABLE_FEATURE_TOPMEM |
# if ENABLE_FEATURE_TOPMEM |
1092 |
if (c == 's') { |
if (c == 's') { |
1093 |
scan_mask = TOPMEM_MASK; |
scan_mask = TOPMEM_MASK; |
1094 |
free(prev_hist); |
free(prev_hist); |
1098 |
} |
} |
1099 |
if (c == 'r') |
if (c == 'r') |
1100 |
inverted ^= 1; |
inverted ^= 1; |
1101 |
#endif |
# endif |
1102 |
#if ENABLE_FEATURE_TOP_SMP_CPU |
# if ENABLE_FEATURE_TOP_SMP_CPU |
1103 |
/* procps-2.0.18 uses 'C', 3.2.7 uses '1' */ |
/* procps-2.0.18 uses 'C', 3.2.7 uses '1' */ |
1104 |
if (c == 'c' || c == '1') { |
if (c == 'c' || c == '1') { |
1105 |
/* User wants to toggle per cpu <> aggregate */ |
/* User wants to toggle per cpu <> aggregate */ |
1116 |
smp_cpu_info = !smp_cpu_info; |
smp_cpu_info = !smp_cpu_info; |
1117 |
get_jiffy_counts(); |
get_jiffy_counts(); |
1118 |
} |
} |
1119 |
#endif |
# endif |
1120 |
#endif |
# endif |
1121 |
} |
} |
1122 |
#endif /* FEATURE_USE_TERMIOS */ |
#endif /* FEATURE_USE_TERMIOS */ |
1123 |
} /* end of "while (1)" */ |
} /* end of "while (1)" */ |