]> granicus.if.org Git - procps-ng/commitdiff
top: parent total cpu includes collapsed children, pgm
authorJim Warner <james.warner@comcast.net>
Mon, 25 Jun 2018 05:00:00 +0000 (00:00 -0500)
committerCraig Small <csmall@enc.com.au>
Tue, 17 Jul 2018 11:00:51 +0000 (21:00 +1000)
Now, when a parent's children have been collapsed, the
cpu used by those unseen tasks will disappear no more.
Instead such tics will be added to the parent's total.

[ if one wished a return to the 'land of lost tics', ]
[ the '#define TREE_VCPUOFF' directive is available. ]

------------------------------------------------------
Note: With collapsible parents now displaying children
cpu usage, it will eventually be noticed the cpu stats
for the summary area and task areas often vary widely.

It's worth a reminder that for top's summary area each
individual cpu and the cpu summary is limited to 100%,
regardless of how many tics a linux kernel may export.

An individual task is limited to 100% times the number
of threads. But, in no case will cpu usage ever exceed
100% times total number of processors. Such limits are
further reduced under 'Solaris' mode ('I' toggle off).
In this mode, a task cpu usage will never exceed 100%.
These limits will now also apply to collapsed parents.

In addition to those influences, results are subjected
to kernel timer sampling anomalies and the distortions
inherent in a small sample size, made worse by smaller
delay intervals. Often there is just 1 or 2 tics for a
few tasks at smaller intervals such as: 1/10th second.

Anyway, should questions on this subject arise, a good
starting point, beyond the reminders above, is the 1st
link listed below. Those other links were derivatives.

Reference(s):
. from the kernel documentation
https://www.kernel.org/doc/Documentation/cpu-load.txt
. as mentioned in the above kernel documentation
https://lkml.org/lkml/2007/2/12/6
. from above, with many more links on the subject
https://www.boblycat.org/~malc/apc/

Signed-off-by: Jim Warner <james.warner@comcast.net>
top: parent total cpu includes collapsed children, pgm

top/top.c
top/top.h

index fb5ff49f70a98866084003045cd00d5be0538874..ca4b0b2c34f292194c7b921fa5fb3c76710f84eb 100644 (file)
--- a/top/top.c
+++ b/top/top.c
@@ -4684,13 +4684,16 @@ static inline int wins_usrselect (const WIN_t *q, const int idx) {
 static proc_t **Seed_ppt;                   // temporary win ppt pointer
 static proc_t **Tree_ppt;                   // forest_create will resize
 static int      Tree_idx;                   // frame_make resets to zero
-        /* those next two support collapse/expand children. the Hide_pid
+        /* the next three support collapse/expand children. the Hide_pid
            array holds parent pids whose children have been manipulated.
            positive pid values represent parents with collapsed children
            while a negative pid value means children have been expanded.
            ( both of these are managed under the 'keys_task()' routine ) */
 static int *Hide_pid;                       // collapsible process array
 static int  Hide_tot;                       // total used in above array
+#ifndef TREE_VCPUOFF
+static int *Hide_cpu;                       // accum tics from collapsed
+#endif
 
         /*
          * This little recursive guy is the real forest view workhorse.
@@ -4745,6 +4748,9 @@ static void forest_create (WIN_t *q) {
          hwmsav = Frame_maxtask;
          Tree_ppt = alloc_r(Tree_ppt, sizeof(proc_t*) * hwmsav);
          Hide_pid = alloc_r(Hide_pid, sizeof(int) * hwmsav);
+#ifndef TREE_VCPUOFF
+         Hide_cpu = alloc_r(Hide_cpu, sizeof(int) * hwmsav);
+#endif
       }
 
 #ifndef TREE_SCANALL
@@ -4754,6 +4760,9 @@ static void forest_create (WIN_t *q) {
          if (!Seed_ppt[i]->pad_3)           // real & pseudo parents == zero
             forest_adds(i, 0);              // add a parent and its children
       }
+#ifndef TREE_VCPUOFF
+      memset(Hide_cpu, 0, sizeof(int) * Frame_maxtask);
+#endif
       /* we're borrowing some pad bytes in the proc_t,
          pad_2: 'x' means a collapsed thread, 'z' means an unseen child
          pad_3: where level number is stored (0 - 100) */
@@ -4767,6 +4776,9 @@ static void forest_create (WIN_t *q) {
 
                   while (j+1 < Frame_maxtask && Tree_ppt[j+1]->pad_3 > level) {
                      Tree_ppt[j+1]->pad_2 = 'z';
+#ifndef TREE_VCPUOFF
+                     Hide_cpu[parent] += Tree_ppt[j+1]->pcpu;
+#endif
                      children = 1;
                      ++j;
                   }
@@ -5987,10 +5999,18 @@ static const char *task_show (const WIN_t *q, const int idx) {
             cp = make_num(p->processor, W, Jn, AUTOX_NO, 0);
             break;
          case EU_CPU:
-         {  float u = (float)p->pcpu * Frame_etscale;
+         {  float u = (float)p->pcpu;
+#ifndef TREE_VCPUOFF
+            // Hide_cpu entry is always zero, unless we're a collapsed parent
+            u += Hide_cpu[idx];
+            u *= Frame_etscale;
+            if (p->pad_2 != 'x' && u > 100.0 * p->nlwp) u = 100.0 * p->nlwp;
+#else
+            u *= Frame_etscale;
             /* process can't use more %cpu than number of threads it has
              ( thanks Jaromir Capik <jcapik@redhat.com> ) */
             if (u > 100.0 * p->nlwp) u = 100.0 * p->nlwp;
+#endif
             if (u > Cpu_pmax) u = Cpu_pmax;
             cp = scale_pcnt(u, W, Jn);
          }
index fbbe13312954277a31f8fb21ac49ff9e4eabe42a..d2719eb27986b8acf48f8432743aad56ab384d54 100644 (file)
--- a/top/top.h
+++ b/top/top.h
@@ -56,6 +56,7 @@
 //#define TERMIOS_ONLY            /* just limp along with native input only  */
 //#define TREE_NORESET            /* sort keys do NOT force forest view OFF  */
 //#define TREE_SCANALL            /* rescan array w/ forest view, avoid sort */
+//#define TREE_VCPUOFF            /* a collapsed parent excludes child's cpu */
 //#define TREE_VPROMPT            /* pid collapse/expand prompt, vs. top row */
 //#define TREE_VWINALL            /* pid collapse/expand impacts all windows */
 //#define USE_X_COLHDR            /* emphasize header vs. whole col, for 'x' */