top: adapted this program to those changes, <STAT> api

This guy is the real beneficiary of the new <stat> API
especially when it comes to the DELTA items which were
really the only values of interest (beyond some id's).

Signed-off-by: Jim Warner <james.warner@comcast.net>
This commit is contained in:
Jim Warner 2016-05-06 00:00:00 -05:00 committed by Craig Small
parent abc71a46ad
commit 6c2b95872f
2 changed files with 87 additions and 195 deletions

269
top/top.c
View File

@ -20,9 +20,6 @@
#include <ctype.h> #include <ctype.h>
#include <curses.h> #include <curses.h>
#ifndef NUMA_DISABLE
#include <dlfcn.h>
#endif
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <float.h> #include <float.h>
@ -84,7 +81,6 @@ static int Rc_questions;
/* SMP, Irix/Solaris mode, Linux 2.5.xx support (and beyond) */ /* SMP, Irix/Solaris mode, Linux 2.5.xx support (and beyond) */
static long Hertz; static long Hertz;
static int Cpu_cnt; static int Cpu_cnt;
static int Cpu_faux_cnt;
static float Cpu_pmax; static float Cpu_pmax;
static const char *Cpu_States_fmts; static const char *Cpu_States_fmts;
@ -183,27 +179,12 @@ static int Autox_array [EU_MAXPFLGS],
static char Scaled_sfxtab[] = { 'k', 'm', 'g', 't', 'p', 'e', 0 }; static char Scaled_sfxtab[] = { 'k', 'm', 'g', 't', 'p', 'e', 0 };
#endif #endif
/* Support for NUMA Node display, node expansion/targeting and /* Support for NUMA Node display plus node expansion and targeting */
run-time dynamic linking with libnuma.so treated as a plugin */
#ifndef OFF_STDERROR #ifndef OFF_STDERROR
static int Stderr_save = -1; static int Stderr_save = -1;
#endif #endif
static int Numa_node_tot; static int Numa_node_tot;
static int Numa_node_sel = -1; static int Numa_node_sel = -1;
#ifndef NUMA_DISABLE
static void *Libnuma_handle;
#if defined(PRETEND_NUMA) || defined(PRETEND8CPUS)
static int Numa_max_node(void) { return 3; }
#ifndef OFF_NUMASKIP
static int Numa_node_of_cpu(int num) { return (1 == (num % 4)) ? 0 : (num % 4); }
#else
static int Numa_node_of_cpu(int num) { return (num % 4); }
#endif
#else
static int (*Numa_max_node)(void);
static int (*Numa_node_of_cpu)(int num);
#endif
#endif
/* Support for Graphing of the View_STATES ('t') and View_MEMORY ('m') /* Support for Graphing of the View_STATES ('t') and View_MEMORY ('m')
commands -- which are now both 4-way toggles */ commands -- which are now both 4-way toggles */
@ -216,9 +197,8 @@ static const char Graph_blks[] = "
static const char Graph_bars[] = "||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||"; static const char Graph_bars[] = "||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||";
/* Support for the new library API -- acquired (if necessary) /* Support for the new library API -- acquired (if necessary)
at program startup and referenced throughout our lifetime. at program startup and referenced throughout our lifetime. */
( appearing in order of newlib development availability. )*/ // --- <proc/meminfo.h> -----------------------------------------------
// ---------------------------------------------- <proc/meminfo.h>
static struct procps_meminfo *Mem_ctx; static struct procps_meminfo *Mem_ctx;
static struct meminfo_stack *Mem_stack; static struct meminfo_stack *Mem_stack;
static enum meminfo_item Mem_items[] = { static enum meminfo_item Mem_items[] = {
@ -226,16 +206,12 @@ static enum meminfo_item Mem_items[] = {
PROCPS_MEM_CACHED, PROCPS_MEM_BUFFERS, PROCPS_MEM_AVAILABLE, PROCPS_MEM_CACHED, PROCPS_MEM_BUFFERS, PROCPS_MEM_AVAILABLE,
PROCPS_SWAP_TOTAL, PROCPS_SWAP_FREE, PROCPS_SWAP_USED, PROCPS_SWAP_TOTAL, PROCPS_SWAP_FREE, PROCPS_SWAP_USED,
PROCPS_MEM_stack_end }; PROCPS_MEM_stack_end };
enum Rel_items { enum Rel_memitems {
mem_FREE, mem_USED, mem_TOTAL, mem_CACHE, mem_BUFFS, mem_FREE, mem_USED, mem_TOTAL, mem_CACHE, mem_BUFFS,
mem_AVAIL, swp_TOTAL, swp_FREE, swp_USED mem_AVAIL, swp_TOTAL, swp_FREE, swp_USED };
};
// mem stack results extractor macro, where e=rel enum // mem stack results extractor macro, where e=rel enum
#define MEM_VAL(e) Mem_stack->head[e].result.ul_int #define MEM_VAL(e) Mem_stack->head[e].result.ul_int
// ------------------------------------------------- <proc/stat.h> // --- <proc/pids.h> --------------------------------------------------
static struct procps_stat *Cpu_ctx;
static struct procps_jiffs_hist *Cpu_jiffs;
// ------------------------------------------------- <proc/pids.h>
static struct procps_pidsinfo *Pids_ctx; static struct procps_pidsinfo *Pids_ctx;
static int Pids_itms_cur; // 'current' max (<= Fieldstab) static int Pids_itms_cur; // 'current' max (<= Fieldstab)
static enum pids_item *Pids_itms; // allocated as MAXTBL(Fieldstab) static enum pids_item *Pids_itms; // allocated as MAXTBL(Fieldstab)
@ -245,6 +221,22 @@ static struct pids_reap *Pids_reap; // for reap or select
// ( we'll exploit that <proc/pids.h> provided macro as much as possible ) // ( we'll exploit that <proc/pids.h> provided macro as much as possible )
// ( but many functions use their own unique tailored version for access ) // ( but many functions use their own unique tailored version for access )
#define PID_VAL(e,t,s) PROCPS_PIDS_VAL(Fieldstab[ e ].erel, t, s) #define PID_VAL(e,t,s) PROCPS_PIDS_VAL(Fieldstab[ e ].erel, t, s)
// --- <proc/stat.h> --------------------------------------------------
static struct procps_statinfo *Stat_ctx;
static struct stat_reaped *Stat_reap;
static enum stat_item Stat_items[] = {
PROCPS_STAT_TIC_ID, PROCPS_STAT_TIC_NUMA_NODE,
PROCPS_STAT_TIC_DELTA_USER, PROCPS_STAT_TIC_DELTA_SYSTEM,
PROCPS_STAT_TIC_DELTA_NICE, PROCPS_STAT_TIC_DELTA_IDLE,
PROCPS_STAT_TIC_DELTA_IOWAIT, PROCPS_STAT_TIC_DELTA_IRQ,
PROCPS_STAT_TIC_DELTA_SOFTIRQ, PROCPS_STAT_TIC_DELTA_STOLEN };
enum Rel_statitems {
stat_ID, stat_NU, stat_US, stat_SY, stat_NI,
stat_IL, stat_IO, stat_IR, stat_SI, stat_ST };
// cpu/node stack results extractor macro, where e=rel enum, t=type, x=index
#define SUM_VAL(e,t) PROCPS_STAT_VAL(e, t, Stat_reap->summary)
#define CPU_VAL(e,t,x) PROCPS_STAT_VAL(e, t, Stat_reap->cpus->stacks[x])
#define NOD_VAL(e,t,x) PROCPS_STAT_VAL(e, t, Stat_reap->nodes->stacks[x])
/*###### Tiny useful routine(s) ########################################*/ /*###### Tiny useful routine(s) ########################################*/
@ -330,8 +322,7 @@ static void bye_bye (const char *str) {
"\n\tProgram" "\n\tProgram"
"\n\t %s" "\n\t %s"
"\n\t Hertz = %u (%u bytes, %u-bit time)" "\n\t Hertz = %u (%u bytes, %u-bit time)"
"\n\t Cpu_faux_cnt = %d, Cpu_cnt = %d" "\n\t Stat_reap->cpus->total = %d, Stat_reap->nodes->total = %d"
"\n\t sizeof(procps_jiffs) = %u, sizeof(procps_jiffs_hist) = %u"
"\n\t sizeof(struct pids_result) = %u, sizeof(struct pids_stack) = %u" "\n\t sizeof(struct pids_result) = %u, sizeof(struct pids_stack) = %u"
"\n\t SCREENMAX = %u, ROWMINSIZ = %u, ROWMAXSIZ = %u" "\n\t SCREENMAX = %u, ROWMINSIZ = %u, ROWMAXSIZ = %u"
"\n\t PACKAGE = '%s', LOCALEDIR = '%s'" "\n\t PACKAGE = '%s', LOCALEDIR = '%s'"
@ -359,8 +350,7 @@ static void bye_bye (const char *str) {
, __func__ , __func__
, PACKAGE_STRING , PACKAGE_STRING
, (unsigned)Hertz, (unsigned)sizeof(Hertz), (unsigned)sizeof(Hertz) * 8 , (unsigned)Hertz, (unsigned)sizeof(Hertz), (unsigned)sizeof(Hertz) * 8
, Cpu_faux_cnt, (int)Cpu_cnt , Stat_reap->cpus->total, Stat_reap->nodes->total
, (unsigned)sizeof(struct procps_jiffs), (unsigned)sizeof(struct procps_jiffs_hist)
, (unsigned)sizeof(struct pids_result), (unsigned)sizeof(*p) , (unsigned)sizeof(struct pids_result), (unsigned)sizeof(*p)
, (unsigned)SCREENMAX, (unsigned)ROWMINSIZ, (unsigned)ROWMAXSIZ , (unsigned)SCREENMAX, (unsigned)ROWMINSIZ, (unsigned)ROWMAXSIZ
, PACKAGE, LOCALEDIR , PACKAGE, LOCALEDIR
@ -388,12 +378,10 @@ static void bye_bye (const char *str) {
} }
#endif // end: ATEOJ_RPTSTD #endif // end: ATEOJ_RPTSTD
procps_stat_unref(&Cpu_ctx);
procps_meminfo_unref(&Mem_ctx); procps_meminfo_unref(&Mem_ctx);
procps_pids_unref(&Pids_ctx); procps_pids_unref(&Pids_ctx);
#ifndef NUMA_DISABLE procps_stat_unref(&Stat_ctx);
if (Libnuma_handle) dlclose(Libnuma_handle);
#endif
if (str) { if (str) {
fputs(str, stderr); fputs(str, stderr);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -2169,84 +2157,28 @@ static void zap_fieldstab (void) {
/*###### Library Interface #############################################*/ /*###### Library Interface #############################################*/
/* /*
* We'll track all cpu data in the jiffs array which is organized * This guy's responsible for interfacing with the library <stat> API
* as follows: * and reaping all cpu or numa node tics.
* Cpu_jiffs[0] - Cpu_jiffs[n] == tics for each separate cpu * ( his task is now embarassingly small under the new api ) */
* Cpu_jiffs[sumSLOT] == tics from /proc/stat line #1
* [ and beyond sumSLOT == tics for each cpu NUMA node ] */
static void cpus_refresh (void) { static void cpus_refresh (void) {
#define sumSLOT ( Cpu_cnt ) enum stat_reap_type which;
#define totSLOT ( 1 + Cpu_cnt + Numa_node_tot )
static int sav_slot = -1; which = STAT_REAP_CPUS_ONLY;
#ifndef NUMA_DISABLE #ifndef NUMA_DISABLE
int i; if (CHKw(Curwin, View_CPUNOD))
int node; which = STAT_REAP_CPUS_AND_NODES;
#endif #endif
Stat_reap = procps_stat_reap(Stat_ctx, which, Stat_items, MAXTBL(Stat_items));
/*** hotplug_acclimated ***/ if (!Stat_reap)
if (sav_slot != sumSLOT) {
sav_slot = sumSLOT;
zap_fieldstab();
if (Cpu_jiffs) { free(Cpu_jiffs); Cpu_jiffs = NULL; }
}
if (!Cpu_jiffs) {
/* note: we allocate one more CPU_t via totSLOT than 'cpus' so that a
slot can hold tics representing the /proc/stat cpu summary */
Cpu_jiffs = alloc_c(totSLOT * sizeof(struct procps_jiffs_hist));
}
// 1st, retrieve all of the actual cpu jiffs
// 'hist_fill' also implies 'read', saving us one more call
Cpu_faux_cnt = procps_stat_jiffs_hist_fill(Cpu_ctx, Cpu_jiffs, sumSLOT);
if (Cpu_faux_cnt < 0)
error_exit(fmtmk(N_fmt(LIB_errorcpu_fmt),__LINE__)); error_exit(fmtmk(N_fmt(LIB_errorcpu_fmt),__LINE__));
// 2nd, retrieve just the cpu summary jiffs // adapt to changes in total numa nodes (assuming it's even possible)
if (procps_stat_jiffs_hist_get(Cpu_ctx, &Cpu_jiffs[sumSLOT], -1) < 0) if (Stat_reap->nodes->total && Stat_reap->nodes->total != Numa_node_tot) {
error_exit(fmtmk(N_fmt(LIB_errorcpu_fmt),__LINE__)); Numa_node_tot = Stat_reap->nodes->total;
Numa_node_sel = -1;
#ifndef NUMA_DISABLE
/* henceforth, with just a little more arithmetic we can avoid
maintaining *any* node stats unless they're actually needed */
if (CHKw(Curwin, View_CPUNOD)) {
struct procps_jiffs_hist *sum_ptr = &Cpu_jiffs[sumSLOT];
// forget all of the prior node statistics
memset(sum_ptr + 1, 0, Numa_node_tot * sizeof(struct procps_jiffs_hist));
// spin thru each cpu and value the jiffs for it's numa node
for (i = 0; i < sumSLOT; i++) {
struct procps_jiffs_hist *cpu_ptr = &Cpu_jiffs[i];
if (CHKw(Curwin, View_CPUNOD)
&& Numa_node_tot
&& -1 < (node = Numa_node_of_cpu(cpu_ptr->id))) {
struct procps_jiffs_hist *nod_ptr = sum_ptr + 1 + node;
nod_ptr->new.user += cpu_ptr->new.user; nod_ptr->old.user += cpu_ptr->old.user;
nod_ptr->new.nice += cpu_ptr->new.nice; nod_ptr->old.nice += cpu_ptr->old.nice;
nod_ptr->new.system += cpu_ptr->new.system; nod_ptr->old.system += cpu_ptr->old.system;
nod_ptr->new.idle += cpu_ptr->new.idle; nod_ptr->old.idle += cpu_ptr->old.idle;
nod_ptr->new.iowait += cpu_ptr->new.iowait; nod_ptr->old.iowait += cpu_ptr->old.iowait;
nod_ptr->new.irq += cpu_ptr->new.irq; nod_ptr->old.irq += cpu_ptr->old.irq;
nod_ptr->new.sirq += cpu_ptr->new.sirq; nod_ptr->old.sirq += cpu_ptr->old.sirq;
nod_ptr->new.stolen += cpu_ptr->new.stolen; nod_ptr->old.stolen += cpu_ptr->old.stolen;
#ifndef OFF_NUMASKIP
nod_ptr->id = -1;
#endif
/* note: the above call to Numa_node_of_cpu will produce a modest
* memory leak summarized as:
* ==1234== LEAK SUMMARY:
* ==1234== definitely lost: 512 bytes in 1 blocks
* ==1234== indirectly lost: 48 bytes in 2 blocks
* ==1234== ...
* it does *not* happen when PRETEND_NUMA has been defined
* [ thanks very much libnuma, for all the pain you've caused us ]
*/
} }
} if (Stat_reap->cpus->total && Stat_reap->cpus->total != Cpu_cnt)
} Cpu_cnt = Stat_reap->cpus->total;
#endif
return; return;
#undef sumSLOT
#undef totSLOT
} // end: cpus_refresh } // end: cpus_refresh
@ -2257,7 +2189,7 @@ static void cpus_refresh (void) {
static void procs_refresh (void) { static void procs_refresh (void) {
#define nALIGN(n,m) (((n + m - 1) / m) * m) // unconditionally align #define nALIGN(n,m) (((n + m - 1) / m) * m) // unconditionally align
#define nALGN2(n,m) ((n + m - 1) & ~(m - 1)) // with power of 2 align #define nALGN2(n,m) ((n + m - 1) & ~(m - 1)) // with power of 2 align
#define n_reap Pids_reap->counts.total // maintained by newlib #define n_reap Pids_reap->counts.total
static double uptime_sav; static double uptime_sav;
static int n_alloc = -1; // size of windows stacks arrays static int n_alloc = -1; // size of windows stacks arrays
double uptime_cur; double uptime_cur;
@ -2313,17 +2245,6 @@ static void sysinfo_refresh (int forced) {
error_exit(fmtmk(N_fmt(LIB_errormem_fmt),__LINE__)); error_exit(fmtmk(N_fmt(LIB_errormem_fmt),__LINE__));
mem_secs = cur_secs; mem_secs = cur_secs;
} }
#ifndef PRETEND8CPUS
/*** hotplug_acclimated ***/
if (60 <= cur_secs - cpu_secs) {
Cpu_cnt = Cpu_faux_cnt = procps_cpu_count();
cpu_secs = cur_secs;
#ifndef NUMA_DISABLE
if (Libnuma_handle)
Numa_node_tot = Numa_max_node() + 1;
#endif
}
#endif
} // end: sysinfo_refresh } // end: sysinfo_refresh
/*###### Inspect Other Output ##########################################*/ /*###### Inspect Other Output ##########################################*/
@ -2868,6 +2789,7 @@ signify_that:
* No matter what *they* say, we handle the really really BIG and * No matter what *they* say, we handle the really really BIG and
* IMPORTANT stuff upon which all those lessor functions depend! */ * IMPORTANT stuff upon which all those lessor functions depend! */
static void before (char *me) { static void before (char *me) {
enum stat_reap_type which;
struct sigaction sa; struct sigaction sa;
int i; int i;
int linux_version_code = procps_linux_version(); int linux_version_code = procps_linux_version();
@ -2884,24 +2806,29 @@ static void before (char *me) {
// accommodate nls/gettext potential translations // accommodate nls/gettext potential translations
initialize_nls(); initialize_nls();
// establish cpu particulars // establish some cpu particulars
Hertz = procps_hertz_get(); Hertz = procps_hertz_get();
Cpu_cnt = procps_cpu_count();
#ifdef PRETEND8CPUS
Cpu_cnt = 8;
#endif
Cpu_faux_cnt = Cpu_cnt;
Cpu_States_fmts = N_unq(STATE_lin2x6_fmt); Cpu_States_fmts = N_unq(STATE_lin2x6_fmt);
if (linux_version_code >= LINUX_VERSION(2, 6, 11)) if (linux_version_code >= LINUX_VERSION(2, 6, 11))
Cpu_States_fmts = N_unq(STATE_lin2x7_fmt); Cpu_States_fmts = N_unq(STATE_lin2x7_fmt);
// prepare for new library API ... // get the total cpus (and, if possible, max numa node number)
which = STAT_REAP_CPUS_ONLY;
#ifndef NUMA_DISABLE
which = STAT_REAP_CPUS_AND_NODES;
#endif
if (procps_stat_new(&Stat_ctx) < 0
|| !(Stat_reap = procps_stat_reap(Stat_ctx, which, Stat_items, MAXTBL(Stat_items))))
error_exit(fmtmk(N_fmt(LIB_errorcpu_fmt),__LINE__));
Numa_node_tot = Stat_reap->nodes->total;
Cpu_cnt = Stat_reap->cpus->total;
// prepare for memory stats from new library API ...
if (procps_meminfo_new(&Mem_ctx) < 0) if (procps_meminfo_new(&Mem_ctx) < 0)
error_exit(fmtmk(N_fmt(LIB_errormem_fmt),__LINE__)); error_exit(fmtmk(N_fmt(LIB_errormem_fmt),__LINE__));
if (!(Mem_stack = procps_meminfo_stack_alloc(Mem_ctx, MAXTBL(Mem_items), Mem_items))) if (!(Mem_stack = procps_meminfo_stack_alloc(Mem_ctx, MAXTBL(Mem_items), Mem_items)))
error_exit(fmtmk(N_fmt(LIB_errormem_fmt),__LINE__)); error_exit(fmtmk(N_fmt(LIB_errormem_fmt),__LINE__));
if (procps_stat_new(&Cpu_ctx) < 0)
error_exit(fmtmk(N_fmt(LIB_errorcpu_fmt),__LINE__));
// establish max depth for newlib pids stack (# of result structs) // establish max depth for newlib pids stack (# of result structs)
Pids_itms = alloc_c(sizeof(enum pids_item) * MAXTBL(Fieldstab)); Pids_itms = alloc_c(sizeof(enum pids_item) * MAXTBL(Fieldstab));
for (i = 0; i < MAXTBL(Fieldstab); i++) for (i = 0; i < MAXTBL(Fieldstab); i++)
@ -2911,25 +2838,6 @@ static void before (char *me) {
if (procps_pids_new(&Pids_ctx, Pids_itms_cur, Pids_itms)) if (procps_pids_new(&Pids_ctx, Pids_itms_cur, Pids_itms))
error_exit(fmtmk(N_fmt(LIB_errorpid_fmt),__LINE__)); error_exit(fmtmk(N_fmt(LIB_errorpid_fmt),__LINE__));
#ifndef NUMA_DISABLE
#if defined(PRETEND_NUMA) || defined(PRETEND8CPUS)
Numa_node_tot = Numa_max_node() + 1;
#else
// we'll try for the most recent version, then a version we know works...
if ((Libnuma_handle = dlopen("libnuma.so", RTLD_LAZY))
|| (Libnuma_handle = dlopen("libnuma.so.1", RTLD_LAZY))) {
Numa_max_node = dlsym(Libnuma_handle, "numa_max_node");
Numa_node_of_cpu = dlsym(Libnuma_handle, "numa_node_of_cpu");
if (Numa_max_node && Numa_node_of_cpu)
Numa_node_tot = Numa_max_node() + 1;
else {
dlclose(Libnuma_handle);
Libnuma_handle = NULL;
}
}
#endif
#endif
#ifndef SIGRTMAX // not available on hurd, maybe others too #ifndef SIGRTMAX // not available on hurd, maybe others too
#define SIGRTMAX 32 #define SIGRTMAX 32
#endif #endif
@ -4041,7 +3949,7 @@ static void keys_global (int ch) {
Pseudo_row = PROC_XTRA; Pseudo_row = PROC_XTRA;
break; break;
case 'I': case 'I':
if (Cpu_faux_cnt > 1) { if (Cpu_cnt > 1) {
Rc.mode_irixps = !Rc.mode_irixps; Rc.mode_irixps = !Rc.mode_irixps;
show_msg(fmtmk(N_fmt(IRIX_curmode_fmt) show_msg(fmtmk(N_fmt(IRIX_curmode_fmt)
, Rc.mode_irixps ? N_txt(ON_word_only_txt) : N_txt(OFF_one_word_txt))); , Rc.mode_irixps ? N_txt(ON_word_only_txt) : N_txt(OFF_one_word_txt)));
@ -4697,22 +4605,16 @@ all_done:
* 2) modest smp boxes with room for each cpu's percentages * 2) modest smp boxes with room for each cpu's percentages
* 3) massive smp guys leaving little or no room for process * 3) massive smp guys leaving little or no room for process
* display and thus requiring the cpu summary toggle */ * display and thus requiring the cpu summary toggle */
static void summary_hlp (struct procps_jiffs_hist *cpu, const char *pfx) { static void summary_hlp (struct stat_stack *this, const char *pfx) {
/* we'll trim to zero if we get negative time ticks, // a tailored 'results stack value' extractor macro
which has happened with some SMP kernels (pre-2.4?) #define rSv(E) PROCPS_STAT_VAL(E, sl_int, this)
and when cpus are dynamically added or removed */ SIC_t u_frme, s_frme, n_frme, i_frme, w_frme, x_frme, y_frme, z_frme, tot_frme;
#define TRIMz(x) ((tz = (SIC_t)(x)) < 0 ? 0 : tz)
SIC_t u_frme, s_frme, n_frme, i_frme, w_frme, x_frme, y_frme, z_frme, tot_frme, tz;
float scale; float scale;
u_frme = TRIMz(cpu->new.user - cpu->old.user); u_frme = rSv(stat_US); s_frme = rSv(stat_SY); n_frme = rSv(stat_NI);
s_frme = TRIMz(cpu->new.system - cpu->old.system); i_frme = rSv(stat_IL); w_frme = rSv(stat_IO); x_frme = rSv(stat_IR);
n_frme = TRIMz(cpu->new.nice - cpu->old.nice); y_frme = rSv(stat_SI); z_frme = rSv(stat_ST);
i_frme = TRIMz(cpu->new.idle - cpu->old.idle);
w_frme = TRIMz(cpu->new.iowait - cpu->old.iowait);
x_frme = TRIMz(cpu->new.irq - cpu->old.irq);
y_frme = TRIMz(cpu->new.sirq - cpu->old.sirq);
z_frme = TRIMz(cpu->new.stolen - cpu->old.stolen);
tot_frme = u_frme + s_frme + n_frme + i_frme + w_frme + x_frme + y_frme + z_frme; tot_frme = u_frme + s_frme + n_frme + i_frme + w_frme + x_frme + y_frme + z_frme;
if (1 > tot_frme) i_frme = tot_frme = 1; if (1 > tot_frme) i_frme = tot_frme = 1;
scale = 100.0 / (float)tot_frme; scale = 100.0 / (float)tot_frme;
@ -4750,7 +4652,7 @@ static void summary_hlp (struct procps_jiffs_hist *cpu, const char *pfx) {
, (float)w_frme * scale, (float)x_frme * scale , (float)w_frme * scale, (float)x_frme * scale
, (float)y_frme * scale, (float)z_frme * scale)); , (float)y_frme * scale, (float)z_frme * scale));
} }
#undef TRIMz #undef rSv
} // end: summary_hlp } // end: summary_hlp
@ -4791,33 +4693,32 @@ static void summary_show (void) {
if (CHKw(w, View_CPUNOD)) { if (CHKw(w, View_CPUNOD)) {
if (Numa_node_sel < 0) { if (Numa_node_sel < 0) {
numa_oops:
// display the 1st /proc/stat line, then the nodes (if room) // display the 1st /proc/stat line, then the nodes (if room)
summary_hlp(&Cpu_jiffs[Cpu_cnt], N_txt(WORD_allcpus_txt)); summary_hlp(Stat_reap->summary, N_txt(WORD_allcpus_txt));
Msg_row += 1; Msg_row += 1;
// display each cpu node's states // display each cpu node's states
for (i = 0; i < Numa_node_tot; i++) { for (i = 0; i < Numa_node_tot; i++) {
struct procps_jiffs_hist *nod_ptr = &Cpu_jiffs[1 + Cpu_cnt + i]; struct stat_stack *nod_ptr = Stat_reap->nodes->stacks[i];
if (NOD_VAL(stat_ID, s_int, i) == PROCPS_STAT_NODE_INVALID) continue;
if (!isROOM(anyFLG, 1)) break; if (!isROOM(anyFLG, 1)) break;
#ifndef OFF_NUMASKIP snprintf(tmp, sizeof(tmp), N_fmt(NUMA_nodenam_fmt), NOD_VAL(stat_ID, s_int, i));
if (nod_ptr->id) {
#endif
snprintf(tmp, sizeof(tmp), N_fmt(NUMA_nodenam_fmt), i);
summary_hlp(nod_ptr, tmp); summary_hlp(nod_ptr, tmp);
Msg_row += 1; Msg_row += 1;
#ifndef OFF_NUMASKIP
}
#endif
} }
} else { } else {
// display the node summary, then the associated cpus (if room) // display the node summary, then the associated cpus (if room)
for (i = 0; i < Numa_node_tot; i++)
if (Numa_node_sel == NOD_VAL(stat_ID, s_int, i)) break;
if (i == Numa_node_tot) goto numa_oops;
snprintf(tmp, sizeof(tmp), N_fmt(NUMA_nodenam_fmt), Numa_node_sel); snprintf(tmp, sizeof(tmp), N_fmt(NUMA_nodenam_fmt), Numa_node_sel);
summary_hlp(&Cpu_jiffs[1 + Cpu_cnt + Numa_node_sel], tmp); summary_hlp(Stat_reap->nodes->stacks[Numa_node_sel], tmp);
Msg_row += 1; Msg_row += 1;
for (i = 0; i < Cpu_faux_cnt; i++) { for (i = 0; i < Cpu_cnt; i++) {
if (Numa_node_sel == Numa_node_of_cpu(Cpu_jiffs[i].id)) { if (Numa_node_sel == CPU_VAL(stat_NU, s_int, i)) {
if (!isROOM(anyFLG, 1)) break; if (!isROOM(anyFLG, 1)) break;
snprintf(tmp, sizeof(tmp), N_fmt(WORD_eachcpu_fmt), Cpu_jiffs[i].id); snprintf(tmp, sizeof(tmp), N_fmt(WORD_eachcpu_fmt), CPU_VAL(stat_ID, s_int, i));
summary_hlp(&Cpu_jiffs[i], tmp); summary_hlp(Stat_reap->nodes->stacks[i], tmp);
Msg_row += 1; Msg_row += 1;
} }
} }
@ -4827,14 +4728,14 @@ numa_nope:
#endif #endif
if (CHKw(w, View_CPUSUM)) { if (CHKw(w, View_CPUSUM)) {
// display just the 1st /proc/stat line // display just the 1st /proc/stat line
summary_hlp(&Cpu_jiffs[Cpu_faux_cnt], N_txt(WORD_allcpus_txt)); summary_hlp(Stat_reap->summary, N_txt(WORD_allcpus_txt));
Msg_row += 1; Msg_row += 1;
} else { } else {
// display each cpu's states separately, screen height permitting... // display each cpu's states separately, screen height permitting...
for (i = 0; i < Cpu_faux_cnt; i++) { for (i = 0; i < Cpu_cnt; i++) {
snprintf(tmp, sizeof(tmp), N_fmt(WORD_eachcpu_fmt), Cpu_jiffs[i].id); snprintf(tmp, sizeof(tmp), N_fmt(WORD_eachcpu_fmt), CPU_VAL(stat_ID, s_int, i));
summary_hlp(&Cpu_jiffs[i], tmp); summary_hlp(Stat_reap->cpus->stacks[i], tmp);
Msg_row += 1; Msg_row += 1;
if (!isROOM(anyFLG, 1)) break; if (!isROOM(anyFLG, 1)) break;
} }

View File

@ -39,13 +39,10 @@
//#define INSP_SAVEBUF /* preserve 'Insp_buf' contents in a file */ //#define INSP_SAVEBUF /* preserve 'Insp_buf' contents in a file */
//#define INSP_SLIDE_1 /* when scrolling left/right don't move 8 */ //#define INSP_SLIDE_1 /* when scrolling left/right don't move 8 */
//#define MEMGRAPH_OLD /* don't use 'available' when graphing Mem */ //#define MEMGRAPH_OLD /* don't use 'available' when graphing Mem */
//#define OFF_NUMASKIP /* do NOT skip numa nodes if discontinuous */
//#define OFF_SCROLLBK /* disable tty emulators scrollback buffer */ //#define OFF_SCROLLBK /* disable tty emulators scrollback buffer */
//#define OFF_STDERROR /* disable our stderr buffering (redirect) */ //#define OFF_STDERROR /* disable our stderr buffering (redirect) */
//#define OFF_STDIOLBF /* disable our own stdout _IOFBF override */ //#define OFF_STDIOLBF /* disable our own stdout _IOFBF override */
//#define PRETEND8CPUS /* pretend we're smp with 8 ticsers (sic) */
//#define PRETENDNOCAP /* use a terminal without essential caps */ //#define PRETENDNOCAP /* use a terminal without essential caps */
//#define PRETEND_NUMA /* pretend 4 (or 3 w/o OFF_NUMASKIP) Nodes */
//#define QUICK_GRAPHS /* use fast algorithm, accept +2% distort */ //#define QUICK_GRAPHS /* use fast algorithm, accept +2% distort */
//#define RCFILE_NOERR /* rcfile errs silently default, vs. fatal */ //#define RCFILE_NOERR /* rcfile errs silently default, vs. fatal */
//#define RECALL_FIXED /* don't reorder saved strings if recalled */ //#define RECALL_FIXED /* don't reorder saved strings if recalled */
@ -522,12 +519,6 @@ typedef struct WIN_t {
#if defined(RECALL_FIXED) && defined(TERMIOS_ONLY) #if defined(RECALL_FIXED) && defined(TERMIOS_ONLY)
# error 'RECALL_FIXED' conflicts with 'TERMIOS_ONLY' # error 'RECALL_FIXED' conflicts with 'TERMIOS_ONLY'
#endif #endif
#if defined(PRETEND_NUMA) && defined(NUMA_DISABLE)
# error 'PRETEND_NUMA' confilcts with 'NUMA_DISABLE'
#endif
#if defined(OFF_NUMASKIP) && defined(NUMA_DISABLE)
# error 'OFF_NUMASKIP' confilcts with 'NUMA_DISABLE'
#endif
#if (LRGBUFSIZ < SCREENMAX) #if (LRGBUFSIZ < SCREENMAX)
# error 'LRGBUFSIZ' must NOT be less than 'SCREENMAX' # error 'LRGBUFSIZ' must NOT be less than 'SCREENMAX'
#endif #endif
@ -574,7 +565,7 @@ typedef struct WIN_t {
/*------ Small Utility routines ----------------------------------------*/ /*------ Small Utility routines ----------------------------------------*/
//atic float get_float (const char *prompt); //atic float get_float (const char *prompt);
//atic int get_int (const char *prompt); //atic int get_int (const char *prompt);
//atic inline const char *hex_make (KLONG num, int noz); //atic inline const char *hex_make (long num, int noz);
//atic void osel_clear (WIN_t *q); //atic void osel_clear (WIN_t *q);
//atic inline int osel_matched (const WIN_t *q, FLG_t enu, const char *str); //atic inline int osel_matched (const WIN_t *q, FLG_t enu, const char *str);
//atic const char *user_certify (WIN_t *q, const char *str, char typ); //atic const char *user_certify (WIN_t *q, const char *str, char typ);
@ -648,7 +639,7 @@ typedef struct WIN_t {
//atic inline const char *forest_display (const WIN_t *q, struct pids_stack *p); //atic inline const char *forest_display (const WIN_t *q, struct pids_stack *p);
/*------ Main Screen routines ------------------------------------------*/ /*------ Main Screen routines ------------------------------------------*/
//atic void do_key (int ch); //atic void do_key (int ch);
//atic void summary_hlp (struct procps_jiffs_hist *cpu, const char *pfx); //atic void summary_hlp (struct stat_stack *this, const char *pfx);
//atic void summary_show (void); //atic void summary_show (void);
//atic const char *task_show (const WIN_t *q, struct pids_stack *p); //atic const char *task_show (const WIN_t *q, struct pids_stack *p);
//atic int window_show (WIN_t *q, int wmax); //atic int window_show (WIN_t *q, int wmax);