]> granicus.if.org Git - procps-ng/commitdiff
top: added fields for 'start time' & 'cpu utilization'
authorJim Warner <james.warner@comcast.net>
Fri, 25 Feb 2022 06:00:00 +0000 (00:00 -0600)
committerCraig Small <csmall@dropbear.xyz>
Sun, 27 Feb 2022 10:27:02 +0000 (21:27 +1100)
This patch will exploit some new library capabilities.

[ one will raise eyebrows, the other likely will not ]

A new 'STARTED' field was added which shows the time a
process started after system boot. As such the largest
interval represents the most recently started process.

This is the field that will likely be questioned since
it's somewhat counterintuitive. But were we to instead
use TIME_ELAPSED, the value will change with every top
refresh. This will defeat any PUFF macro optimization.

The new '%CUU' field will probably be better received.
It represents the cpu usage over the life of the task.
When a process was showing high %CPU usage, this field
can be used to determine if it's an anomaly or normal.

[ and as with %CPU, %CUU shows a '?' when running in ]
[ a namespace when /proc was mounted with subset=pid ]

Signed-off-by: Jim Warner <james.warner@comcast.net>
top/top.c
top/top.h
top/top_nls.c

index df3019d06a7caed11d5a58b4dab04933817ec309..f30ce57f98d7e96d93c73f6624831e3810576389 100644 (file)
--- a/top/top.c
+++ b/top/top.c
@@ -1597,18 +1597,27 @@ end_justifies:
 
         /*
          * Make and then justify a percentage, with decreasing precision. */
-static const char *scale_pcnt (float num, int width, int justr) {
+static const char *scale_pcnt (float num, int width, int justr, int xtra) {
    static char buf[SMLBUFSIZ];
 
    buf[0] = '\0';
    if (Rc.zero_suppress && 0 >= num)
       goto end_justifies;
+   if (xtra) {
+      if (width >= snprintf(buf, sizeof(buf), "%#.3f", num))
+         goto end_justifies;
+      if (width >= snprintf(buf, sizeof(buf), "%#.2f", num))
+         goto end_justifies;
+      goto carry_on;
+   }
 #ifdef BOOST_PERCNT
    if (width >= snprintf(buf, sizeof(buf), "%#.3f", num))
       goto end_justifies;
    if (width >= snprintf(buf, sizeof(buf), "%#.2f", num))
       goto end_justifies;
+   (void)xtra;
 #endif
+carry_on:
    if (width >= snprintf(buf, sizeof(buf), "%#.1f", num))
       goto end_justifies;
    if (width >= snprintf(buf, sizeof(buf), "%*.0f", width, num))
@@ -1766,23 +1775,23 @@ static struct {
    {     6,     -1,  A_right,  PIDS_IO_WRITE_BYTES },  // ul_int   EU_IWB
    {     5,     -1,  A_right,  PIDS_IO_WRITE_OPS   },  // ul_int   EU_IWO
    {     5,     -1,  A_right,  PIDS_AUTOGRP_ID     },  // s_int    EU_AGI
-   {     4,     -1,  A_right,  PIDS_AUTOGRP_NICE   }   // s_int    EU_AGN
-#define eu_LAST        EU_AGN
+   {     4,     -1,  A_right,  PIDS_AUTOGRP_NICE   },  // s_int    EU_AGN
+   {     9,     -1,  A_right,  PIDS_TICS_BEGAN     },  // ull_int  EU_TM3
+   {     6,     -1,  A_right,  PIDS_UTILIZATION    }   // real     EU_CUU
+#define eu_LAST  EU_CUU
 // xtra Fieldstab 'pseudo pflag' entries for the newlib interface . . . . . . .
 #define eu_CMDLINE     eu_LAST +1
 #define eu_TICS_ALL_C  eu_LAST +2
-#define eu_TIME_START  eu_LAST +3
-#define eu_ID_FUID     eu_LAST +4
-#define eu_TREE_HID    eu_LAST +5
-#define eu_TREE_LVL    eu_LAST +6
-#define eu_TREE_ADD    eu_LAST +7
+#define eu_ID_FUID     eu_LAST +3
+#define eu_TREE_HID    eu_LAST +4
+#define eu_TREE_LVL    eu_LAST +5
+#define eu_TREE_ADD    eu_LAST +6
    , {  -1, -1, -1,  PIDS_CMDLINE     }  // str      ( if Show_CMDLIN, eu_CMDLINE    )
    , {  -1, -1, -1,  PIDS_TICS_ALL_C  }  // ull_int  ( if Show_CTIMES, eu_TICS_ALL_C )
-   , {  -1, -1, -1,  PIDS_TIME_START  }  // ull_int  ( if Show_FOREST, eu_TIME_START )
    , {  -1, -1, -1,  PIDS_ID_FUID     }  // u_int    ( if a usrseltyp, eu_ID_FUID    )
    , {  -1, -1, -1,  PIDS_extra       }  // s_ch     ( if Show_FOREST, eu_TREE_HID   )
    , {  -1, -1, -1,  PIDS_extra       }  // s_int    ( if Show_FOREST, eu_TREE_LVL   )
-   , {  -1, -1, -1,  PIDS_extra       }  // u_int    ( if Show_FOREST, eu_TREE_ADD   )
+   , {  -1, -1, -1,  PIDS_extra       }  // s_int    ( if Show_FOREST, eu_TREE_ADD   )
  #undef A_left
  #undef A_right
 };
@@ -1956,9 +1965,9 @@ static void build_headers (void) {
          if (!CHKw(w, Show_IDLEPS)) ckITEM(EU_CPU);
          // with forest view mode, we'll need pid, tgid, ppid & start_time...
 #ifndef TREE_VCPUOFF
-         if (CHKw(w, Show_FOREST)) { ckITEM(EU_PPD); ckITEM(EU_TGD); ckITEM(eu_TIME_START); ckITEM(eu_TREE_HID); ckITEM(eu_TREE_LVL); ckITEM(eu_TREE_ADD); }
+         if (CHKw(w, Show_FOREST)) { ckITEM(EU_PPD); ckITEM(EU_TGD); ckITEM(EU_TM3); ckITEM(eu_TREE_HID); ckITEM(eu_TREE_LVL); ckITEM(eu_TREE_ADD); }
 #else
-         if (CHKw(w, Show_FOREST)) { ckITEM(EU_PPD); ckITEM(EU_TGD); ckITEM(eu_TIME_START); ckITEM(eu_TREE_HID); ckITEM(eu_TREE_LVL); }
+         if (CHKw(w, Show_FOREST)) { ckITEM(EU_PPD); ckITEM(EU_TGD); ckITEM(EU_TM3); ckITEM(eu_TREE_HID); ckITEM(eu_TREE_LVL); }
 #endif
          // for 'u/U' filtering we need these too (old top forgot that, oops)
          if (w->usrseltyp) { ckITEM(EU_UED); ckITEM(EU_URD); ckITEM(EU_USD); ckITEM(eu_ID_FUID); }
@@ -4549,7 +4558,7 @@ static void forest_begin (WIN_t *q) {
 
 #ifndef TREE_SCANALL
       if (!(procps_pids_sort(Pids_ctx, Seed_ppt, PIDSmaxt
-         , PIDS_TIME_START, PIDS_SORT_ASCEND)))
+         , PIDS_TICS_BEGAN, PIDS_SORT_ASCEND)))
             error_exit(fmtmk(N_fmt(LIB_errorpid_fmt), __LINE__, strerror(errno)));
 #endif
       for (i = 0; i < PIDSmaxt; i++) {         // avoid hidepid distorts |
@@ -6158,9 +6167,17 @@ static const char *task_show (const WIN_t *q, int idx) {
             if (u > 100.0 * n) u = 100.0 * n;
 #endif
             if (u > Cpu_pmax) u = Cpu_pmax;
-            cp = scale_pcnt(u, W, Jn);
+            cp = scale_pcnt(u, W, Jn, 0);
          }
             break;
+   /* ull_int, scale_pcnt for 'utilization' */
+         case EU_CUU:        // PIDS_UTILIZATION
+            if (Restrict_some) {
+               cp = justify_pad("?", W, Jn);
+               break;
+            }
+            cp = scale_pcnt(rSv(EU_CUU, real), W, Jn, 1);
+            break;
    /* u_int, make_num with auto width */
          case EU_GID:        // PIDS_ID_EGID
          case EU_UED:        // PIDS_ID_EUID
@@ -6213,7 +6230,7 @@ static const char *task_show (const WIN_t *q, int idx) {
                cp = justify_pad("?", W, Jn);
                break;
             }
-            cp = scale_pcnt((float)rSv(EU_MEM, ul_int) * 100 / MEM_VAL(mem_TOT), W, Jn);
+            cp = scale_pcnt((float)rSv(EU_MEM, ul_int) * 100 / MEM_VAL(mem_TOT), W, Jn, 0);
             break;
    /* ul_int, make_str with special handling */
          case EU_FLG:        // PIDS_FLAGS
@@ -6228,6 +6245,10 @@ static const char *task_show (const WIN_t *q, int idx) {
             cp = scale_tics(t, W, Jn);
          }
             break;
+   /* ull_int, scale_time */
+         case EU_TM3:        // PIDS_TICS_BEGAN
+            cp = scale_tics(rSv(EU_TM3, ull_int), W, Jn);
+            break;
    /* str, make_str (all AUTOX yes) */
          case EU_LXC:        // PIDS_LXCNAME
          case EU_TTY:        // PIDS_TTY_NAME
index 3e67e49347a2dea5e2553662cfb3d38b53bcd2b1..f008f550685f6dfd381e965827a2d125c5a571f7 100644 (file)
--- a/top/top.h
+++ b/top/top.h
@@ -202,6 +202,7 @@ enum pflag {
    EU_RSS, EU_PSS, EU_PZA, EU_PZF, EU_PZS, EU_USS,
    EU_IRB, EU_IRO, EU_IWB, EU_IWO,
    EU_AGI, EU_AGN,
+   EU_TM3, EU_CUU,
 #ifdef USE_X_COLHDR
    // not really pflags, used with tbl indexing
    EU_MAXPFLGS
@@ -622,7 +623,7 @@ typedef struct WIN_t {
 //atic inline const char *make_str_utf8 (const char *str, int width, int justr, int col);
 //atic const char   *scale_mem (int target, float num, int width, int justr);
 //atic const char   *scale_num (float num, int width, int justr);
-//atic const char   *scale_pcnt (float num, int width, int justr);
+//atic const char   *scale_pcnt (float num, int width, int justr, int xtra);
 //atic const char   *scale_tics (TIC_t tics, int width, int justr);
 /*------  Fields Management support  -------------------------------------*/
 /*atic struct        Fieldstab[] = { ... }                                */
index 38e1867d2110975f4c9d3dddbc511b7535d1ab5b..64c9cc5ffba6c9e471b1fd2cd33967149f0e3ddd 100644 (file)
@@ -350,6 +350,12 @@ static void build_two_nlstabs (void) {
 /* Translation Hint: maximum 'AGNI' = 4 */
    Head_nlstab[EU_AGN] = _("AGNI");
    Desc_nlstab[EU_AGN] = _("Autogroup Nice Value");
+/* Translation Hint: maximum 'STARTED' = 9 */
+   Head_nlstab[EU_TM3] = _("STARTED");
+   Desc_nlstab[EU_TM3] = _("Start Time from boot");
+/* Translation Hint: maximum '%CUU' = 6 */
+   Head_nlstab[EU_CUU] = _("%CUU");
+   Desc_nlstab[EU_CUU] = _("CPU Utilization");
 }