top: provide the means to adjust scaled summary memory

Earlier this year, the switch from KiB to Mib as shown
in top's summary area was postponed to those occasions
when KiB exceeded 8 digits. In hindsight that may have
moved top in the wrong direction, given the difficulty
of digesting such large numbers of digits at a glance.

This commit adds a new 'E' interactive command used to
cycle the displayed memory amounts ranging from KiB to
TiB. Thus, users can choose the radix they wish shown.

p.s. and it will be rcfile preserved for any restarts!

(now that we know a '.' + 2 spaces is squeezed to one)
(everything's perfectly justified, but it's just luck)

Reference(s):
http://www.freelists.org/post/procps/top-regression-reports

commit 95f2201730
Author: James Cloos <cloos@jhcloos.com>
Date:   Mon Feb 6 00:00:00 2012 -0500

Signed-off-by: Jim Warner <james.warner@comcast.net>
This commit is contained in:
Jim Warner 2012-12-14 00:00:00 -06:00 committed by Craig Small
parent 407d1fc8f2
commit bc46f67f9a
5 changed files with 86 additions and 43 deletions

View File

@ -421,14 +421,14 @@ kernel versions are shown first.
.SS 2c. MEMORY Usage .SS 2c. MEMORY Usage
.\" ---------------------------------------------------------------------- .\" ----------------------------------------------------------------------
This portion consists of two lines which may express values in kibibytes (KiB), This portion consists of two lines which may express values in kibibytes (KiB),
mebibytes (MiB) or gibibytes (GiB) depending on the amount of currently mebibytes (MiB) or gibibytes (GiB) depending on the scaling factor enforced
installed \*(MP. with the 'E' \*(CI.
Line 1 reflects \*(MP, classified as: Line 1 reflects \*(MP, classified as:
total, used, free, buffers total, used, free and buffers
Line 2 reflects \*(MV, classified as: Line 2 reflects mostly \*(MV, classified as:
total, used, free, cached total, used, free and cached (which is \*(MP)
.\" ---------------------------------------------------------------------- .\" ----------------------------------------------------------------------
.SH 3. FIELDS / Columns .SH 3. FIELDS / Columns
@ -832,7 +832,8 @@ depending on the context in which they are issued.
.Bd -literal .Bd -literal
4a.\fI Global-Commands \fR 4a.\fI Global-Commands \fR
<Ent/Sp> ?, =, A, B, d, g, h, H, I, k, q, r, s, W, X, Y, Z <Ent/Sp> ?, =,
A, B, d, E, g, h, H, I, k, q, r, s, W, X, Y, Z
4b.\fI Summary-Area-Commands \fR 4b.\fI Summary-Area-Commands \fR
C, l, t, 1, m C, l, t, 1, m
4c.\fI Task-Area-Commands \fR 4c.\fI Task-Area-Commands \fR
@ -927,6 +928,16 @@ so set it with care.
If at any time you wish to know the current delay time, simply ask for If at any time you wish to know the current delay time, simply ask for
help and view the system summary on the second line. help and view the system summary on the second line.
.TP 7
\ \ \'\fBE\fR\' :\fIExtend-Memory-Scale\fR in Summary Area
With this command you can cycle through the available \*(SA memory scaling
which ranges from KiB (kibibytes or 1,024 bytes) through TiB (tebibytes or
1,099,511,627,776 bytes).
If you see a '+' between a displayed number and the following label, it
means that \*(We was forced to truncate some portion of that number.
By raising the scaling factor, such truncation can usually be avoided.
.TP 7 .TP 7
\ \ \'\fBg\fR\' :\fIChoose-Another-Window/Field-Group \fR \ \ \'\fBg\fR\' :\fIChoose-Another-Window/Field-Group \fR
You will be prompted to enter a number between 1 and 4 designating the You will be prompted to enter a number between 1 and 4 designating the

View File

@ -3065,7 +3065,7 @@ static void configs_read (void) {
} // end: for (GROUPSMAX) } // end: for (GROUPSMAX)
// any new addition(s) last, for older rcfiles compatibility... // any new addition(s) last, for older rcfiles compatibility...
fscanf(fp, "Fixed_widest=%d\n", &Rc.fixed_widest); fscanf(fp, "Fixed_widest=%d, Summ_mscale=%d\n", &Rc.fixed_widest, &Rc.summ_mscale);
try_inspect_entries: try_inspect_entries:
@ -3653,7 +3653,7 @@ static void file_writerc (void) {
} }
// any new addition(s) last, for older rcfiles compatibility... // any new addition(s) last, for older rcfiles compatibility...
fprintf(fp, "Fixed_widest=%d\n", Rc.fixed_widest); fprintf(fp, "Fixed_widest=%d, Summ_mscale=%d\n", Rc.fixed_widest, Rc.summ_mscale);
if (Inspect.raw) if (Inspect.raw)
fputs(Inspect.raw, fp); fputs(Inspect.raw, fp);
@ -3769,6 +3769,10 @@ static void keys_global (int ch) {
if (-1 < tmp) Rc.delay_time = tmp; if (-1 < tmp) Rc.delay_time = tmp;
} }
break; break;
case 'E':
// current summary_show limits: 0 == kilo through 3 == tera
if (++Rc.summ_mscale > 3) Rc.summ_mscale = 0;
break;
case 'F': case 'F':
case 'f': case 'f':
fields_utility(); fields_utility();
@ -4307,7 +4311,7 @@ static void do_key (int ch) {
char keys[SMLBUFSIZ]; char keys[SMLBUFSIZ];
} key_tab[] = { } key_tab[] = {
{ keys_global, { keys_global,
{ '?', 'B', 'd', 'F', 'f', 'g', 'H', 'h', 'I', 'k', 'r', 's', 'X', 'Y', 'Z' { '?', 'B', 'd', 'E', 'F', 'f', 'g', 'H', 'h', 'I', 'k', 'r', 's', 'X', 'Y', 'Z'
, kbd_ENTER, kbd_SPACE, '\0' } }, , kbd_ENTER, kbd_SPACE, '\0' } },
{ keys_summary, { keys_summary,
{ '1', 'C', 'l', 'm', 't', '\0' } }, { '1', 'C', 'l', 'm', 't', '\0' } },
@ -4461,23 +4465,47 @@ static void summary_show (void) {
// Display Memory and Swap stats // Display Memory and Swap stats
if (isROOM(View_MEMORY, 2)) { if (isROOM(View_MEMORY, 2)) {
#define mkM(x) (unsigned long)(kb_main_ ## x >> shift) #define bfT(n) buftab[n].buf
#define mkS(x) (unsigned long)(kb_swap_ ## x >> shift) #define scT(e) scaletab[Rc.summ_mscale]. e
const char *which = N_txt(AMT_kilobyte_txt); #define mkM(x) (float)kb_main_ ## x / scT(div)
int shift = 0; #define mkS(x) (float)kb_swap_ ## x / scT(div)
#define prT(b,z) { if (9 < snprintf(b, 10, scT(fmts), z)) b[8] = '+'; }
static struct {
float div;
const char *fmts;
const char *label;
} scaletab[] = {
{ 1, "%8.0f ", NULL }, // kilo
{ 1024.0, "%#5.2f ", NULL }, // mega
{ 1024.0*1024, "%#4.3f ", NULL }, // giga
{ 1024.0*1024*1024, "%#3.4f ", NULL } // tera
};
struct {
// after snprintf, contents of each buf: 'nnnnnnnn 0'
// and prT macro might replace space at buf[8] with: ---> +
char buf[10]; // MEMORY_lines_fmt provides for 8+1 bytes
} buftab[8];
/*** hotplug_acclimated ***/ if (!scaletab[0].label) {
if (kb_main_total > 99999999) scaletab[0].label = N_txt(AMT_kilobyte_txt);
{ which = N_txt(AMT_megabyte_txt); shift = 10; } scaletab[1].label = N_txt(AMT_megabyte_txt);
if (kb_main_total > 9999999999ull) scaletab[2].label = N_txt(AMT_gigabyte_txt);
{ which = N_txt(AMT_gigabyte_txt); shift = 20; } scaletab[3].label = N_txt(AMT_terabyte_txt);
}
prT(bfT(0), mkM(total)); prT(bfT(1), mkM(used));
prT(bfT(2), mkM(free)); prT(bfT(3), mkM(buffers));
prT(bfT(4), mkS(total)); prT(bfT(5), mkS(used));
prT(bfT(6), mkS(free)); prT(bfT(7), mkM(cached));
show_special(0, fmtmk(N_unq(MEMORY_lines_fmt) show_special(0, fmtmk(N_unq(MEMORY_lines_fmt)
, which, mkM(total), mkM(used), mkM(free), mkM(buffers) , scT(label), &bfT(0), &bfT(1), &bfT(2), &bfT(3)
, which, mkS(total), mkS(used), mkS(free), mkM(cached))); , scT(label), &bfT(4), &bfT(5), &bfT(6), &bfT(7)));
Msg_row += 2; Msg_row += 2;
#undef bfT
#undef scT
#undef mkM #undef mkM
#undef mkS #undef mkS
#undef prT
} }
#undef isROOM #undef isROOM

View File

@ -336,6 +336,7 @@ typedef struct RCF_t {
int win_index; // Curwin, as index int win_index; // Curwin, as index
RCW_t win [GROUPSMAX]; // a 'WIN_t.rc' for each window RCW_t win [GROUPSMAX]; // a 'WIN_t.rc' for each window
int fixed_widest; // 'X' - wider non-scalable col addition int fixed_widest; // 'X' - wider non-scalable col addition
int summ_mscale; // 'E' - scaling of summary memory values
} RCF_t; } RCF_t;
/* This structure stores configurable information for each window. /* This structure stores configurable information for each window.

View File

@ -353,6 +353,9 @@ static void build_norm_nlstab (void) {
/* Translation Hint: This is an abbreviation (limit 3 characters) for: /* Translation Hint: This is an abbreviation (limit 3 characters) for:
. gibibytes (1,073,741,824 bytes) */ . gibibytes (1,073,741,824 bytes) */
Norm_nlstab[AMT_gigabyte_txt] = _("GiB"); Norm_nlstab[AMT_gigabyte_txt] = _("GiB");
/* Translation Hint: This is an abbreviation (limit 3 characters) for:
. tebibytes (1,099,511,627,776 bytes) */
Norm_nlstab[AMT_terabyte_txt] = _("TiB");
Norm_nlstab[WORD_threads_txt] = _("Threads"); Norm_nlstab[WORD_threads_txt] = _("Threads");
Norm_nlstab[WORD_process_txt] = _("Tasks"); Norm_nlstab[WORD_process_txt] = _("Tasks");
/* Translation Hint: The following "word" is meant to represent either a single /* Translation Hint: The following "word" is meant to represent either a single
@ -455,7 +458,7 @@ static void build_uniq_nlstab (void) {
"Help for Interactive Commands~2 - %s\n" "Help for Interactive Commands~2 - %s\n"
"Window ~1%s~6: ~1Cumulative mode ~3%s~2. ~1System~6: ~1Delay ~3%.1f secs~2; ~1Secure mode ~3%s~2.\n" "Window ~1%s~6: ~1Cumulative mode ~3%s~2. ~1System~6: ~1Delay ~3%.1f secs~2; ~1Secure mode ~3%s~2.\n"
"\n" "\n"
" Z~5,~1B~5 Global: '~1Z~2' change color mappings; '~1B~2' disable/enable bold\n" " Z~5,~1B~5,E Global: '~1Z~2' color mappings; '~1B~2' bold; '~1E~2' summary mem scale\n"
" l,t,m Toggle Summaries: '~1l~2' load avg; '~1t~2' task/cpu stats; '~1m~2' mem info\n" " l,t,m Toggle Summaries: '~1l~2' load avg; '~1t~2' task/cpu stats; '~1m~2' mem info\n"
" 1,I Toggle SMP view: '~11~2' single/separate states; '~1I~2' Irix/Solaris mode\n" " 1,I Toggle SMP view: '~11~2' single/separate states; '~1I~2' Irix/Solaris mode\n"
" f,F,X Fields: '~1f~2'/'~1F~2' add/remove/order/sort; '~1X~2' increase fixed-width\n" " f,F,X Fields: '~1f~2'/'~1F~2' add/remove/order/sort; '~1X~2' increase fixed-width\n"
@ -465,7 +468,7 @@ static void build_uniq_nlstab (void) {
" c,i,S,j . Toggle: '~1c~2' Cmd name/line; '~1i~2' Idle; '~1S~2' Time; '~1j~2' Str justify\n" " c,i,S,j . Toggle: '~1c~2' Cmd name/line; '~1i~2' Idle; '~1S~2' Time; '~1j~2' Str justify\n"
" x~5,~1y~5 . Toggle highlights: '~1x~2' sort field; '~1y~2' running tasks\n" " x~5,~1y~5 . Toggle highlights: '~1x~2' sort field; '~1y~2' running tasks\n"
" z~5,~1b~5 . Toggle: '~1z~2' color/mono; '~1b~2' bold/reverse (only if 'x' or 'y')\n" " z~5,~1b~5 . Toggle: '~1z~2' color/mono; '~1b~2' bold/reverse (only if 'x' or 'y')\n"
" u,U . Filter by: '~1u~2' effective user; '~1U~2' real, saved, file or effective user\n" " u,U . Filter by: '~1u~2' effective user; '~1U~2' effective/file/real/saved user\n"
" n or # . Set maximum tasks displayed\n" " n or # . Set maximum tasks displayed\n"
" C,... . Toggle scroll coordinates msg for: ~1up~2,~1down~2,~1left~2,right~2,~1home~2,~1end~2\n" " C,... . Toggle scroll coordinates msg for: ~1up~2,~1down~2,~1left~2,right~2,~1home~2,~1end~2\n"
"\n" "\n"
@ -589,8 +592,8 @@ static void build_uniq_nlstab (void) {
. abbreviations: Mem = physical memory/ram, Swap = the linux swap file . abbreviations: Mem = physical memory/ram, Swap = the linux swap file
. words: total, used, free, buffers, cached */ . words: total, used, free, buffers, cached */
Uniq_nlstab[MEMORY_lines_fmt] = _("" Uniq_nlstab[MEMORY_lines_fmt] = _(""
"%s Mem: ~3 %8lu ~2total,~3 %8lu ~2used,~3 %8lu ~2free,~3 %8lu ~2buffers~3\n" "%s Mem: ~3 %9.9s~2total,~3 %9.9s~2used,~3 %9.9s~2free,~3 %9.9s~2buffers~3\n"
"%s Swap:~3 %8lu ~2total,~3 %8lu ~2used,~3 %8lu ~2free,~3 %8lu ~2cached~3\n"); "%s Swap:~3 %9.9s~2total,~3 %9.9s~2used,~3 %9.9s~2free,~3 %9.9s~2cached~3\n");
Uniq_nlstab[INSP_hdrsels_fmt] = _("" Uniq_nlstab[INSP_hdrsels_fmt] = _(""
"Inspection~2 Pause at: pid ~1%d~6 running ~1%s~6 as user ~1%s~6\n" "Inspection~2 Pause at: pid ~1%d~6 running ~1%s~6 as user ~1%s~6\n"

View File

@ -62,25 +62,25 @@ extern const char *Uniq_nlstab[];
* from any text also containiing c-format specifiers. * from any text also containiing c-format specifiers.
*/ */
enum norm_nls { enum norm_nls {
AMT_kilobyte_txt, AMT_megabyte_txt, AMT_gigabyte_txt, BAD_delayint_fmt, AMT_kilobyte_txt, AMT_megabyte_txt, AMT_gigabyte_txt, AMT_terabyte_txt,
BAD_integers_txt, BAD_max_task_txt, BAD_mon_pids_fmt, BAD_niterate_fmt, BAD_delayint_fmt, BAD_integers_txt, BAD_max_task_txt, BAD_mon_pids_fmt,
BAD_numfloat_txt, BAD_signalid_txt, BAD_username_txt, BAD_widtharg_fmt, BAD_niterate_fmt, BAD_numfloat_txt, BAD_signalid_txt, BAD_username_txt,
CHOOSE_group_txt, COLORS_nomap_txt, DELAY_badarg_txt, DELAY_change_fmt, BAD_widtharg_fmt, CHOOSE_group_txt, COLORS_nomap_txt, DELAY_badarg_txt,
DELAY_secure_txt, DISABLED_cmd_txt, DISABLED_win_fmt, EXIT_signals_fmt, DELAY_change_fmt, DELAY_secure_txt, DISABLED_cmd_txt, DISABLED_win_fmt,
FAIL_alloc_c_txt, FAIL_alloc_r_txt, FAIL_openlib_fmt, FAIL_rc_open_fmt, EXIT_signals_fmt, FAIL_alloc_c_txt, FAIL_alloc_r_txt, FAIL_openlib_fmt,
FAIL_re_nice_fmt, FAIL_sigmask_fmt, FAIL_signals_fmt, FAIL_sigstop_fmt, FAIL_rc_open_fmt, FAIL_re_nice_fmt, FAIL_sigmask_fmt, FAIL_signals_fmt,
FAIL_statget_txt, FAIL_statopn_fmt, FAIL_tty_get_txt, FAIL_tty_mod_fmt, FAIL_sigstop_fmt, FAIL_statget_txt, FAIL_statopn_fmt, FAIL_tty_get_txt,
FAIL_tty_raw_fmt, FAIL_widecpu_txt, FAIL_widepid_txt, FIND_no_find_fmt, FAIL_tty_mod_fmt, FAIL_tty_raw_fmt, FAIL_widecpu_txt, FAIL_widepid_txt,
FIND_no_next_txt, FOREST_modes_fmt, FOREST_views_txt, GET_find_str_txt, FIND_no_find_fmt, FIND_no_next_txt, FOREST_modes_fmt, FOREST_views_txt,
GET_max_task_fmt, GET_nice_num_fmt, GET_pid2kill_fmt, GET_pid2nice_fmt, GET_find_str_txt, GET_max_task_fmt, GET_nice_num_fmt, GET_pid2kill_fmt,
GET_sigs_num_fmt, GET_user_ids_txt, HELP_cmdline_fmt, HILIGHT_cant_txt, GET_pid2nice_fmt, GET_sigs_num_fmt, GET_user_ids_txt, HELP_cmdline_fmt,
IRIX_curmode_fmt, LIMIT_exceed_fmt, MISSING_args_fmt, NAME_windows_fmt, HILIGHT_cant_txt, IRIX_curmode_fmt, LIMIT_exceed_fmt, MISSING_args_fmt,
NOT_onsecure_txt, NOT_smp_cpus_txt, OFF_one_word_txt, ON_word_only_txt, NAME_windows_fmt, NOT_onsecure_txt, NOT_smp_cpus_txt, OFF_one_word_txt,
RC_bad_entry_fmt, RC_bad_files_fmt, SCROLL_coord_fmt, SELECT_clash_txt, ON_word_only_txt, RC_bad_entry_fmt, RC_bad_files_fmt, SCROLL_coord_fmt,
THREADS_show_fmt, TIME_accumed_fmt, UNKNOWN_cmds_txt, UNKNOWN_opts_fmt, SELECT_clash_txt, THREADS_show_fmt, TIME_accumed_fmt, UNKNOWN_cmds_txt,
USAGE_abbrev_txt, WORD_allcpus_txt, WORD_another_txt, WORD_eachcpu_fmt, UNKNOWN_opts_fmt, USAGE_abbrev_txt, WORD_allcpus_txt, WORD_another_txt,
WORD_process_txt, WORD_threads_txt, WRITE_rcfile_fmt, WRONG_switch_fmt, WORD_eachcpu_fmt, WORD_process_txt, WORD_threads_txt, WRITE_rcfile_fmt,
XTRA_fixwide_fmt, XTRA_sortopt_fmt, XTRA_warncfg_txt, WRONG_switch_fmt, XTRA_fixwide_fmt, XTRA_sortopt_fmt, XTRA_warncfg_txt,
#ifndef INSP_OFFDEMO #ifndef INSP_OFFDEMO
YINSP_demo01_txt, YINSP_demo02_txt, YINSP_demo03_txt, YINSP_deqfmt_txt, YINSP_demo01_txt, YINSP_demo02_txt, YINSP_demo03_txt, YINSP_deqfmt_txt,
YINSP_deqtyp_txt, YINSP_dstory_txt, YINSP_deqtyp_txt, YINSP_dstory_txt,