top: implement scrolling up/down (_very_ useful)
function old new delta handle_input 494 564 +70 top_main 928 947 +19 display_topmem_process_list 363 381 +18 display_process_list 1442 1453 +11 clearmems 38 28 -10 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 4/1 up/down: 118/-10) Total: 108 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
3c62bbae94
commit
2fb8d0dee9
@ -140,60 +140,6 @@ config BB_SYSCTL
|
||||
help
|
||||
Configure kernel parameters at runtime.
|
||||
|
||||
config TOP
|
||||
bool "top"
|
||||
default y
|
||||
help
|
||||
The top program provides a dynamic real-time view of a running
|
||||
system.
|
||||
|
||||
config FEATURE_TOP_CPU_USAGE_PERCENTAGE
|
||||
bool "Show CPU per-process usage percentage"
|
||||
default y
|
||||
depends on TOP
|
||||
help
|
||||
Make top display CPU usage for each process.
|
||||
This adds about 2k.
|
||||
|
||||
config FEATURE_TOP_CPU_GLOBAL_PERCENTS
|
||||
bool "Show CPU global usage percentage"
|
||||
default y
|
||||
depends on FEATURE_TOP_CPU_USAGE_PERCENTAGE
|
||||
help
|
||||
Makes top display "CPU: NN% usr NN% sys..." line.
|
||||
This adds about 0.5k.
|
||||
|
||||
config FEATURE_TOP_SMP_CPU
|
||||
bool "SMP CPU usage display ('c' key)"
|
||||
default y
|
||||
depends on FEATURE_TOP_CPU_GLOBAL_PERCENTS
|
||||
help
|
||||
Allow 'c' key to switch between individual/cumulative CPU stats
|
||||
This adds about 0.5k.
|
||||
|
||||
config FEATURE_TOP_DECIMALS
|
||||
bool "Show 1/10th of a percent in CPU/mem statistics"
|
||||
default y
|
||||
depends on FEATURE_TOP_CPU_USAGE_PERCENTAGE
|
||||
help
|
||||
Show 1/10th of a percent in CPU/mem statistics.
|
||||
This adds about 0.3k.
|
||||
|
||||
config FEATURE_TOP_SMP_PROCESS
|
||||
bool "Show CPU process runs on ('j' field)"
|
||||
default y
|
||||
depends on TOP
|
||||
help
|
||||
Show CPU where process was last found running on.
|
||||
This is the 'j' field.
|
||||
|
||||
config FEATURE_TOPMEM
|
||||
bool "Topmem command ('s' key)"
|
||||
default y
|
||||
depends on TOP
|
||||
help
|
||||
Enable 's' in top (gives lots of memory info).
|
||||
|
||||
config FEATURE_SHOW_THREADS
|
||||
bool "Support for showing threads in ps/pstree/top"
|
||||
default y
|
||||
|
130
procps/top.c
130
procps/top.c
@ -50,6 +50,60 @@
|
||||
* chroot . ./top -bn1 >top1.out
|
||||
*/
|
||||
|
||||
//config:config TOP
|
||||
//config: bool "top"
|
||||
//config: default y
|
||||
//config: help
|
||||
//config: The top program provides a dynamic real-time view of a running
|
||||
//config: system.
|
||||
//config:
|
||||
//config:config FEATURE_TOP_CPU_USAGE_PERCENTAGE
|
||||
//config: bool "Show CPU per-process usage percentage"
|
||||
//config: default y
|
||||
//config: depends on TOP
|
||||
//config: help
|
||||
//config: Make top display CPU usage for each process.
|
||||
//config: This adds about 2k.
|
||||
//config:
|
||||
//config:config FEATURE_TOP_CPU_GLOBAL_PERCENTS
|
||||
//config: bool "Show CPU global usage percentage"
|
||||
//config: default y
|
||||
//config: depends on FEATURE_TOP_CPU_USAGE_PERCENTAGE
|
||||
//config: help
|
||||
//config: Makes top display "CPU: NN% usr NN% sys..." line.
|
||||
//config: This adds about 0.5k.
|
||||
//config:
|
||||
//config:config FEATURE_TOP_SMP_CPU
|
||||
//config: bool "SMP CPU usage display ('c' key)"
|
||||
//config: default y
|
||||
//config: depends on FEATURE_TOP_CPU_GLOBAL_PERCENTS
|
||||
//config: help
|
||||
//config: Allow 'c' key to switch between individual/cumulative CPU stats
|
||||
//config: This adds about 0.5k.
|
||||
//config:
|
||||
//config:config FEATURE_TOP_DECIMALS
|
||||
//config: bool "Show 1/10th of a percent in CPU/mem statistics"
|
||||
//config: default y
|
||||
//config: depends on FEATURE_TOP_CPU_USAGE_PERCENTAGE
|
||||
//config: help
|
||||
//config: Show 1/10th of a percent in CPU/mem statistics.
|
||||
//config: This adds about 0.3k.
|
||||
//config:
|
||||
//config:config FEATURE_TOP_SMP_PROCESS
|
||||
//config: bool "Show CPU process runs on ('j' field)"
|
||||
//config: default y
|
||||
//config: depends on TOP
|
||||
//config: help
|
||||
//config: Show CPU where process was last found running on.
|
||||
//config: This is the 'j' field.
|
||||
//config:
|
||||
//config:config FEATURE_TOPMEM
|
||||
//config: bool "Topmem command ('s' key)"
|
||||
//config: default y
|
||||
//config: depends on TOP
|
||||
//config: help
|
||||
//config: Enable 's' in top (gives lots of memory info).
|
||||
|
||||
#include "libbb.h"
|
||||
|
||||
|
||||
@ -101,6 +155,8 @@ struct globals {
|
||||
#endif
|
||||
#if ENABLE_FEATURE_USE_TERMIOS
|
||||
struct termios initial_settings;
|
||||
unsigned lines; /* screen height */
|
||||
int scroll_ofs;
|
||||
#endif
|
||||
#if !ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE
|
||||
cmp_funcp sort_function[1];
|
||||
@ -117,6 +173,9 @@ struct globals {
|
||||
/* Per CPU samples: current and last */
|
||||
jiffy_counts_t *cpu_jif, *cpu_prev_jif;
|
||||
int num_cpus;
|
||||
#endif
|
||||
#if ENABLE_FEATURE_USE_TERMIOS
|
||||
char kbd_input[KEYCODE_BUFFER_SIZE];
|
||||
#endif
|
||||
char line_buf[80];
|
||||
}; //FIX_ALIASING; - large code growth
|
||||
@ -602,9 +661,9 @@ static NOINLINE void display_process_list(int lines_rem, int scr_width)
|
||||
|
||||
/* Ok, all preliminary data is ready, go through the list */
|
||||
scr_width += 2; /* account for leading '\n' and trailing NUL */
|
||||
if (lines_rem > ntop)
|
||||
lines_rem = ntop;
|
||||
s = top;
|
||||
if (lines_rem > ntop - G.scroll_ofs)
|
||||
lines_rem = ntop - G.scroll_ofs;
|
||||
s = top + G.scroll_ofs;
|
||||
while (--lines_rem >= 0) {
|
||||
unsigned col;
|
||||
CALC_STAT(pmem, (s->vsz*pmem_scale + pmem_half) >> pmem_shift);
|
||||
@ -649,7 +708,6 @@ static void clearmems(void)
|
||||
clear_username_cache();
|
||||
free(top);
|
||||
top = NULL;
|
||||
ntop = 0;
|
||||
}
|
||||
|
||||
#if ENABLE_FEATURE_USE_TERMIOS
|
||||
@ -793,7 +851,7 @@ static NOINLINE void display_topmem_process_list(int lines_rem, int scr_width)
|
||||
{
|
||||
#define HDR_STR " PID VSZ VSZRW RSS (SHR) DIRTY (SHR) STACK"
|
||||
#define MIN_WIDTH sizeof(HDR_STR)
|
||||
const topmem_status_t *s = topmem;
|
||||
const topmem_status_t *s = topmem + G.scroll_ofs;
|
||||
|
||||
display_topmem_header(scr_width, &lines_rem);
|
||||
strcpy(line_buf, HDR_STR " COMMAND");
|
||||
@ -801,8 +859,8 @@ static NOINLINE void display_topmem_process_list(int lines_rem, int scr_width)
|
||||
printf(OPT_BATCH_MODE ? "%.*s" : "\e[7m%.*s\e[0m", scr_width, line_buf);
|
||||
lines_rem--;
|
||||
|
||||
if (lines_rem > ntop)
|
||||
lines_rem = ntop;
|
||||
if (lines_rem > ntop - G.scroll_ofs)
|
||||
lines_rem = ntop - G.scroll_ofs;
|
||||
while (--lines_rem >= 0) {
|
||||
/* PID VSZ VSZRW RSS (SHR) DIRTY (SHR) COMMAND */
|
||||
ulltoa6_and_space(s->pid , &line_buf[0*6]);
|
||||
@ -856,26 +914,57 @@ enum {
|
||||
#if ENABLE_FEATURE_USE_TERMIOS
|
||||
static unsigned handle_input(unsigned scan_mask, unsigned interval)
|
||||
{
|
||||
unsigned char c;
|
||||
struct pollfd pfd[1];
|
||||
|
||||
pfd[0].fd = 0;
|
||||
pfd[0].events = POLLIN;
|
||||
|
||||
while (1) {
|
||||
if (safe_poll(pfd, 1, interval * 1000) <= 0)
|
||||
return scan_mask;
|
||||
interval = 0;
|
||||
int32_t c;
|
||||
|
||||
if (safe_read(STDIN_FILENO, &c, 1) != 1) { /* error/EOF? */
|
||||
c = read_key(STDIN_FILENO, G.kbd_input, interval * 1000);
|
||||
if (c == -1 && errno != EAGAIN) {
|
||||
/* error/EOF */
|
||||
option_mask32 |= OPT_EOF;
|
||||
return scan_mask;
|
||||
break;
|
||||
}
|
||||
interval = 0;
|
||||
|
||||
if (c == initial_settings.c_cc[VINTR])
|
||||
return EXIT_MASK;
|
||||
if (c == initial_settings.c_cc[VEOF])
|
||||
return EXIT_MASK;
|
||||
|
||||
if (c == KEYCODE_UP) {
|
||||
G.scroll_ofs--;
|
||||
goto normalize_ofs;
|
||||
}
|
||||
if (c == KEYCODE_DOWN) {
|
||||
G.scroll_ofs++;
|
||||
goto normalize_ofs;
|
||||
}
|
||||
if (c == KEYCODE_HOME) {
|
||||
G.scroll_ofs = 0;
|
||||
break;
|
||||
}
|
||||
if (c == KEYCODE_END) {
|
||||
G.scroll_ofs = ntop - G.lines / 2;
|
||||
goto normalize_ofs;
|
||||
}
|
||||
if (c == KEYCODE_PAGEUP) {
|
||||
G.scroll_ofs -= G.lines / 2;
|
||||
goto normalize_ofs;
|
||||
}
|
||||
if (c == KEYCODE_PAGEDOWN) {
|
||||
G.scroll_ofs += G.lines / 2;
|
||||
normalize_ofs:
|
||||
if (G.scroll_ofs >= ntop)
|
||||
G.scroll_ofs = ntop - 1;
|
||||
if (G.scroll_ofs < 0)
|
||||
G.scroll_ofs = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
c |= 0x20; /* lowercase */
|
||||
if (c == 'q')
|
||||
return EXIT_MASK;
|
||||
@ -1011,7 +1100,7 @@ int top_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
||||
int top_main(int argc UNUSED_PARAM, char **argv)
|
||||
{
|
||||
int iterations;
|
||||
unsigned lines, col;
|
||||
unsigned col;
|
||||
unsigned interval;
|
||||
char *str_interval, *str_iterations;
|
||||
unsigned scan_mask = TOP_MASK;
|
||||
@ -1081,15 +1170,15 @@ int top_main(int argc UNUSED_PARAM, char **argv)
|
||||
procps_status_t *p = NULL;
|
||||
|
||||
if (OPT_BATCH_MODE) {
|
||||
lines = INT_MAX;
|
||||
G.lines = INT_MAX;
|
||||
col = LINE_BUF_SIZE - 2; /* +2 bytes for '\n', NUL */
|
||||
} else {
|
||||
lines = 24; /* default */
|
||||
G.lines = 24; /* default */
|
||||
col = 79;
|
||||
#if ENABLE_FEATURE_USE_TERMIOS
|
||||
/* We output to stdout, we need size of stdout (not stdin)! */
|
||||
get_terminal_width_height(STDOUT_FILENO, &col, &lines);
|
||||
if (lines < 5 || col < 10) {
|
||||
get_terminal_width_height(STDOUT_FILENO, &col, &G.lines);
|
||||
if (G.lines < 5 || col < 10) {
|
||||
sleep(interval);
|
||||
continue;
|
||||
}
|
||||
@ -1099,6 +1188,7 @@ int top_main(int argc UNUSED_PARAM, char **argv)
|
||||
}
|
||||
|
||||
/* read process IDs & status for all the processes */
|
||||
ntop = 0;
|
||||
while ((p = procps_scan(p, scan_mask)) != NULL) {
|
||||
int n;
|
||||
#if ENABLE_FEATURE_TOPMEM
|
||||
@ -1165,10 +1255,10 @@ int top_main(int argc UNUSED_PARAM, char **argv)
|
||||
}
|
||||
#endif
|
||||
if (scan_mask != TOPMEM_MASK)
|
||||
display_process_list(lines, col);
|
||||
display_process_list(G.lines, col);
|
||||
#if ENABLE_FEATURE_TOPMEM
|
||||
else
|
||||
display_topmem_process_list(lines, col);
|
||||
display_topmem_process_list(G.lines, col);
|
||||
#endif
|
||||
clearmems();
|
||||
if (iterations >= 0 && !--iterations)
|
||||
|
Loading…
Reference in New Issue
Block a user