Add Linux process column for context switches

Displays the incremental sum of voluntary_ctxt_switches and nonvoluntary_ctxt_switches.
This commit is contained in:
Christian Göttsche 2020-09-11 15:02:00 +02:00 committed by cgzones
parent ffc65b3827
commit 98ee833932
4 changed files with 45 additions and 1 deletions

View File

@ -386,6 +386,9 @@ Which cgroup the process is in.
.B OOM .B OOM
OOM killer score. OOM killer score.
.TP .TP
.B CTXT
Incremental sum of voluntary and nonvoluntary context switches.
.TP
.B IO_PRIORITY (IO) .B IO_PRIORITY (IO)
The I/O scheduling class followed by the priority if the class supports it: The I/O scheduling class followed by the priority if the class supports it:
\fBR\fR for Realtime \fBR\fR for Realtime

View File

@ -107,6 +107,7 @@ ProcessFieldData Process_fields[] = {
[M_PSS] = { .name = "M_PSS", .title = " PSS ", .description = "proportional set size, same as M_RESIDENT but each page is divided by the number of processes sharing it.", .flags = PROCESS_FLAG_LINUX_SMAPS, }, [M_PSS] = { .name = "M_PSS", .title = " PSS ", .description = "proportional set size, same as M_RESIDENT but each page is divided by the number of processes sharing it.", .flags = PROCESS_FLAG_LINUX_SMAPS, },
[M_SWAP] = { .name = "M_SWAP", .title = " SWAP ", .description = "Size of the process's swapped pages", .flags = PROCESS_FLAG_LINUX_SMAPS, }, [M_SWAP] = { .name = "M_SWAP", .title = " SWAP ", .description = "Size of the process's swapped pages", .flags = PROCESS_FLAG_LINUX_SMAPS, },
[M_PSSWP] = { .name = "M_PSSWP", .title = " PSSWP ", .description = "shows proportional swap share of this mapping, Unlike \"Swap\", this does not take into account swapped out page of underlying shmem objects.", .flags = PROCESS_FLAG_LINUX_SMAPS, }, [M_PSSWP] = { .name = "M_PSSWP", .title = " PSSWP ", .description = "shows proportional swap share of this mapping, Unlike \"Swap\", this does not take into account swapped out page of underlying shmem objects.", .flags = PROCESS_FLAG_LINUX_SMAPS, },
[CTXT] = { .name = "CTXT", .title = " CTXT ", .description = "Context switches (incremental sum of voluntary_ctxt_switches and nonvoluntary_ctxt_switches)", .flags = PROCESS_FLAG_LINUX_CTXT, },
[LAST_PROCESSFIELD] = { .name = "*** report bug! ***", .title = NULL, .description = NULL, .flags = 0, }, [LAST_PROCESSFIELD] = { .name = "*** report bug! ***", .title = NULL, .description = NULL, .flags = 0, },
}; };
@ -276,6 +277,11 @@ void LinuxProcess_writeField(Process* this, RichString* str, ProcessField field)
case PERCENT_IO_DELAY: LinuxProcess_printDelay(lp->blkio_delay_percent, buffer, n); break; case PERCENT_IO_DELAY: LinuxProcess_printDelay(lp->blkio_delay_percent, buffer, n); break;
case PERCENT_SWAP_DELAY: LinuxProcess_printDelay(lp->swapin_delay_percent, buffer, n); break; case PERCENT_SWAP_DELAY: LinuxProcess_printDelay(lp->swapin_delay_percent, buffer, n); break;
#endif #endif
case CTXT:
if (lp->ctxt_diff > 1000)
attr |= A_BOLD;
xSnprintf(buffer, n, "%5lu ", lp->ctxt_diff);
break;
default: default:
Process_writeField((Process*)this, str, field); Process_writeField((Process*)this, str, field);
return; return;
@ -359,6 +365,8 @@ long LinuxProcess_compare(const void* v1, const void* v2) {
#endif #endif
case IO_PRIORITY: case IO_PRIORITY:
return LinuxProcess_effectiveIOPriority(p1) - LinuxProcess_effectiveIOPriority(p2); return LinuxProcess_effectiveIOPriority(p1) - LinuxProcess_effectiveIOPriority(p2);
case CTXT:
return ((long)p2->ctxt_diff - (long)p1->ctxt_diff);
default: default:
return Process_compare(v1, v2); return Process_compare(v1, v2);
} }

View File

@ -14,6 +14,7 @@ in the source distribution for its full text.
#define PROCESS_FLAG_LINUX_CGROUP 0x0800 #define PROCESS_FLAG_LINUX_CGROUP 0x0800
#define PROCESS_FLAG_LINUX_OOM 0x1000 #define PROCESS_FLAG_LINUX_OOM 0x1000
#define PROCESS_FLAG_LINUX_SMAPS 0x2000 #define PROCESS_FLAG_LINUX_SMAPS 0x2000
#define PROCESS_FLAG_LINUX_CTXT 0x4000
typedef enum UnsupportedProcessFields { typedef enum UnsupportedProcessFields {
FLAGS = 9, FLAGS = 9,
@ -80,7 +81,8 @@ typedef enum LinuxProcessFields {
M_PSS = 119, M_PSS = 119,
M_SWAP = 120, M_SWAP = 120,
M_PSSWP = 121, M_PSSWP = 121,
LAST_PROCESSFIELD = 122, CTXT = 122,
LAST_PROCESSFIELD = 123,
} LinuxProcessField; } LinuxProcessField;
#include "IOPriority.h" #include "IOPriority.h"
@ -138,6 +140,8 @@ typedef struct LinuxProcess_ {
float blkio_delay_percent; float blkio_delay_percent;
float swapin_delay_percent; float swapin_delay_percent;
#endif #endif
unsigned long ctxt_total;
unsigned long ctxt_diff;
} LinuxProcess; } LinuxProcess;
#define Process_isKernelThread(_process) (((LinuxProcess*)(_process))->isKernelThread) #define Process_isKernelThread(_process) (((LinuxProcess*)(_process))->isKernelThread)

View File

@ -588,6 +588,32 @@ static void LinuxProcessList_readOomData(LinuxProcess* process, const char* dirn
fclose(file); fclose(file);
} }
static void LinuxProcessList_readCtxtData(LinuxProcess* process, const char* dirname, const char* name) {
char filename[MAX_NAME+1];
xSnprintf(filename, MAX_NAME, "%s/%s/status", dirname, name);
FILE* file = fopen(filename, "r");
if (!file)
return;
char buffer[PROC_LINE_LENGTH + 1];
unsigned long ctxt = 0;
while (fgets(buffer, PROC_LINE_LENGTH, file)) {
if (String_startsWith(buffer, "voluntary_ctxt_switches:")) {
unsigned long vctxt;
int ok = sscanf(buffer, "voluntary_ctxt_switches:\t%lu", &vctxt);
if (ok >= 1)
ctxt += vctxt;
} else if (String_startsWith(buffer, "nonvoluntary_ctxt_switches:")) {
unsigned long nvctxt;
int ok = sscanf(buffer, "nonvoluntary_ctxt_switches:\t%lu", &nvctxt);
if (ok >= 1)
ctxt += nvctxt;
}
}
fclose(file);
process->ctxt_diff = (ctxt > process->ctxt_total) ? (ctxt - process->ctxt_total) : 0;
process->ctxt_total = ctxt;
}
#ifdef HAVE_DELAYACCT #ifdef HAVE_DELAYACCT
static int handleNetlinkMsg(struct nl_msg *nlmsg, void *linuxProcess) { static int handleNetlinkMsg(struct nl_msg *nlmsg, void *linuxProcess) {
@ -885,6 +911,9 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, const char*
if (settings->flags & PROCESS_FLAG_LINUX_OOM) if (settings->flags & PROCESS_FLAG_LINUX_OOM)
LinuxProcessList_readOomData(lp, dirname, name); LinuxProcessList_readOomData(lp, dirname, name);
if (settings->flags & PROCESS_FLAG_LINUX_CTXT)
LinuxProcessList_readCtxtData(lp, dirname, name);
if (proc->state == 'Z' && (proc->basenameOffset == 0)) { if (proc->state == 'Z' && (proc->basenameOffset == 0)) {
proc->basenameOffset = -1; proc->basenameOffset = -1;
setCommand(proc, command, commLen); setCommand(proc, command, commLen);