summaryrefslogtreecommitdiffstats
path: root/linux
diff options
context:
space:
mode:
authorHisham Muhammad <hisham@gobolinux.org>2018-01-29 12:08:56 -0200
committerHisham Muhammad <hisham@gobolinux.org>2018-01-30 14:50:27 -0200
commitf8d6560d714c99b010aeadee09924d636c83cd02 (patch)
tree221d8a1888f69b7b4a22604a4b7fd51bcc441d41 /linux
parentfb0b5926d2e3e8002fdbddcb76a2d174da45f058 (diff)
Add IPC performance counter for Linux
Diffstat (limited to 'linux')
-rw-r--r--linux/LinuxProcess.c34
-rw-r--r--linux/LinuxProcess.h13
-rw-r--r--linux/LinuxProcessList.c31
-rw-r--r--linux/LinuxProcessList.h4
4 files changed, 80 insertions, 2 deletions
diff --git a/linux/LinuxProcess.c b/linux/LinuxProcess.c
index 32fe1212..ba42db1f 100644
--- a/linux/LinuxProcess.c
+++ b/linux/LinuxProcess.c
@@ -18,11 +18,14 @@ in the source distribution for its full text.
/*{
+#include "PerfCounter.h"
+
#define PROCESS_FLAG_LINUX_IOPRIO 0x0100
#define PROCESS_FLAG_LINUX_OPENVZ 0x0200
#define PROCESS_FLAG_LINUX_VSERVER 0x0400
#define PROCESS_FLAG_LINUX_CGROUP 0x0800
#define PROCESS_FLAG_LINUX_OOM 0x1000
+#define PROCESS_FLAG_LINUX_HPC 0x2000
typedef enum UnsupportedProcessFields {
FLAGS = 9,
@@ -86,7 +89,10 @@ typedef enum LinuxProcessFields {
PERCENT_IO_DELAY = 117,
PERCENT_SWAP_DELAY = 118,
#endif
- LAST_PROCESSFIELD = 119,
+ #ifdef HAVE_PERFCOUNTERS
+ IPC = 119,
+ #endif
+ LAST_PROCESSFIELD = 120,
} LinuxProcessField;
#include "IOPriority.h"
@@ -139,6 +145,11 @@ typedef struct LinuxProcess_ {
float blkio_delay_percent;
float swapin_delay_percent;
#endif
+ #ifdef HAVE_PERFCOUNTERS
+ PerfCounter* cycleCounter;
+ PerfCounter* insnCounter;
+ double ipc;
+ #endif
} LinuxProcess;
#ifndef Process_isKernelThread
@@ -234,6 +245,9 @@ ProcessFieldData Process_fields[] = {
[PERCENT_IO_DELAY] = { .name = "PERCENT_IO_DELAY", .title = "IOD% ", .description = "Block I/O delay %", .flags = 0, },
[PERCENT_SWAP_DELAY] = { .name = "PERCENT_SWAP_DELAY", .title = "SWAPD% ", .description = "Swapin delay %", .flags = 0, },
#endif
+#ifdef HAVE_PERFCOUNTERS
+ [IPC] = { .name = "IPC", .title = " IPC ", .description = "Executed instructions per cycle", .flags = PROCESS_FLAG_LINUX_HPC, },
+#endif
[LAST_PROCESSFIELD] = { .name = "*** report bug! ***", .title = NULL, .description = NULL, .flags = 0, },
};
@@ -274,6 +288,10 @@ void Process_delete(Object* cast) {
#ifdef HAVE_CGROUP
free(this->cgroup);
#endif
+#ifdef HAVE_PERFCOUNTERS
+ PerfCounter_delete(this->cycleCounter);
+ PerfCounter_delete(this->insnCounter);
+#endif
free(this->ttyDevice);
free(this);
}
@@ -394,6 +412,16 @@ void LinuxProcess_writeField(Process* this, RichString* str, ProcessField field)
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;
#endif
+ #ifdef HAVE_PERFCOUNTERS
+ case IPC: {
+ if (lp->ipc == -1) {
+ attr = CRT_colors[PROCESS_SHADOW];
+ xSnprintf(buffer, n, " N/A "); break;
+ } else {
+ xSnprintf(buffer, n, "%5.2f ", lp->ipc); break;
+ }
+ }
+ #endif
default:
Process_writeField((Process*)this, str, field);
return;
@@ -463,6 +491,10 @@ long LinuxProcess_compare(const void* v1, const void* v2) {
case PERCENT_SWAP_DELAY:
return (p2->swapin_delay_percent > p1->swapin_delay_percent ? 1 : -1);
#endif
+ #ifdef HAVE_PERFCOUNTERS
+ case IPC:
+ return (p2->ipc > p1->ipc ? 1 : -1);
+ #endif
case IO_PRIORITY:
return LinuxProcess_effectiveIOPriority(p1) - LinuxProcess_effectiveIOPriority(p2);
default:
diff --git a/linux/LinuxProcess.h b/linux/LinuxProcess.h
index 5995dafb..ca22bdda 100644
--- a/linux/LinuxProcess.h
+++ b/linux/LinuxProcess.h
@@ -10,11 +10,14 @@ in the source distribution for its full text.
*/
+#include "PerfCounter.h"
+
#define PROCESS_FLAG_LINUX_IOPRIO 0x0100
#define PROCESS_FLAG_LINUX_OPENVZ 0x0200
#define PROCESS_FLAG_LINUX_VSERVER 0x0400
#define PROCESS_FLAG_LINUX_CGROUP 0x0800
#define PROCESS_FLAG_LINUX_OOM 0x1000
+#define PROCESS_FLAG_LINUX_HPC 0x2000
typedef enum UnsupportedProcessFields {
FLAGS = 9,
@@ -78,7 +81,10 @@ typedef enum LinuxProcessFields {
PERCENT_IO_DELAY = 117,
PERCENT_SWAP_DELAY = 118,
#endif
- LAST_PROCESSFIELD = 119,
+ #ifdef HAVE_PERFCOUNTERS
+ IPC = 119,
+ #endif
+ LAST_PROCESSFIELD = 120,
} LinuxProcessField;
#include "IOPriority.h"
@@ -131,6 +137,11 @@ typedef struct LinuxProcess_ {
float blkio_delay_percent;
float swapin_delay_percent;
#endif
+ #ifdef HAVE_PERFCOUNTERS
+ PerfCounter* cycleCounter;
+ PerfCounter* insnCounter;
+ double ipc;
+ #endif
} LinuxProcess;
#ifndef Process_isKernelThread
diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c
index 753a478e..bba611f0 100644
--- a/linux/LinuxProcessList.c
+++ b/linux/LinuxProcessList.c
@@ -660,6 +660,32 @@ static void LinuxProcessList_readDelayAcctData(LinuxProcessList* this, LinuxProc
#endif
+#ifdef HAVE_PERFCOUNTERS
+
+static void LinuxProcessList_readPerfCounters(LinuxProcess* lp) {
+ if (!lp->cycleCounter) {
+ lp->cycleCounter = PerfCounter_new(lp->super.pid, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES);
+ }
+ if (!lp->insnCounter) {
+ lp->insnCounter = PerfCounter_new(lp->super.pid, PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS);
+ }
+ bool cOk = PerfCounter_read(lp->cycleCounter);
+ bool iOk = PerfCounter_read(lp->insnCounter);
+ if (cOk && iOk) {
+ uint64_t i = PerfCounter_delta(lp->insnCounter);
+ uint64_t c = PerfCounter_delta(lp->cycleCounter);
+ if (c > 0) {
+ lp->ipc = (double)i / c;
+ } else {
+ lp->ipc = 0;
+ }
+ } else {
+ lp->ipc = -1;
+ }
+}
+
+#endif
+
static void setCommand(Process* process, const char* command, int len) {
if (process->comm && process->commLen >= len) {
strncpy(process->comm, command, len + 1);
@@ -871,6 +897,11 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, const char*
if (ss->flags & PROCESS_FLAG_LINUX_OOM)
LinuxProcessList_readOomData(lp, dirname, name);
+ #ifdef HAVE_PERFCOUNTERS
+ if (ss->flags & PROCESS_FLAG_LINUX_HPC)
+ LinuxProcessList_readPerfCounters(lp);
+ #endif
+
if (proc->state == 'Z' && (proc->basenameOffset == 0)) {
proc->basenameOffset = -1;
setCommand(proc, command, commLen);
diff --git a/linux/LinuxProcessList.h b/linux/LinuxProcessList.h
index 5005220a..06447713 100644
--- a/linux/LinuxProcessList.h
+++ b/linux/LinuxProcessList.h
@@ -116,6 +116,10 @@ void ProcessList_delete(ProcessList* pl);
#endif
+#ifdef HAVE_PERFCOUNTERS
+
+#endif
+
void ProcessList_goThroughEntries(ProcessList* super);
#endif

© 2014-2024 Faster IT GmbH | imprint | privacy policy