top: parent total cpu includes collapsed children, pgm

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
This commit is contained in:
Jim Warner 2018-06-25 00:00:00 -05:00 committed by Craig Small
parent e66c36794a
commit 3da7318683
2 changed files with 23 additions and 2 deletions

View File

@ -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 **Seed_ppt; // temporary win ppt pointer
static proc_t **Tree_ppt; // forest_create will resize static proc_t **Tree_ppt; // forest_create will resize
static int Tree_idx; // frame_make resets to zero 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. array holds parent pids whose children have been manipulated.
positive pid values represent parents with collapsed children positive pid values represent parents with collapsed children
while a negative pid value means children have been expanded. while a negative pid value means children have been expanded.
( both of these are managed under the 'keys_task()' routine ) */ ( both of these are managed under the 'keys_task()' routine ) */
static int *Hide_pid; // collapsible process array static int *Hide_pid; // collapsible process array
static int Hide_tot; // total used in above 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. * This little recursive guy is the real forest view workhorse.
@ -4745,6 +4748,9 @@ static void forest_create (WIN_t *q) {
hwmsav = Frame_maxtask; hwmsav = Frame_maxtask;
Tree_ppt = alloc_r(Tree_ppt, sizeof(proc_t*) * hwmsav); Tree_ppt = alloc_r(Tree_ppt, sizeof(proc_t*) * hwmsav);
Hide_pid = alloc_r(Hide_pid, sizeof(int) * 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 #ifndef TREE_SCANALL
@ -4754,6 +4760,9 @@ static void forest_create (WIN_t *q) {
if (!Seed_ppt[i]->pad_3) // real & pseudo parents == zero if (!Seed_ppt[i]->pad_3) // real & pseudo parents == zero
forest_adds(i, 0); // add a parent and its children 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, /* we're borrowing some pad bytes in the proc_t,
pad_2: 'x' means a collapsed thread, 'z' means an unseen child pad_2: 'x' means a collapsed thread, 'z' means an unseen child
pad_3: where level number is stored (0 - 100) */ 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) { while (j+1 < Frame_maxtask && Tree_ppt[j+1]->pad_3 > level) {
Tree_ppt[j+1]->pad_2 = 'z'; Tree_ppt[j+1]->pad_2 = 'z';
#ifndef TREE_VCPUOFF
Hide_cpu[parent] += Tree_ppt[j+1]->pcpu;
#endif
children = 1; children = 1;
++j; ++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); cp = make_num(p->processor, W, Jn, AUTOX_NO, 0);
break; break;
case EU_CPU: 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 /* process can't use more %cpu than number of threads it has
( thanks Jaromir Capik <jcapik@redhat.com> ) */ ( thanks Jaromir Capik <jcapik@redhat.com> ) */
if (u > 100.0 * p->nlwp) u = 100.0 * p->nlwp; if (u > 100.0 * p->nlwp) u = 100.0 * p->nlwp;
#endif
if (u > Cpu_pmax) u = Cpu_pmax; if (u > Cpu_pmax) u = Cpu_pmax;
cp = scale_pcnt(u, W, Jn); cp = scale_pcnt(u, W, Jn);
} }

View File

@ -56,6 +56,7 @@
//#define TERMIOS_ONLY /* just limp along with native input only */ //#define TERMIOS_ONLY /* just limp along with native input only */
//#define TREE_NORESET /* sort keys do NOT force forest view OFF */ //#define TREE_NORESET /* sort keys do NOT force forest view OFF */
//#define TREE_SCANALL /* rescan array w/ forest view, avoid sort */ //#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_VPROMPT /* pid collapse/expand prompt, vs. top row */
//#define TREE_VWINALL /* pid collapse/expand impacts all windows */ //#define TREE_VWINALL /* pid collapse/expand impacts all windows */
//#define USE_X_COLHDR /* emphasize header vs. whole col, for 'x' */ //#define USE_X_COLHDR /* emphasize header vs. whole col, for 'x' */