From 00f5c74b1bc583d37315fa094c6f50cef7961c0c Mon Sep 17 00:00:00 2001 From: Jim Warner Date: Wed, 28 Sep 2022 00:00:00 -0500 Subject: [PATCH] top: exploit that library p-core/e-core identification I sure hope we won't disappoint the library with these changes since we're only exploiting one of the two new enumerators that the immediately prior patch provided. Now top will be able to offer a visual clue as to each cpu (thread actually) core association. Is it a P-core offering multiple threads or a single threaded E-core. We'll accomplish this feat with a subtle change to the states portion ('t' toggle) of the summary area. Where before processors were represented as 'Cpu', they will now be displayed as 'CpP' (P-core) and 'CpE' (E-core). [ assuming that new '5' command toggle has been used ] There are also new provisions for filtering those cpus by their core type association via the new '5' toggle. Signed-off-by: Jim Warner --- src/top/top.c | 93 ++++++++++++++++++++++++++++++++++++++++++----- src/top/top.h | 12 ++++-- src/top/top_nls.c | 5 ++- 3 files changed, 95 insertions(+), 15 deletions(-) diff --git a/src/top/top.c b/src/top/top.c index 718dbb39..f3bef9a7 100644 --- a/src/top/top.c +++ b/src/top/top.c @@ -286,7 +286,11 @@ static enum stat_item Stat_items[] = { STAT_TIC_DELTA_IOWAIT, STAT_TIC_DELTA_IRQ, STAT_TIC_DELTA_SOFTIRQ, STAT_TIC_DELTA_STOLEN, STAT_TIC_SUM_DELTA_USER, STAT_TIC_SUM_DELTA_SYSTEM, +#ifdef CORE_TYPE_NO STAT_TIC_SUM_DELTA_TOTAL }; +#else + STAT_TIC_SUM_DELTA_TOTAL, STAT_TIC_TYPE_CORE }; +#endif enum Rel_statitems { stat_ID, stat_NU, stat_US, stat_SY, @@ -294,11 +298,19 @@ enum Rel_statitems { stat_IO, stat_IR, stat_SI, stat_ST, stat_SUM_USR, stat_SUM_SYS, +#ifdef CORE_TYPE_NO stat_SUM_TOT }; +#else + stat_SUM_TOT, stat_COR_TYP }; +#endif // cpu/node stack results extractor macros, where e=rel enum, x=index #define CPU_VAL(e,x) STAT_VAL(e, s_int, Stat_reap->cpus->stacks[x], Stat_ctx) #define NOD_VAL(e,x) STAT_VAL(e, s_int, Stat_reap->numa->stacks[x], Stat_ctx) #define TIC_VAL(e,s) STAT_VAL(e, sl_int, s, Stat_ctx) +#define E_CORE 1 // values for stat_COR_TYP itself +#define P_CORE 2 // ( 0 = unsure/unknown ) +#define P_CORES_ONLY 2 // values of rc.core_types toggle, for filtering +#define E_CORES_ONLY 3 // ( 0 = Cpu shown, 1 = both CpP & CpE shown ) /* * --- ----------------------------------------------- */ static struct meminfo_info *Mem_ctx; @@ -2721,6 +2733,12 @@ static void *cpus_refresh (void *unused) { Cpu_cnt = 48; #endif } +#ifdef PRETENDECORE +{ int i; + for (i = Cpu_cnt - (Cpu_cnt / 4); i < Cpu_cnt; i++) + Stat_reap->cpus->stacks[i]->head[stat_COR_TYP].result.s_int = E_CORE; +} +#endif #ifdef THREADED_CPU sem_post(&Semaphore_cpus_end); } while (1); @@ -3990,9 +4008,9 @@ static const char *configs_file (FILE *fp, const char *name, float *delay) { // be tolerant of missing release 3.3.10 graph modes additions if (3 > fscanf(fp, "\twinflags=%d, sortindx=%d, maxtasks=%d, graph_cpus=%d, graph_mems=%d" - ", double_up=%d, combine_cpus=%d\n" + ", double_up=%d, combine_cpus=%d, core_types=%d\n" , &w->rc.winflags, &w->rc.sortindx, &w->rc.maxtasks, &w->rc.graph_cpus, &w->rc.graph_mems - , &w->rc.double_up, &w->rc.combine_cpus)) + , &w->rc.double_up, &w->rc.combine_cpus, &w->rc.core_types)) return p; if (w->rc.sortindx < 0 || w->rc.sortindx >= EU_MAXPFLGS) return p; @@ -4007,6 +4025,8 @@ static const char *configs_file (FILE *fp, const char *name, float *delay) { // can't check upper bounds until Cpu_cnt is known if (w->rc.combine_cpus < 0) return p; + if (w->rc.core_types < 0 || w->rc.core_types > E_CORES_ONLY) + return p; if (4 != fscanf(fp, "\tsummclr=%d, msgsclr=%d, headclr=%d, taskclr=%d\n" , &w->rc.summclr, &w->rc.msgsclr, &w->rc.headclr, &w->rc.taskclr)) @@ -4498,6 +4518,7 @@ static void win_reset (WIN_t *q) { osel_clear(q); q->findstr[0] = '\0'; q->rc.combine_cpus = 0; + q->rc.core_types = 0; // these next guys are global, not really windows based Monpidsidx = 0; @@ -5471,10 +5492,10 @@ static void write_rcfile (void) { } fprintf(fp, "\n"); fprintf(fp, "\twinflags=%d, sortindx=%d, maxtasks=%d, graph_cpus=%d, graph_mems=%d" - ", double_up=%d, combine_cpus=%d\n" + ", double_up=%d, combine_cpus=%d, core_types=%d\n" , Winstk[i].rc.winflags, Winstk[i].rc.sortindx, Winstk[i].rc.maxtasks - , Winstk[i].rc.graph_cpus, Winstk[i].rc.graph_mems - , Winstk[i].rc.double_up, Winstk[i].rc.combine_cpus); + , Winstk[i].rc.graph_cpus, Winstk[i].rc.graph_mems, Winstk[i].rc.double_up + , Winstk[i].rc.combine_cpus, Winstk[i].rc.core_types); fprintf(fp, "\tsummclr=%d, msgsclr=%d, headclr=%d, taskclr=%d\n" , Winstk[i].rc.summclr, Winstk[i].rc.msgsclr , Winstk[i].rc.headclr, Winstk[i].rc.taskclr); @@ -5728,6 +5749,7 @@ static void keys_summary (int ch) { if (!w->rc.combine_cpus) w->rc.combine_cpus = 1; else w->rc.combine_cpus *= 2; if (w->rc.combine_cpus >= Cpu_cnt) w->rc.combine_cpus = 0; + w->rc.core_types = 0; } break; case '1': @@ -5736,6 +5758,7 @@ static void keys_summary (int ch) { OFFw(w, View_CPUNOD); SETw(w, View_STATES); w->rc.double_up = 0; + w->rc.core_types = 0; break; case '2': if (!Numa_node_tot) @@ -5746,6 +5769,7 @@ static void keys_summary (int ch) { SETw(w, View_STATES); Numa_node_sel = -1; w->rc.double_up = 0; + w->rc.core_types = 0; } break; case '3': @@ -5759,6 +5783,7 @@ static void keys_summary (int ch) { SETw(w, View_CPUNOD | View_STATES); OFFw(w, View_CPUSUM); w->rc.double_up = 0; + w->rc.core_types = 0; } else show_msg(N_txt(NUMA_nodebad_txt)); } @@ -5774,6 +5799,27 @@ static void keys_summary (int ch) { w->rc.double_up = 0; OFFw(w, (View_CPUSUM | View_CPUNOD)); break; +#ifndef CORE_TYPE_NO + case '5': + if (!CHKw(w, View_STATES) + || ((CHKw(w, View_CPUSUM | View_CPUNOD)) + || ((w->rc.combine_cpus)))) + show_msg(N_txt(XTRA_modebad_txt)); + else { + static int scanned; + if (!scanned) { + for (; scanned < Cpu_cnt; scanned++) + if (CPU_VAL(stat_COR_TYP, scanned) == E_CORE) + break; + } + if (scanned < Cpu_cnt) { + w->rc.core_types += 1; + if (w->rc.core_types > E_CORES_ONLY) + w->rc.core_types = 0; + } else w->rc.core_types = 0; + } + break; +#endif case 'C': VIZTOGw(w, View_SCROLL); break; @@ -6252,6 +6298,7 @@ static inline int sum_see (const char *str, int nobuf) { char *p; p = scat(row, str); + if (!str[0]) goto flush_it; if (Curwin->rc.double_up && (!nobuf)) { if (++tog <= Curwin->rc.double_up) { @@ -6259,6 +6306,8 @@ static inline int sum_see (const char *str, int nobuf) { return 0; } } +flush_it: + if (!row[0]) return 0; scat(p, "\n"); show_special(0, row); row[0] = '\0'; @@ -6277,12 +6326,17 @@ static inline int sum_see (const char *str, int nobuf) { * display and thus requiring the '1', '4', or '!' cpu toggles | * ( we return the number of lines printed, as reported by sum_see ) | */ static int sum_tics (struct stat_stack *this, const char *pfx, int nobuf) { - // a tailored 'results stack value' extractor macro + // tailored 'results stack value' extractor macros + #define qSv(E) STAT_VAL(E, s_int, this, Stat_ctx) #define rSv(E) TIC_VAL(E, this) SIC_t idl_frme, tot_frme; struct rx_st *rx; float scale; +#ifndef CORE_TYPE_NO + if (Curwin->rc.core_types == P_CORES_ONLY && qSv(stat_COR_TYP) != P_CORE) return 0; + if (Curwin->rc.core_types == E_CORES_ONLY && qSv(stat_COR_TYP) != E_CORE) return 0; +#endif idl_frme = rSv(stat_IL); tot_frme = rSv(stat_SUM_TOT); if (1 > tot_frme) idl_frme = tot_frme = 1; @@ -6310,6 +6364,7 @@ static int sum_tics (struct stat_stack *this, const char *pfx, int nobuf) { , (float)rSv(stat_IO) * scale, (float)rSv(stat_IR) * scale , (float)rSv(stat_SI) * scale, (float)rSv(stat_ST) * scale), nobuf); } + #undef qSv #undef rSv } // end: sum_tics @@ -6360,6 +6415,7 @@ static int sum_unify (struct stat_stack *this, int nobuf) { * ( so as to keep the 'summary_show' guy a reasonable size ) | */ static void do_cpus (void) { #define noMAS (Msg_row + 1 >= SCREEN_ROWS - 1) + #define eachCPU(x) N_fmt(WORD_eachcpu_fmt), 'u', x char tmp[MEDBUFSIZ]; int i; @@ -6398,7 +6454,7 @@ numa_oops: for (i = 0; i < deLIMIT; i++) { if (Numa_node_sel == CPU_VAL(stat_NU, i)) { if (noMAS) break; - snprintf(tmp, sizeof(tmp), N_fmt(WORD_eachcpu_fmt), CPU_VAL(stat_ID, i)); + snprintf(tmp, sizeof(tmp), eachCPU(CPU_VAL(stat_ID, i))); Msg_row += sum_tics(Stat_reap->cpus->stacks[i], tmp, 1); } } @@ -6419,7 +6475,7 @@ numa_oops: } } else { for (i = 0, j = 0; i < Cpu_cnt; i++) { - snprintf(tmp, sizeof(tmp), N_fmt(WORD_eachcpu_fmt), i); + snprintf(tmp, sizeof(tmp), eachCPU(i)); Msg_row += sum_tics(Stat_reap->cpus->stacks[j], tmp, (i+1 >= Cpu_cnt)); if (++j >= Stat_reap->cpus->total) j = 0; if (noMAS) break; @@ -6433,7 +6489,18 @@ numa_oops: } } else { for (i = 0; i < Cpu_cnt; i++) { - snprintf(tmp, sizeof(tmp), N_fmt(WORD_eachcpu_fmt), CPU_VAL(stat_ID, i)); +#ifndef CORE_TYPE_NO + #ifdef CORE_TYPE_LO + char ctab[] = { 'u', 'e', 'p' }; + #else + char ctab[] = { 'u', 'E', 'P' }; + #endif + int cid = CPU_VAL(stat_ID, i), typ = CPU_VAL(stat_COR_TYP, i); + char chr = Curwin->rc.core_types ? ctab[typ] : 'u' ; + snprintf(tmp, sizeof(tmp), N_fmt(WORD_eachcpu_fmt), chr, cid); +#else + snprintf(tmp, sizeof(tmp), eachCPU(CPU_VAL(stat_ID, i))); +#endif Msg_row += sum_tics(Stat_reap->cpus->stacks[i], tmp, (i+1 >= Cpu_cnt)); if (noMAS) break; } @@ -6445,7 +6512,11 @@ numa_oops: * display just the 1st /proc/stat line ... */ Msg_row += sum_tics(Stat_reap->summary, N_txt(WORD_allcpus_txt), 1); } + + // coax this guy into flushing any pending cpu stuff ... + Msg_row += sum_see("", 1); #undef noMAS + #undef eachCPU } // end: do_cpus @@ -6583,7 +6654,11 @@ static void do_key (int ch) { , kbd_CtrlN, kbd_CtrlP, kbd_CtrlR, kbd_CtrlU , kbd_ENTER, kbd_SPACE, kbd_BTAB, '\0' } }, { keys_summary, + #ifdef CORE_TYPE_NO { '!', '1', '2', '3', '4', 'C', 'l', 'm', 't', '\0' } }, + #else + { '!', '1', '2', '3', '4', '5', 'C', 'l', 'm', 't', '\0' } }, + #endif { keys_task, { '#', '<', '>', 'b', 'c', 'F', 'i', 'J', 'j', 'n', 'O', 'o' , 'R', 'S', 'U', 'u', 'V', 'v', 'x', 'y', 'z' diff --git a/src/top/top.h b/src/top/top.h index 74532f2c..17920025 100644 --- a/src/top/top.h +++ b/src/top/top.h @@ -30,6 +30,8 @@ //#define BOT_STRV_OFF /* don't emphasize strv w/ focus if spaces */ //#define CASEUP_HEXES /* show all those hex values in upper case */ //#define CASEUP_SUFIX /* show time/mem/cnts suffix in upper case */ +//#define CORE_TYPE_LO /* show the type of cpu core in lower case */ +//#define CORE_TYPE_NO /* don't distinguish the types of cpu core */ //#define EQUCOLHDRYES /* yes, equalize the column header lengths */ //#define FOCUS_HARD_Y /* 'F' will avoid topmost task distortions */ //#define FOCUS_TREE_X /* 'F' resets forest view indentation to 0 */ @@ -47,6 +49,7 @@ //#define OVERTYPE_SEE /* display a visual hint for overtype mode */ //#define PRETEND0NUMA /* pretend that there ain't any numa nodes */ //#define PRETEND48CPU /* pretend we're smp with 48 ticsers (sic) */ +//#define PRETENDECORE /* pretend we've got some e-core type cpus */ //#define PRETENDNOCAP /* pretend terminal missing essential caps */ //#define RCFILE_NOERR /* rcfile errs silently default, vs. fatal */ //#define RECALL_FIXED /* don't reorder saved strings if recalled */ @@ -324,6 +327,7 @@ typedef struct RCW_t { // the 'window' portion of an rcfile graph_mems, // 'm' - View_MEMORY supplememtary vals double_up, // '4' - show multiple cpus on one line combine_cpus, // '!' - keep combining additional cpus + core_types, // '5' - show/filter P-core/E-core cpus summclr, // a colors 'number' used for summ info msgsclr, // " in msgs/pmts headclr, // " in cols head @@ -587,16 +591,16 @@ typedef struct WIN_t { /* The default values for the local config file */ #define DEF_RCFILE { \ RCF_VERSION_ID, 0, 1, DEF_DELAY, 0, { \ - { EU_CPU, DEF_WINFLGS, 0, DEF_GRAPHS2, 1, 0, \ + { EU_CPU, DEF_WINFLGS, 0, DEF_GRAPHS2, 1, 0, 0, \ COLOR_RED, COLOR_RED, COLOR_YELLOW, COLOR_RED, \ "Def", DEF_FIELDS }, \ - { EU_PID, ALT_WINFLGS, 0, ALT_GRAPHS2, 0, 0, \ + { EU_PID, ALT_WINFLGS, 0, ALT_GRAPHS2, 0, 0, 0, \ COLOR_CYAN, COLOR_CYAN, COLOR_WHITE, COLOR_CYAN, \ "Job", JOB_FIELDS }, \ - { EU_MEM, ALT_WINFLGS, 0, ALT_GRAPHS2, 0, 0, \ + { EU_MEM, ALT_WINFLGS, 0, ALT_GRAPHS2, 0, 0, 0, \ COLOR_MAGENTA, COLOR_MAGENTA, COLOR_BLUE, COLOR_MAGENTA, \ "Mem", MEM_FIELDS }, \ - { EU_UEN, ALT_WINFLGS, 0, ALT_GRAPHS2, 0, 0, \ + { EU_UEN, ALT_WINFLGS, 0, ALT_GRAPHS2, 0, 0, 0, \ COLOR_YELLOW, COLOR_YELLOW, COLOR_GREEN, COLOR_YELLOW, \ "Usr", USR_FIELDS } \ }, 0, DEF_SCALES2, 0, 0 } diff --git a/src/top/top_nls.c b/src/top/top_nls.c index 7c44a7a6..869a88cf 100644 --- a/src/top/top_nls.c +++ b/src/top/top_nls.c @@ -496,8 +496,9 @@ static void build_norm_nlstab (void) { . (should be exactly 6 characters, excluding leading % & colon) */ Norm_nlstab[WORD_allcpus_txt] = _("%Cpu(s):"); /* Translation Hint: The following "word" is meant to represent a single processor - . (should be exactly 3 characters, excluding leading %%, fmt chars & colon) */ - Norm_nlstab[WORD_eachcpu_fmt] = _("%%Cpu%-3d:"); + and 'the Cp' prefix will be combined with a core id: 'p', 'e' or 'u' + . (if 'Cp' is translated, it must be exactly 2 characters long) */ + Norm_nlstab[WORD_eachcpu_fmt] = _("%%Cp%c%-3d:"); /* Translation Hint: The following word "another" must have 1 trailing space */ Norm_nlstab[WORD_another_txt] = _("another "); Norm_nlstab[FIND_no_next_txt] = _("Locate next inactive, use \"L\""); -- 2.40.0