top: exploit the new library API for memory statistics
This commit represents the pioneering attempt at using the concept of 'chained' library requests in an effort to reduce function call overhead. It required exposing no more implementation details than were already shown through the individual calls, yet is satisfied in one. It is just such an approach that will prove invaluable when it comes time to access individual /proc/##/data. Programs could 'chain' only those 'results' structures representing their current view independent of all the fields any such programs might be prepared to display. Thus the standard 'read', which wouldn't apply to task level data very well (or efficiently), can now become a 'read_chain' whereby the former PROC_FILL flags need can be satisfied & yield the minimum open/close calls. Signed-off-by: Jim Warner <james.warner@comcast.net>
This commit is contained in:
parent
a05084f381
commit
c3fd7473c5
55
top/top.c
55
top/top.c
@ -50,6 +50,7 @@
|
|||||||
#include "../include/nls.h"
|
#include "../include/nls.h"
|
||||||
|
|
||||||
#include "../proc/devname.h"
|
#include "../proc/devname.h"
|
||||||
|
#include "../proc/meminfo.h"
|
||||||
#include "../proc/procps.h"
|
#include "../proc/procps.h"
|
||||||
#include "../proc/readproc.h"
|
#include "../proc/readproc.h"
|
||||||
#include "../proc/sig.h"
|
#include "../proc/sig.h"
|
||||||
@ -244,6 +245,26 @@ static float Graph_adj; // bars/blocks scaling factor
|
|||||||
static int Graph_len; // scaled length (<= GRAPH_actual)
|
static int Graph_len; // scaled length (<= GRAPH_actual)
|
||||||
static const char Graph_blks[] = " ";
|
static const char Graph_blks[] = " ";
|
||||||
static const char Graph_bars[] = "||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||";
|
static const char Graph_bars[] = "||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||";
|
||||||
|
|
||||||
|
/* Support for the new library API -- acquired (if necessary)
|
||||||
|
at program startup and referenced throughout our lifetime */
|
||||||
|
static struct procps_meminfo *mem_info;
|
||||||
|
static struct meminfo_result mem_chain[] = {
|
||||||
|
{ PROCPS_MEM_FREE, 0, &mem_chain[1] },
|
||||||
|
{ PROCPS_MEM_USED, 0, &mem_chain[2] },
|
||||||
|
{ PROCPS_MEM_TOTAL, 0, &mem_chain[3] },
|
||||||
|
{ PROCPS_MEM_CACHED, 0, &mem_chain[4] },
|
||||||
|
{ PROCPS_MEM_BUFFERS, 0, &mem_chain[5] },
|
||||||
|
{ PROCPS_MEM_AVAILABLE, 0, &mem_chain[6] },
|
||||||
|
{ PROCPS_SWAP_TOTAL, 0, &mem_chain[7] },
|
||||||
|
{ PROCPS_SWAP_FREE, 0, &mem_chain[8] },
|
||||||
|
{ PROCPS_SWAP_USED, 0, NULL }
|
||||||
|
};
|
||||||
|
enum mem_enums {
|
||||||
|
mem_FREE, mem_USED, mem_TOTAL, mem_CACHE, mem_BUFFS,
|
||||||
|
mem_AVAIL, swp_TOTAL, swp_FREE, swp_USED
|
||||||
|
};
|
||||||
|
#define MEM_VAL(e) mem_chain[e].result
|
||||||
|
|
||||||
/*###### Sort callbacks ################################################*/
|
/*###### Sort callbacks ################################################*/
|
||||||
|
|
||||||
@ -2697,7 +2718,9 @@ static void sysinfo_refresh (int forced) {
|
|||||||
|
|
||||||
/*** hotplug_acclimated ***/
|
/*** hotplug_acclimated ***/
|
||||||
if (3 <= cur_secs - mem_secs) {
|
if (3 <= cur_secs - mem_secs) {
|
||||||
meminfo();
|
if (procps_meminfo_read(mem_info) < 0)
|
||||||
|
error_exit(N_txt(LIB_errormem_txt));
|
||||||
|
procps_meminfo_get_chain(mem_info, mem_chain);
|
||||||
mem_secs = cur_secs;
|
mem_secs = cur_secs;
|
||||||
}
|
}
|
||||||
#ifndef PRETEND8CPUS
|
#ifndef PRETEND8CPUS
|
||||||
@ -3293,6 +3316,10 @@ static void before (char *me) {
|
|||||||
i = page_bytes; // from sysinfo.c, at lib init
|
i = page_bytes; // from sysinfo.c, at lib init
|
||||||
while(i > 1024) { i >>= 1; Pg2K_shft++; }
|
while(i > 1024) { i >>= 1; Pg2K_shft++; }
|
||||||
|
|
||||||
|
// prepare for new library API ...
|
||||||
|
if (procps_meminfo_new(&mem_info) < 0)
|
||||||
|
error_exit(N_txt(LIB_errormem_txt));
|
||||||
|
|
||||||
#ifndef OFF_HST_HASH
|
#ifndef OFF_HST_HASH
|
||||||
// prep for HST_t's put/get hashing optimizations
|
// prep for HST_t's put/get hashing optimizations
|
||||||
for (i = 0; i < HHASH_SIZ; i++) HHash_nul[i] = -1;
|
for (i = 0; i < HHASH_SIZ; i++) HHash_nul[i] = -1;
|
||||||
@ -5207,8 +5234,7 @@ numa_nope:
|
|||||||
if (isROOM(View_MEMORY, 2)) {
|
if (isROOM(View_MEMORY, 2)) {
|
||||||
#define bfT(n) buftab[n].buf
|
#define bfT(n) buftab[n].buf
|
||||||
#define scT(e) scaletab[Rc.summ_mscale]. e
|
#define scT(e) scaletab[Rc.summ_mscale]. e
|
||||||
#define mkM(x) (float)kb_main_ ## x / scT(div)
|
#define mkM(x) (float) 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] = '+'; }
|
#define prT(b,z) { if (9 < snprintf(b, 10, scT(fmts), z)) b[8] = '+'; }
|
||||||
static struct {
|
static struct {
|
||||||
float div;
|
float div;
|
||||||
@ -5246,13 +5272,13 @@ numa_nope:
|
|||||||
};
|
};
|
||||||
char used[SMLBUFSIZ], util[SMLBUFSIZ], dual[MEDBUFSIZ];
|
char used[SMLBUFSIZ], util[SMLBUFSIZ], dual[MEDBUFSIZ];
|
||||||
int ix = w->rc.graph_mems - 1;
|
int ix = w->rc.graph_mems - 1;
|
||||||
float pct_used = (float)kb_main_used * (100.0 / (float)kb_main_total),
|
float pct_used = (float)MEM_VAL(mem_USED) * (100.0 / (float)MEM_VAL(mem_TOTAL)),
|
||||||
#ifdef MEMGRAPH_OLD
|
#ifdef MEMGRAPH_OLD
|
||||||
pct_misc = (float)(kb_main_buffers + kb_main_cached) * (100.0 / (float)kb_main_total),
|
pct_misc = (float)(MEM_VAL(mem_BUFFS) + MEM_VAL(mem_CACHE)) * (100.0 / (float)MEM_VAL(mem_TOTAL)),
|
||||||
#else
|
#else
|
||||||
pct_misc = (float)(kb_main_total - kb_main_available - kb_main_used) * (100.0 / (float)kb_main_total),
|
pct_misc = (float)(MEM_VAL(mem_TOTAL) - MEM_VAL(mem_AVAIL) - MEM_VAL(mem_USED)) * (100.0 / (float)MEM_VAL(mem_TOTAL)),
|
||||||
#endif
|
#endif
|
||||||
pct_swap = kb_swap_total ? (float)kb_swap_used * (100.0 / (float)kb_swap_total) : 0;
|
pct_swap = MEM_VAL(swp_TOTAL) ? (float)MEM_VAL(swp_USED) * (100.0 / (float)MEM_VAL(swp_TOTAL)) : 0;
|
||||||
#ifndef QUICK_GRAPHS
|
#ifndef QUICK_GRAPHS
|
||||||
int num_used = (int)((pct_used * Graph_adj) + .5),
|
int num_used = (int)((pct_used * Graph_adj) + .5),
|
||||||
num_misc = (int)((pct_misc * Graph_adj) + .5);
|
num_misc = (int)((pct_misc * Graph_adj) + .5);
|
||||||
@ -5265,16 +5291,16 @@ numa_nope:
|
|||||||
#endif
|
#endif
|
||||||
snprintf(dual, sizeof(dual), "%s%s", used, util);
|
snprintf(dual, sizeof(dual), "%s%s", used, util);
|
||||||
snprintf(util, sizeof(util), gtab[ix].swap, (int)((pct_swap * Graph_adj) + .5), gtab[ix].type);
|
snprintf(util, sizeof(util), gtab[ix].swap, (int)((pct_swap * Graph_adj) + .5), gtab[ix].type);
|
||||||
prT(bfT(0), mkM(total)); prT(bfT(1), mkS(total));
|
prT(bfT(0), mkM(MEM_VAL(mem_TOTAL))); prT(bfT(1), mkM(MEM_VAL(swp_TOTAL)));
|
||||||
show_special(0, fmtmk( "%s %s:~3%#5.1f~2/%-9.9s~3[~1%-*s]~1\n%s %s:~3%#5.1f~2/%-9.9s~3[~1%-*s]~1\n"
|
show_special(0, fmtmk( "%s %s:~3%#5.1f~2/%-9.9s~3[~1%-*s]~1\n%s %s:~3%#5.1f~2/%-9.9s~3[~1%-*s]~1\n"
|
||||||
, scT(label), N_txt(WORD_abv_mem_txt), pct_used + pct_misc, bfT(0), Graph_len +4, dual
|
, scT(label), N_txt(WORD_abv_mem_txt), pct_used + pct_misc, bfT(0), Graph_len +4, dual
|
||||||
, scT(label), N_txt(WORD_abv_swp_txt), pct_swap, bfT(1), Graph_len +2, util));
|
, scT(label), N_txt(WORD_abv_swp_txt), pct_swap, bfT(1), Graph_len +2, util));
|
||||||
} else {
|
} else {
|
||||||
unsigned long kb_main_my_misc = kb_main_buffers + kb_main_cached;
|
unsigned long my_misc = MEM_VAL(mem_BUFFS) + MEM_VAL(mem_CACHE);
|
||||||
prT(bfT(0), mkM(total)); prT(bfT(1), mkM(free));
|
prT(bfT(0), mkM(MEM_VAL(mem_TOTAL))); prT(bfT(1), mkM(MEM_VAL(mem_FREE)));
|
||||||
prT(bfT(2), mkM(used)); prT(bfT(3), mkM(my_misc));
|
prT(bfT(2), mkM(MEM_VAL(mem_USED))); prT(bfT(3), mkM(my_misc));
|
||||||
prT(bfT(4), mkS(total)); prT(bfT(5), mkS(free));
|
prT(bfT(4), mkM(MEM_VAL(swp_TOTAL))); prT(bfT(5), mkM(MEM_VAL(swp_FREE)));
|
||||||
prT(bfT(6), mkS(used)); prT(bfT(7), mkM(available));
|
prT(bfT(6), mkM(MEM_VAL(swp_USED))); prT(bfT(7), mkM(MEM_VAL(mem_AVAIL)));
|
||||||
show_special(0, fmtmk(N_unq(MEMORY_lines_fmt)
|
show_special(0, fmtmk(N_unq(MEMORY_lines_fmt)
|
||||||
, scT(label), N_txt(WORD_abv_mem_txt), bfT(0), bfT(1), bfT(2), bfT(3)
|
, scT(label), N_txt(WORD_abv_mem_txt), bfT(0), bfT(1), bfT(2), bfT(3)
|
||||||
, scT(label), N_txt(WORD_abv_swp_txt), bfT(4), bfT(5), bfT(6), bfT(7)
|
, scT(label), N_txt(WORD_abv_swp_txt), bfT(4), bfT(5), bfT(6), bfT(7)
|
||||||
@ -5284,7 +5310,6 @@ numa_nope:
|
|||||||
#undef bfT
|
#undef bfT
|
||||||
#undef scT
|
#undef scT
|
||||||
#undef mkM
|
#undef mkM
|
||||||
#undef mkS
|
|
||||||
#undef prT
|
#undef prT
|
||||||
} // end: View_MEMORY
|
} // end: View_MEMORY
|
||||||
|
|
||||||
@ -5390,7 +5415,7 @@ static const char *task_show (const WIN_t *q, const proc_t *p) {
|
|||||||
cp = make_str(p->lxcname, W, Js, EU_LXC);
|
cp = make_str(p->lxcname, W, Js, EU_LXC);
|
||||||
break;
|
break;
|
||||||
case EU_MEM:
|
case EU_MEM:
|
||||||
cp = scale_pcnt((float)pages2K(p->resident) * 100 / kb_main_total, W, Jn);
|
cp = scale_pcnt((float)pages2K(p->resident) * 100 / MEM_VAL(mem_TOTAL), W, Jn);
|
||||||
break;
|
break;
|
||||||
case EU_NCE:
|
case EU_NCE:
|
||||||
cp = make_num(p->nice, W, Jn, AUTOX_NO);
|
cp = make_num(p->nice, W, Jn, AUTOX_NO);
|
||||||
|
@ -472,6 +472,7 @@ static void build_norm_nlstab (void) {
|
|||||||
. padding with extra spaces as necessary */
|
. padding with extra spaces as necessary */
|
||||||
Norm_nlstab[WORD_abv_mem_txt] = _("Mem ");
|
Norm_nlstab[WORD_abv_mem_txt] = _("Mem ");
|
||||||
Norm_nlstab[WORD_abv_swp_txt] = _("Swap");
|
Norm_nlstab[WORD_abv_swp_txt] = _("Swap");
|
||||||
|
Norm_nlstab[LIB_errormem_txt] = _("library failed memory stats");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -74,17 +74,17 @@ enum norm_nls {
|
|||||||
FIND_no_next_txt, FOREST_modes_fmt, FOREST_views_txt, GET_find_str_txt,
|
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_max_task_fmt, GET_nice_num_fmt, GET_pid2kill_fmt, GET_pid2nice_fmt,
|
||||||
GET_sigs_num_fmt, GET_user_ids_txt, HELP_cmdline_fmt, IRIX_curmode_fmt,
|
GET_sigs_num_fmt, GET_user_ids_txt, HELP_cmdline_fmt, IRIX_curmode_fmt,
|
||||||
LIMIT_exceed_fmt, MISSING_args_fmt, NAME_windows_fmt, NOT_onsecure_txt,
|
LIB_errormem_txt, LIMIT_exceed_fmt, MISSING_args_fmt, NAME_windows_fmt,
|
||||||
NOT_smp_cpus_txt, NUMA_nodebad_txt, NUMA_nodeget_fmt, NUMA_nodenam_fmt,
|
NOT_onsecure_txt, NOT_smp_cpus_txt, NUMA_nodebad_txt, NUMA_nodeget_fmt,
|
||||||
NUMA_nodenot_txt, OFF_one_word_txt, ON_word_only_txt, OSEL_casenot_txt,
|
NUMA_nodenam_fmt, NUMA_nodenot_txt, OFF_one_word_txt, ON_word_only_txt,
|
||||||
OSEL_caseyes_txt, OSEL_errdelm_fmt, OSEL_errdups_txt, OSEL_errvalu_fmt,
|
OSEL_casenot_txt, OSEL_caseyes_txt, OSEL_errdelm_fmt, OSEL_errdups_txt,
|
||||||
OSEL_prompts_fmt, OSEL_statlin_fmt, RC_bad_entry_fmt, RC_bad_files_fmt,
|
OSEL_errvalu_fmt, OSEL_prompts_fmt, OSEL_statlin_fmt, RC_bad_entry_fmt,
|
||||||
SCROLL_coord_fmt, SELECT_clash_txt, THREADS_show_fmt, TIME_accumed_fmt,
|
RC_bad_files_fmt, SCROLL_coord_fmt, SELECT_clash_txt, THREADS_show_fmt,
|
||||||
UNKNOWN_cmds_txt, UNKNOWN_opts_fmt, USAGE_abbrev_txt, WORD_abv_mem_txt,
|
TIME_accumed_fmt, UNKNOWN_cmds_txt, UNKNOWN_opts_fmt, USAGE_abbrev_txt,
|
||||||
WORD_abv_swp_txt, WORD_allcpus_txt, WORD_another_txt, WORD_eachcpu_fmt,
|
WORD_abv_mem_txt, WORD_abv_swp_txt, WORD_allcpus_txt, WORD_another_txt,
|
||||||
WORD_exclude_txt, WORD_include_txt, WORD_noneone_txt, WORD_process_txt,
|
WORD_eachcpu_fmt, WORD_exclude_txt, WORD_include_txt, WORD_noneone_txt,
|
||||||
WORD_threads_txt, WRITE_rcfile_fmt, WRONG_switch_fmt, XTRA_badflds_fmt,
|
WORD_process_txt, WORD_threads_txt, WRITE_rcfile_fmt, WRONG_switch_fmt,
|
||||||
XTRA_fixwide_fmt, XTRA_warncfg_txt, XTRA_winsize_txt,
|
XTRA_badflds_fmt, XTRA_fixwide_fmt, XTRA_warncfg_txt, XTRA_winsize_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,
|
||||||
|
Loading…
Reference in New Issue
Block a user