From bc46f67f9a63c9f43c9a697b3bfa85abf721c5da Mon Sep 17 00:00:00 2001 From: Jim Warner Date: Fri, 14 Dec 2012 00:00:00 -0600 Subject: [PATCH] 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 95f22017309f0025c724258335cf586b1d939e68 Author: James Cloos Date: Mon Feb 6 00:00:00 2012 -0500 Signed-off-by: Jim Warner --- top/top.1 | 23 +++++++++++++++------ top/top.c | 56 ++++++++++++++++++++++++++++++++++++++------------- top/top.h | 1 + top/top_nls.c | 11 ++++++---- top/top_nls.h | 38 +++++++++++++++++----------------- 5 files changed, 86 insertions(+), 43 deletions(-) diff --git a/top/top.1 b/top/top.1 index 741d2e0b..0ba5bed4 100644 --- a/top/top.1 +++ b/top/top.1 @@ -421,14 +421,14 @@ kernel versions are shown first. .SS 2c. MEMORY Usage .\" ---------------------------------------------------------------------- This portion consists of two lines which may express values in kibibytes (KiB), -mebibytes (MiB) or gibibytes (GiB) depending on the amount of currently -installed \*(MP. +mebibytes (MiB) or gibibytes (GiB) depending on the scaling factor enforced +with the 'E' \*(CI. Line 1 reflects \*(MP, classified as: - total, used, free, buffers + total, used, free and buffers -Line 2 reflects \*(MV, classified as: - total, used, free, cached +Line 2 reflects mostly \*(MV, classified as: + total, used, free and cached (which is \*(MP) .\" ---------------------------------------------------------------------- .SH 3. FIELDS / Columns @@ -832,7 +832,8 @@ depending on the context in which they are issued. .Bd -literal 4a.\fI Global-Commands \fR - ?, =, A, B, d, g, h, H, I, k, q, r, s, W, X, Y, Z + ?, =, + A, B, d, E, g, h, H, I, k, q, r, s, W, X, Y, Z 4b.\fI Summary-Area-Commands \fR C, l, t, 1, m 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 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 \ \ \'\fBg\fR\' :\fIChoose-Another-Window/Field-Group \fR You will be prompted to enter a number between 1 and 4 designating the diff --git a/top/top.c b/top/top.c index 1a7b7576..655bf0c2 100644 --- a/top/top.c +++ b/top/top.c @@ -3065,7 +3065,7 @@ static void configs_read (void) { } // end: for (GROUPSMAX) // 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: @@ -3653,7 +3653,7 @@ static void file_writerc (void) { } // 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) fputs(Inspect.raw, fp); @@ -3769,6 +3769,10 @@ static void keys_global (int ch) { if (-1 < tmp) Rc.delay_time = tmp; } 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': fields_utility(); @@ -4307,7 +4311,7 @@ static void do_key (int ch) { char keys[SMLBUFSIZ]; } key_tab[] = { { 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' } }, { keys_summary, { '1', 'C', 'l', 'm', 't', '\0' } }, @@ -4461,23 +4465,47 @@ static void summary_show (void) { // Display Memory and Swap stats if (isROOM(View_MEMORY, 2)) { - #define mkM(x) (unsigned long)(kb_main_ ## x >> shift) - #define mkS(x) (unsigned long)(kb_swap_ ## x >> shift) - const char *which = N_txt(AMT_kilobyte_txt); - int shift = 0; + #define bfT(n) buftab[n].buf + #define scT(e) scaletab[Rc.summ_mscale]. e + #define mkM(x) (float)kb_main_ ## x / scT(div) + #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 (kb_main_total > 99999999) - { which = N_txt(AMT_megabyte_txt); shift = 10; } - if (kb_main_total > 9999999999ull) - { which = N_txt(AMT_gigabyte_txt); shift = 20; } + if (!scaletab[0].label) { + scaletab[0].label = N_txt(AMT_kilobyte_txt); + scaletab[1].label = N_txt(AMT_megabyte_txt); + scaletab[2].label = N_txt(AMT_gigabyte_txt); + 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) - , which, mkM(total), mkM(used), mkM(free), mkM(buffers) - , which, mkS(total), mkS(used), mkS(free), mkM(cached))); + , scT(label), &bfT(0), &bfT(1), &bfT(2), &bfT(3) + , scT(label), &bfT(4), &bfT(5), &bfT(6), &bfT(7))); Msg_row += 2; + #undef bfT + #undef scT #undef mkM #undef mkS + #undef prT } #undef isROOM diff --git a/top/top.h b/top/top.h index 9f052305..be5bdfc6 100644 --- a/top/top.h +++ b/top/top.h @@ -336,6 +336,7 @@ typedef struct RCF_t { int win_index; // Curwin, as index RCW_t win [GROUPSMAX]; // a 'WIN_t.rc' for each window int fixed_widest; // 'X' - wider non-scalable col addition + int summ_mscale; // 'E' - scaling of summary memory values } RCF_t; /* This structure stores configurable information for each window. diff --git a/top/top_nls.c b/top/top_nls.c index 5d6f5f68..fa08928b 100644 --- a/top/top_nls.c +++ b/top/top_nls.c @@ -353,6 +353,9 @@ static void build_norm_nlstab (void) { /* Translation Hint: This is an abbreviation (limit 3 characters) for: . gibibytes (1,073,741,824 bytes) */ 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_process_txt] = _("Tasks"); /* 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" "Window ~1%s~6: ~1Cumulative mode ~3%s~2. ~1System~6: ~1Delay ~3%.1f secs~2; ~1Secure mode ~3%s~2.\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" " 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" @@ -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" " 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" - " 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" " C,... . Toggle scroll coordinates msg for: ~1up~2,~1down~2,~1left~2,right~2,~1home~2,~1end~2\n" "\n" @@ -589,8 +592,8 @@ static void build_uniq_nlstab (void) { . abbreviations: Mem = physical memory/ram, Swap = the linux swap file . words: total, used, free, buffers, cached */ Uniq_nlstab[MEMORY_lines_fmt] = _("" - "%s Mem: ~3 %8lu ~2total,~3 %8lu ~2used,~3 %8lu ~2free,~3 %8lu ~2buffers~3\n" - "%s Swap:~3 %8lu ~2total,~3 %8lu ~2used,~3 %8lu ~2free,~3 %8lu ~2cached~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 %9.9s~2total,~3 %9.9s~2used,~3 %9.9s~2free,~3 %9.9s~2cached~3\n"); Uniq_nlstab[INSP_hdrsels_fmt] = _("" "Inspection~2 Pause at: pid ~1%d~6 running ~1%s~6 as user ~1%s~6\n" diff --git a/top/top_nls.h b/top/top_nls.h index 639e6f54..e1488b42 100644 --- a/top/top_nls.h +++ b/top/top_nls.h @@ -62,25 +62,25 @@ extern const char *Uniq_nlstab[]; * from any text also containiing c-format specifiers. */ enum norm_nls { - AMT_kilobyte_txt, AMT_megabyte_txt, AMT_gigabyte_txt, BAD_delayint_fmt, - BAD_integers_txt, BAD_max_task_txt, BAD_mon_pids_fmt, BAD_niterate_fmt, - BAD_numfloat_txt, BAD_signalid_txt, BAD_username_txt, BAD_widtharg_fmt, - CHOOSE_group_txt, COLORS_nomap_txt, DELAY_badarg_txt, DELAY_change_fmt, - DELAY_secure_txt, DISABLED_cmd_txt, DISABLED_win_fmt, EXIT_signals_fmt, - FAIL_alloc_c_txt, FAIL_alloc_r_txt, FAIL_openlib_fmt, FAIL_rc_open_fmt, - FAIL_re_nice_fmt, FAIL_sigmask_fmt, FAIL_signals_fmt, FAIL_sigstop_fmt, - FAIL_statget_txt, FAIL_statopn_fmt, FAIL_tty_get_txt, FAIL_tty_mod_fmt, - FAIL_tty_raw_fmt, FAIL_widecpu_txt, FAIL_widepid_txt, FIND_no_find_fmt, - FIND_no_next_txt, FOREST_modes_fmt, FOREST_views_txt, GET_find_str_txt, - GET_max_task_fmt, GET_nice_num_fmt, GET_pid2kill_fmt, GET_pid2nice_fmt, - GET_sigs_num_fmt, GET_user_ids_txt, HELP_cmdline_fmt, HILIGHT_cant_txt, - IRIX_curmode_fmt, LIMIT_exceed_fmt, MISSING_args_fmt, NAME_windows_fmt, - NOT_onsecure_txt, NOT_smp_cpus_txt, OFF_one_word_txt, ON_word_only_txt, - RC_bad_entry_fmt, RC_bad_files_fmt, SCROLL_coord_fmt, SELECT_clash_txt, - THREADS_show_fmt, TIME_accumed_fmt, UNKNOWN_cmds_txt, UNKNOWN_opts_fmt, - USAGE_abbrev_txt, WORD_allcpus_txt, WORD_another_txt, WORD_eachcpu_fmt, - WORD_process_txt, WORD_threads_txt, WRITE_rcfile_fmt, WRONG_switch_fmt, - XTRA_fixwide_fmt, XTRA_sortopt_fmt, XTRA_warncfg_txt, + AMT_kilobyte_txt, AMT_megabyte_txt, AMT_gigabyte_txt, AMT_terabyte_txt, + BAD_delayint_fmt, BAD_integers_txt, BAD_max_task_txt, BAD_mon_pids_fmt, + BAD_niterate_fmt, BAD_numfloat_txt, BAD_signalid_txt, BAD_username_txt, + BAD_widtharg_fmt, CHOOSE_group_txt, COLORS_nomap_txt, DELAY_badarg_txt, + DELAY_change_fmt, DELAY_secure_txt, DISABLED_cmd_txt, DISABLED_win_fmt, + EXIT_signals_fmt, FAIL_alloc_c_txt, FAIL_alloc_r_txt, FAIL_openlib_fmt, + FAIL_rc_open_fmt, FAIL_re_nice_fmt, FAIL_sigmask_fmt, FAIL_signals_fmt, + FAIL_sigstop_fmt, FAIL_statget_txt, FAIL_statopn_fmt, FAIL_tty_get_txt, + FAIL_tty_mod_fmt, FAIL_tty_raw_fmt, FAIL_widecpu_txt, FAIL_widepid_txt, + FIND_no_find_fmt, FIND_no_next_txt, FOREST_modes_fmt, FOREST_views_txt, + GET_find_str_txt, GET_max_task_fmt, GET_nice_num_fmt, GET_pid2kill_fmt, + GET_pid2nice_fmt, GET_sigs_num_fmt, GET_user_ids_txt, HELP_cmdline_fmt, + HILIGHT_cant_txt, IRIX_curmode_fmt, LIMIT_exceed_fmt, MISSING_args_fmt, + NAME_windows_fmt, NOT_onsecure_txt, NOT_smp_cpus_txt, OFF_one_word_txt, + ON_word_only_txt, RC_bad_entry_fmt, RC_bad_files_fmt, SCROLL_coord_fmt, + SELECT_clash_txt, THREADS_show_fmt, TIME_accumed_fmt, UNKNOWN_cmds_txt, + UNKNOWN_opts_fmt, USAGE_abbrev_txt, WORD_allcpus_txt, WORD_another_txt, + WORD_eachcpu_fmt, WORD_process_txt, WORD_threads_txt, WRITE_rcfile_fmt, + WRONG_switch_fmt, XTRA_fixwide_fmt, XTRA_sortopt_fmt, XTRA_warncfg_txt, #ifndef INSP_OFFDEMO YINSP_demo01_txt, YINSP_demo02_txt, YINSP_demo03_txt, YINSP_deqfmt_txt, YINSP_deqtyp_txt, YINSP_dstory_txt,