mirror of https://github.com/xzeldon/htop.git
PCP: PCPMetric.[ch] Mdoule
Split the PCP Metric API (functions `Metric_*`) into their own module. as @BenBE suggested.
This commit is contained in:
parent
edafa26f9e
commit
fefff80631
|
@ -366,6 +366,7 @@ pcp_platform_headers = \
|
||||||
linux/ZramStats.h \
|
linux/ZramStats.h \
|
||||||
pcp/PCPDynamicColumn.h \
|
pcp/PCPDynamicColumn.h \
|
||||||
pcp/PCPDynamicMeter.h \
|
pcp/PCPDynamicMeter.h \
|
||||||
|
pcp/PCPMetric.h \
|
||||||
pcp/PCPProcess.h \
|
pcp/PCPProcess.h \
|
||||||
pcp/PCPProcessList.h \
|
pcp/PCPProcessList.h \
|
||||||
pcp/Platform.h \
|
pcp/Platform.h \
|
||||||
|
@ -379,6 +380,7 @@ pcp_platform_sources = \
|
||||||
linux/ZramMeter.c \
|
linux/ZramMeter.c \
|
||||||
pcp/PCPDynamicColumn.c \
|
pcp/PCPDynamicColumn.c \
|
||||||
pcp/PCPDynamicMeter.c \
|
pcp/PCPDynamicMeter.c \
|
||||||
|
pcp/PCPMetric.c \
|
||||||
pcp/PCPProcess.c \
|
pcp/PCPProcess.c \
|
||||||
pcp/PCPProcessList.c \
|
pcp/PCPProcessList.c \
|
||||||
pcp/Platform.c \
|
pcp/Platform.c \
|
||||||
|
|
|
@ -14,21 +14,21 @@ in the source distribution for its full text.
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <limits.h>
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "CRT.h"
|
#include "CRT.h"
|
||||||
#include "Macros.h"
|
#include "Macros.h"
|
||||||
#include "Platform.h"
|
#include "Platform.h"
|
||||||
#include "Process.h"
|
#include "Process.h"
|
||||||
|
#include "ProcessList.h"
|
||||||
#include "RichString.h"
|
#include "RichString.h"
|
||||||
#include "XUtils.h"
|
#include "XUtils.h"
|
||||||
|
|
||||||
#include "pcp/PCPProcess.h"
|
#include "pcp/PCPProcess.h"
|
||||||
|
#include "pcp/PCPMetric.h"
|
||||||
|
|
||||||
|
|
||||||
static bool PCPDynamicColumn_addMetric(PCPDynamicColumns* columns, PCPDynamicColumn* column) {
|
static bool PCPDynamicColumn_addMetric(PCPDynamicColumns* columns, PCPDynamicColumn* column) {
|
||||||
|
@ -228,10 +228,10 @@ void PCPDynamicColumns_init(PCPDynamicColumns* columns) {
|
||||||
|
|
||||||
void PCPDynamicColumn_writeField(PCPDynamicColumn* this, const Process* proc, RichString* str) {
|
void PCPDynamicColumn_writeField(PCPDynamicColumn* this, const Process* proc, RichString* str) {
|
||||||
const PCPProcess* pp = (const PCPProcess*) proc;
|
const PCPProcess* pp = (const PCPProcess*) proc;
|
||||||
unsigned int type = Metric_type(this->id);
|
unsigned int type = PCPMetric_type(this->id);
|
||||||
|
|
||||||
pmAtomValue atom;
|
pmAtomValue atom;
|
||||||
if (!Metric_instance(this->id, proc->pid, pp->offset, &atom, type)) {
|
if (!PCPMetric_instance(this->id, proc->pid, pp->offset, &atom, type)) {
|
||||||
RichString_appendAscii(str, CRT_colors[METER_VALUE_ERROR], "no data");
|
RichString_appendAscii(str, CRT_colors[METER_VALUE_ERROR], "no data");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -288,11 +288,11 @@ int PCPDynamicColumn_compareByKey(const PCPProcess* p1, const PCPProcess* p2, Pr
|
||||||
const PCPDynamicColumn* column = Hashtable_get(p1->super.processList->dynamicColumns, key);
|
const PCPDynamicColumn* column = Hashtable_get(p1->super.processList->dynamicColumns, key);
|
||||||
|
|
||||||
size_t metric = column->id;
|
size_t metric = column->id;
|
||||||
unsigned int type = Metric_type(metric);
|
unsigned int type = PCPMetric_type(metric);
|
||||||
|
|
||||||
pmAtomValue atom1 = {0}, atom2 = {0};
|
pmAtomValue atom1 = {0}, atom2 = {0};
|
||||||
if (!Metric_instance(metric, p1->super.pid, p1->offset, &atom1, type) ||
|
if (!PCPMetric_instance(metric, p1->super.pid, p1->offset, &atom1, type) ||
|
||||||
!Metric_instance(metric, p2->super.pid, p2->offset, &atom2, type)) {
|
!PCPMetric_instance(metric, p2->super.pid, p2->offset, &atom2, type)) {
|
||||||
if (type == PM_TYPE_STRING) {
|
if (type == PM_TYPE_STRING) {
|
||||||
free(atom1.cp);
|
free(atom1.cp);
|
||||||
free(atom2.cp);
|
free(atom2.cp);
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
#ifndef HEADER_PCPDynamicColumn
|
#ifndef HEADER_PCPDynamicColumn
|
||||||
#define HEADER_PCPDynamicColumn
|
#define HEADER_PCPDynamicColumn
|
||||||
|
|
||||||
#include "CRT.h"
|
#include <stddef.h>
|
||||||
|
|
||||||
#include "DynamicColumn.h"
|
#include "DynamicColumn.h"
|
||||||
#include "Hashtable.h"
|
#include "Hashtable.h"
|
||||||
#include "Process.h"
|
#include "Process.h"
|
||||||
|
|
|
@ -9,15 +9,22 @@ in the source distribution for its full text.
|
||||||
|
|
||||||
#include "pcp/PCPDynamicMeter.h"
|
#include "pcp/PCPDynamicMeter.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <ctype.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pcp/pmapi.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "Object.h"
|
#include "Macros.h"
|
||||||
#include "Platform.h"
|
#include "Platform.h"
|
||||||
#include "ProcessList.h"
|
|
||||||
#include "RichString.h"
|
#include "RichString.h"
|
||||||
#include "Settings.h"
|
|
||||||
#include "XUtils.h"
|
#include "XUtils.h"
|
||||||
|
|
||||||
|
#include "pcp/PCPMetric.h"
|
||||||
|
|
||||||
|
|
||||||
static PCPDynamicMetric* PCPDynamicMeter_lookupMetric(PCPDynamicMeters* meters, PCPDynamicMeter* meter, const char* name) {
|
static PCPDynamicMetric* PCPDynamicMeter_lookupMetric(PCPDynamicMeters* meters, PCPDynamicMeter* meter, const char* name) {
|
||||||
size_t bytes = 16 + strlen(meter->super.name) + strlen(name);
|
size_t bytes = 16 + strlen(meter->super.name) + strlen(name);
|
||||||
|
@ -278,7 +285,7 @@ void PCPDynamicMeters_init(PCPDynamicMeters* meters) {
|
||||||
|
|
||||||
void PCPDynamicMeter_enable(PCPDynamicMeter* this) {
|
void PCPDynamicMeter_enable(PCPDynamicMeter* this) {
|
||||||
for (size_t i = 0; i < this->totalMetrics; i++)
|
for (size_t i = 0; i < this->totalMetrics; i++)
|
||||||
Metric_enable(this->metrics[i].id, true);
|
PCPMetric_enable(this->metrics[i].id, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PCPDynamicMeter_updateValues(PCPDynamicMeter* this, Meter* meter) {
|
void PCPDynamicMeter_updateValues(PCPDynamicMeter* this, Meter* meter) {
|
||||||
|
@ -291,10 +298,10 @@ void PCPDynamicMeter_updateValues(PCPDynamicMeter* this, Meter* meter) {
|
||||||
buffer[bytes++] = '/'; /* separator */
|
buffer[bytes++] = '/'; /* separator */
|
||||||
|
|
||||||
PCPDynamicMetric* metric = &this->metrics[i];
|
PCPDynamicMetric* metric = &this->metrics[i];
|
||||||
const pmDesc* desc = Metric_desc(metric->id);
|
const pmDesc* desc = PCPMetric_desc(metric->id);
|
||||||
pmAtomValue atom, raw;
|
pmAtomValue atom, raw;
|
||||||
|
|
||||||
if (!Metric_values(metric->id, &raw, 1, desc->type)) {
|
if (!PCPMetric_values(metric->id, &raw, 1, desc->type)) {
|
||||||
bytes--; /* clear the separator */
|
bytes--; /* clear the separator */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -362,11 +369,11 @@ void PCPDynamicMeter_display(PCPDynamicMeter* this, ATTR_UNUSED const Meter* met
|
||||||
|
|
||||||
for (size_t i = 0; i < this->totalMetrics; i++) {
|
for (size_t i = 0; i < this->totalMetrics; i++) {
|
||||||
PCPDynamicMetric* metric = &this->metrics[i];
|
PCPDynamicMetric* metric = &this->metrics[i];
|
||||||
const pmDesc* desc = Metric_desc(metric->id);
|
const pmDesc* desc = PCPMetric_desc(metric->id);
|
||||||
pmAtomValue atom, raw;
|
pmAtomValue atom, raw;
|
||||||
char buffer[64];
|
char buffer[64];
|
||||||
|
|
||||||
if (!Metric_values(metric->id, &raw, 1, desc->type))
|
if (!PCPMetric_values(metric->id, &raw, 1, desc->type))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
pmUnits conv = desc->units; /* convert to canonical units */
|
pmUnits conv = desc->units; /* convert to canonical units */
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
#ifndef HEADER_PCPDynamicMeter
|
#ifndef HEADER_PCPDynamicMeter
|
||||||
#define HEADER_PCPDynamicMeter
|
#define HEADER_PCPDynamicMeter
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
#include "CRT.h"
|
#include "CRT.h"
|
||||||
#include "DynamicMeter.h"
|
#include "DynamicMeter.h"
|
||||||
|
#include "Hashtable.h"
|
||||||
|
#include "Meter.h"
|
||||||
|
#include "RichString.h"
|
||||||
|
|
||||||
|
|
||||||
typedef struct PCPDynamicMetric_ {
|
typedef struct PCPDynamicMetric_ {
|
||||||
|
|
|
@ -0,0 +1,177 @@
|
||||||
|
/*
|
||||||
|
htop - PCPMetric.c
|
||||||
|
(C) 2020-2021 htop dev team
|
||||||
|
(C) 2020-2021 Red Hat, Inc.
|
||||||
|
Released under the GNU GPLv2, see the COPYING file
|
||||||
|
in the source distribution for its full text.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h" // IWYU pragma: keep
|
||||||
|
|
||||||
|
#include "pcp/PCPMetric.h"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "XUtils.h"
|
||||||
|
|
||||||
|
#include "pcp/Platform.h"
|
||||||
|
|
||||||
|
|
||||||
|
extern Platform* pcp;
|
||||||
|
|
||||||
|
const pmDesc* PCPMetric_desc(PCPMetric metric) {
|
||||||
|
return &pcp->descs[metric];
|
||||||
|
}
|
||||||
|
|
||||||
|
int PCPMetric_type(PCPMetric metric) {
|
||||||
|
return pcp->descs[metric].type;
|
||||||
|
}
|
||||||
|
|
||||||
|
pmAtomValue* PCPMetric_values(PCPMetric metric, pmAtomValue* atom, int count, int type) {
|
||||||
|
if (pcp->result == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
pmValueSet* vset = pcp->result->vset[metric];
|
||||||
|
if (!vset || vset->numval <= 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* extract requested number of values as requested type */
|
||||||
|
const pmDesc* desc = &pcp->descs[metric];
|
||||||
|
for (int i = 0; i < vset->numval; i++) {
|
||||||
|
if (i == count)
|
||||||
|
break;
|
||||||
|
const pmValue* value = &vset->vlist[i];
|
||||||
|
int sts = pmExtractValue(vset->valfmt, value, desc->type, &atom[i], type);
|
||||||
|
if (sts < 0) {
|
||||||
|
if (pmDebugOptions.appl0)
|
||||||
|
fprintf(stderr, "Error: cannot extract metric value: %s\n",
|
||||||
|
pmErrStr(sts));
|
||||||
|
memset(&atom[i], 0, sizeof(pmAtomValue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return atom;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PCPMetric_instanceCount(PCPMetric metric) {
|
||||||
|
pmValueSet* vset = pcp->result->vset[metric];
|
||||||
|
if (vset)
|
||||||
|
return vset->numval;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PCPMetric_instanceOffset(PCPMetric metric, int inst) {
|
||||||
|
pmValueSet* vset = pcp->result->vset[metric];
|
||||||
|
if (!vset || vset->numval <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* search for optimal offset for subsequent inst lookups to begin */
|
||||||
|
for (int i = 0; i < vset->numval; i++) {
|
||||||
|
if (inst == vset->vlist[i].inst)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static pmAtomValue* PCPMetric_extract(PCPMetric metric, int inst, int offset, pmValueSet* vset, pmAtomValue* atom, int type) {
|
||||||
|
|
||||||
|
/* extract value (using requested type) of given metric instance */
|
||||||
|
const pmDesc* desc = &pcp->descs[metric];
|
||||||
|
const pmValue* value = &vset->vlist[offset];
|
||||||
|
int sts = pmExtractValue(vset->valfmt, value, desc->type, atom, type);
|
||||||
|
if (sts < 0) {
|
||||||
|
if (pmDebugOptions.appl0)
|
||||||
|
fprintf(stderr, "Error: cannot extract %s instance %d value: %s\n",
|
||||||
|
pcp->names[metric], inst, pmErrStr(sts));
|
||||||
|
memset(atom, 0, sizeof(pmAtomValue));
|
||||||
|
}
|
||||||
|
return atom;
|
||||||
|
}
|
||||||
|
|
||||||
|
pmAtomValue* PCPMetric_instance(PCPMetric metric, int inst, int offset, pmAtomValue* atom, int type) {
|
||||||
|
|
||||||
|
pmValueSet* vset = pcp->result->vset[metric];
|
||||||
|
if (!vset || vset->numval <= 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* fast-path using heuristic offset based on expected location */
|
||||||
|
if (offset >= 0 && offset < vset->numval && inst == vset->vlist[offset].inst)
|
||||||
|
return PCPMetric_extract(metric, inst, offset, vset, atom, type);
|
||||||
|
|
||||||
|
/* slow-path using a linear search for the requested instance */
|
||||||
|
for (int i = 0; i < vset->numval; i++) {
|
||||||
|
if (inst == vset->vlist[i].inst)
|
||||||
|
return PCPMetric_extract(metric, inst, i, vset, atom, type);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Iterate over a set of instances (incl PM_IN_NULL)
|
||||||
|
* returning the next instance identifier and offset.
|
||||||
|
*
|
||||||
|
* Start it off by passing offset -1 into the routine.
|
||||||
|
*/
|
||||||
|
bool PCPMetric_iterate(PCPMetric metric, int* instp, int* offsetp) {
|
||||||
|
if (!pcp->result)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
pmValueSet* vset = pcp->result->vset[metric];
|
||||||
|
if (!vset || vset->numval <= 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int offset = *offsetp;
|
||||||
|
offset = (offset < 0) ? 0 : offset + 1;
|
||||||
|
if (offset > vset->numval - 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*offsetp = offset;
|
||||||
|
*instp = vset->vlist[offset].inst;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Switch on/off a metric for value fetching (sampling) */
|
||||||
|
void PCPMetric_enable(PCPMetric metric, bool enable) {
|
||||||
|
pcp->fetch[metric] = enable ? pcp->pmids[metric] : PM_ID_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PCPMetric_enabled(PCPMetric metric) {
|
||||||
|
return pcp->fetch[metric] != PM_ID_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PCPMetric_enableThreads(void) {
|
||||||
|
pmValueSet* vset = xCalloc(1, sizeof(pmValueSet));
|
||||||
|
vset->vlist[0].inst = PM_IN_NULL;
|
||||||
|
vset->vlist[0].value.lval = 1;
|
||||||
|
vset->valfmt = PM_VAL_INSITU;
|
||||||
|
vset->numval = 1;
|
||||||
|
vset->pmid = pcp->pmids[PCP_CONTROL_THREADS];
|
||||||
|
|
||||||
|
pmResult* result = xCalloc(1, sizeof(pmResult));
|
||||||
|
result->vset[0] = vset;
|
||||||
|
result->numpmid = 1;
|
||||||
|
|
||||||
|
int sts = pmStore(result);
|
||||||
|
if (sts < 0 && pmDebugOptions.appl0)
|
||||||
|
fprintf(stderr, "Error: cannot enable threads: %s\n", pmErrStr(sts));
|
||||||
|
|
||||||
|
pmFreeResult(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PCPMetric_fetch(struct timeval* timestamp) {
|
||||||
|
if (pcp->result) {
|
||||||
|
pmFreeResult(pcp->result);
|
||||||
|
pcp->result = NULL;
|
||||||
|
}
|
||||||
|
int sts = pmFetch(pcp->totalMetrics, pcp->fetch, &pcp->result);
|
||||||
|
if (sts < 0) {
|
||||||
|
if (pmDebugOptions.appl0)
|
||||||
|
fprintf(stderr, "Error: cannot fetch metric values: %s\n",
|
||||||
|
pmErrStr(sts));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (timestamp)
|
||||||
|
*timestamp = pcp->result->timestamp;
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -0,0 +1,179 @@
|
||||||
|
#ifndef HEADER_PCPMetric
|
||||||
|
#define HEADER_PCPMetric
|
||||||
|
/*
|
||||||
|
htop - PCPMetric.h
|
||||||
|
(C) 2020-2021 htop dev team
|
||||||
|
(C) 2020-2021 Red Hat, Inc.
|
||||||
|
Released under the GNU GPLv2, see the COPYING file
|
||||||
|
in the source distribution for its full text.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <pcp/pmapi.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
/* use htop config.h values for these macros, not pcp values */
|
||||||
|
#undef PACKAGE_URL
|
||||||
|
#undef PACKAGE_NAME
|
||||||
|
#undef PACKAGE_STRING
|
||||||
|
#undef PACKAGE_TARNAME
|
||||||
|
#undef PACKAGE_VERSION
|
||||||
|
#undef PACKAGE_BUGREPORT
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum PCPMetric_ {
|
||||||
|
PCP_CONTROL_THREADS, /* proc.control.perclient.threads */
|
||||||
|
|
||||||
|
PCP_HINV_NCPU, /* hinv.ncpu */
|
||||||
|
PCP_HINV_CPUCLOCK, /* hinv.cpu.clock */
|
||||||
|
PCP_UNAME_SYSNAME, /* kernel.uname.sysname */
|
||||||
|
PCP_UNAME_RELEASE, /* kernel.uname.release */
|
||||||
|
PCP_UNAME_MACHINE, /* kernel.uname.machine */
|
||||||
|
PCP_UNAME_DISTRO, /* kernel.uname.distro */
|
||||||
|
PCP_LOAD_AVERAGE, /* kernel.all.load */
|
||||||
|
PCP_PID_MAX, /* kernel.all.pid_max */
|
||||||
|
PCP_UPTIME, /* kernel.all.uptime */
|
||||||
|
PCP_BOOTTIME, /* kernel.all.boottime */
|
||||||
|
PCP_CPU_USER, /* kernel.all.cpu.user */
|
||||||
|
PCP_CPU_NICE, /* kernel.all.cpu.nice */
|
||||||
|
PCP_CPU_SYSTEM, /* kernel.all.cpu.sys */
|
||||||
|
PCP_CPU_IDLE, /* kernel.all.cpu.idle */
|
||||||
|
PCP_CPU_IOWAIT, /* kernel.all.cpu.wait.total */
|
||||||
|
PCP_CPU_IRQ, /* kernel.all.cpu.intr */
|
||||||
|
PCP_CPU_SOFTIRQ, /* kernel.all.cpu.irq.soft */
|
||||||
|
PCP_CPU_STEAL, /* kernel.all.cpu.steal */
|
||||||
|
PCP_CPU_GUEST, /* kernel.all.cpu.guest */
|
||||||
|
PCP_CPU_GUESTNICE, /* kernel.all.cpu.guest_nice */
|
||||||
|
PCP_PERCPU_USER, /* kernel.percpu.cpu.user */
|
||||||
|
PCP_PERCPU_NICE, /* kernel.percpu.cpu.nice */
|
||||||
|
PCP_PERCPU_SYSTEM, /* kernel.percpu.cpu.sys */
|
||||||
|
PCP_PERCPU_IDLE, /* kernel.percpu.cpu.idle */
|
||||||
|
PCP_PERCPU_IOWAIT, /* kernel.percpu.cpu.wait.total */
|
||||||
|
PCP_PERCPU_IRQ, /* kernel.percpu.cpu.intr */
|
||||||
|
PCP_PERCPU_SOFTIRQ, /* kernel.percpu.cpu.irq.soft */
|
||||||
|
PCP_PERCPU_STEAL, /* kernel.percpu.cpu.steal */
|
||||||
|
PCP_PERCPU_GUEST, /* kernel.percpu.cpu.guest */
|
||||||
|
PCP_PERCPU_GUESTNICE, /* kernel.percpu.cpu.guest_nice */
|
||||||
|
PCP_MEM_TOTAL, /* mem.physmem */
|
||||||
|
PCP_MEM_FREE, /* mem.util.free */
|
||||||
|
PCP_MEM_BUFFERS, /* mem.util.bufmem */
|
||||||
|
PCP_MEM_CACHED, /* mem.util.cached */
|
||||||
|
PCP_MEM_SHARED, /* mem.util.shared */
|
||||||
|
PCP_MEM_AVAILABLE, /* mem.util.available */
|
||||||
|
PCP_MEM_SRECLAIM, /* mem.util.slabReclaimable */
|
||||||
|
PCP_MEM_SWAPCACHED, /* mem.util.swapCached */
|
||||||
|
PCP_MEM_SWAPTOTAL, /* mem.util.swapTotal */
|
||||||
|
PCP_MEM_SWAPFREE, /* mem.util.swapFree */
|
||||||
|
PCP_DISK_READB, /* disk.all.read_bytes */
|
||||||
|
PCP_DISK_WRITEB, /* disk.all.write_bytes */
|
||||||
|
PCP_DISK_ACTIVE, /* disk.all.avactive */
|
||||||
|
PCP_NET_RECVB, /* network.all.in.bytes */
|
||||||
|
PCP_NET_SENDB, /* network.all.out.bytes */
|
||||||
|
PCP_NET_RECVP, /* network.all.in.packets */
|
||||||
|
PCP_NET_SENDP, /* network.all.out.packets */
|
||||||
|
PCP_PSI_CPUSOME, /* kernel.all.pressure.cpu.some.avg */
|
||||||
|
PCP_PSI_IOSOME, /* kernel.all.pressure.io.some.avg */
|
||||||
|
PCP_PSI_IOFULL, /* kernel.all.pressure.io.full.avg */
|
||||||
|
PCP_PSI_MEMSOME, /* kernel.all.pressure.memory.some.avg */
|
||||||
|
PCP_PSI_MEMFULL, /* kernel.all.pressure.memory.full.avg */
|
||||||
|
PCP_ZFS_ARC_ANON_SIZE, /* zfs.arc.anon_size */
|
||||||
|
PCP_ZFS_ARC_BONUS_SIZE, /* zfs.arc.bonus_size */
|
||||||
|
PCP_ZFS_ARC_COMPRESSED_SIZE, /* zfs.arc.compressed_size */
|
||||||
|
PCP_ZFS_ARC_UNCOMPRESSED_SIZE, /* zfs.arc.uncompressed_size */
|
||||||
|
PCP_ZFS_ARC_C_MAX, /* zfs.arc.c_max */
|
||||||
|
PCP_ZFS_ARC_DBUF_SIZE, /* zfs.arc.dbuf_size */
|
||||||
|
PCP_ZFS_ARC_DNODE_SIZE, /* zfs.arc.dnode_size */
|
||||||
|
PCP_ZFS_ARC_HDR_SIZE, /* zfs.arc.hdr_size */
|
||||||
|
PCP_ZFS_ARC_MFU_SIZE, /* zfs.arc.mfu_size */
|
||||||
|
PCP_ZFS_ARC_MRU_SIZE, /* zfs.arc.mru_size */
|
||||||
|
PCP_ZFS_ARC_SIZE, /* zfs.arc.size */
|
||||||
|
PCP_ZRAM_CAPACITY, /* zram.capacity */
|
||||||
|
PCP_ZRAM_ORIGINAL, /* zram.mm_stat.data_size.original */
|
||||||
|
PCP_ZRAM_COMPRESSED, /* zram.mm_stat.data_size.compressed */
|
||||||
|
|
||||||
|
PCP_PROC_PID, /* proc.psinfo.pid */
|
||||||
|
PCP_PROC_PPID, /* proc.psinfo.ppid */
|
||||||
|
PCP_PROC_TGID, /* proc.psinfo.tgid */
|
||||||
|
PCP_PROC_PGRP, /* proc.psinfo.pgrp */
|
||||||
|
PCP_PROC_SESSION, /* proc.psinfo.session */
|
||||||
|
PCP_PROC_STATE, /* proc.psinfo.sname */
|
||||||
|
PCP_PROC_TTY, /* proc.psinfo.tty */
|
||||||
|
PCP_PROC_TTYPGRP, /* proc.psinfo.tty_pgrp */
|
||||||
|
PCP_PROC_MINFLT, /* proc.psinfo.minflt */
|
||||||
|
PCP_PROC_MAJFLT, /* proc.psinfo.maj_flt */
|
||||||
|
PCP_PROC_CMINFLT, /* proc.psinfo.cmin_flt */
|
||||||
|
PCP_PROC_CMAJFLT, /* proc.psinfo.cmaj_flt */
|
||||||
|
PCP_PROC_UTIME, /* proc.psinfo.utime */
|
||||||
|
PCP_PROC_STIME, /* proc.psinfo.stime */
|
||||||
|
PCP_PROC_CUTIME, /* proc.psinfo.cutime */
|
||||||
|
PCP_PROC_CSTIME, /* proc.psinfo.cstime */
|
||||||
|
PCP_PROC_PRIORITY, /* proc.psinfo.priority */
|
||||||
|
PCP_PROC_NICE, /* proc.psinfo.nice */
|
||||||
|
PCP_PROC_THREADS, /* proc.psinfo.threads */
|
||||||
|
PCP_PROC_STARTTIME, /* proc.psinfo.start_time */
|
||||||
|
PCP_PROC_PROCESSOR, /* proc.psinfo.processor */
|
||||||
|
PCP_PROC_CMD, /* proc.psinfo.cmd */
|
||||||
|
PCP_PROC_PSARGS, /* proc.psinfo.psargs */
|
||||||
|
PCP_PROC_CGROUPS, /* proc.psinfo.cgroups */
|
||||||
|
PCP_PROC_OOMSCORE, /* proc.psinfo.oom_score */
|
||||||
|
PCP_PROC_VCTXSW, /* proc.psinfo.vctxsw */
|
||||||
|
PCP_PROC_NVCTXSW, /* proc.psinfo.nvctxsw */
|
||||||
|
PCP_PROC_LABELS, /* proc.psinfo.labels */
|
||||||
|
PCP_PROC_ENVIRON, /* proc.psinfo.environ */
|
||||||
|
PCP_PROC_TTYNAME, /* proc.psinfo.ttyname */
|
||||||
|
PCP_PROC_EXE, /* proc.psinfo.exe */
|
||||||
|
PCP_PROC_CWD, /* proc.psinfo.cwd */
|
||||||
|
|
||||||
|
PCP_PROC_AUTOGROUP_ID, /* proc.autogroup.id */
|
||||||
|
PCP_PROC_AUTOGROUP_NICE, /* proc.autogroup.nice */
|
||||||
|
|
||||||
|
PCP_PROC_ID_UID, /* proc.id.uid */
|
||||||
|
PCP_PROC_ID_USER, /* proc.id.uid_nm */
|
||||||
|
|
||||||
|
PCP_PROC_IO_RCHAR, /* proc.io.rchar */
|
||||||
|
PCP_PROC_IO_WCHAR, /* proc.io.wchar */
|
||||||
|
PCP_PROC_IO_SYSCR, /* proc.io.syscr */
|
||||||
|
PCP_PROC_IO_SYSCW, /* proc.io.syscw */
|
||||||
|
PCP_PROC_IO_READB, /* proc.io.read_bytes */
|
||||||
|
PCP_PROC_IO_WRITEB, /* proc.io.write_bytes */
|
||||||
|
PCP_PROC_IO_CANCELLED, /* proc.io.cancelled_write_bytes */
|
||||||
|
|
||||||
|
PCP_PROC_MEM_SIZE, /* proc.memory.size */
|
||||||
|
PCP_PROC_MEM_RSS, /* proc.memory.rss */
|
||||||
|
PCP_PROC_MEM_SHARE, /* proc.memory.share */
|
||||||
|
PCP_PROC_MEM_TEXTRS, /* proc.memory.textrss */
|
||||||
|
PCP_PROC_MEM_LIBRS, /* proc.memory.librss */
|
||||||
|
PCP_PROC_MEM_DATRS, /* proc.memory.datrss */
|
||||||
|
PCP_PROC_MEM_DIRTY, /* proc.memory.dirty */
|
||||||
|
|
||||||
|
PCP_PROC_SMAPS_PSS, /* proc.smaps.pss */
|
||||||
|
PCP_PROC_SMAPS_SWAP, /* proc.smaps.swap */
|
||||||
|
PCP_PROC_SMAPS_SWAPPSS, /* proc.smaps.swappss */
|
||||||
|
|
||||||
|
PCP_METRIC_COUNT /* total metric count */
|
||||||
|
} PCPMetric;
|
||||||
|
|
||||||
|
void PCPMetric_enable(PCPMetric metric, bool enable);
|
||||||
|
|
||||||
|
bool PCPMetric_enabled(PCPMetric metric);
|
||||||
|
|
||||||
|
void PCPMetric_enableThreads(void);
|
||||||
|
|
||||||
|
bool PCPMetric_fetch(struct timeval* timestamp);
|
||||||
|
|
||||||
|
bool PCPMetric_iterate(PCPMetric metric, int* instp, int* offsetp);
|
||||||
|
|
||||||
|
pmAtomValue* PCPMetric_values(PCPMetric metric, pmAtomValue* atom, int count, int type);
|
||||||
|
|
||||||
|
const pmDesc* PCPMetric_desc(PCPMetric metric);
|
||||||
|
|
||||||
|
int PCPMetric_type(PCPMetric metric);
|
||||||
|
|
||||||
|
int PCPMetric_instanceCount(PCPMetric metric);
|
||||||
|
|
||||||
|
int PCPMetric_instanceOffset(PCPMetric metric, int inst);
|
||||||
|
|
||||||
|
pmAtomValue* PCPMetric_instance(PCPMetric metric, int inst, int offset, pmAtomValue* atom, int type);
|
||||||
|
|
||||||
|
#endif
|
|
@ -15,7 +15,6 @@ in the source distribution for its full text.
|
||||||
|
|
||||||
#include "CRT.h"
|
#include "CRT.h"
|
||||||
#include "Macros.h"
|
#include "Macros.h"
|
||||||
#include "Platform.h"
|
|
||||||
#include "Process.h"
|
#include "Process.h"
|
||||||
#include "ProvideCurses.h"
|
#include "ProvideCurses.h"
|
||||||
#include "RichString.h"
|
#include "RichString.h"
|
||||||
|
|
|
@ -17,8 +17,6 @@ in the source distribution for its full text.
|
||||||
#include "Process.h"
|
#include "Process.h"
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
|
|
||||||
#include "pcp/Platform.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define PROCESS_FLAG_LINUX_CGROUP 0x00000800
|
#define PROCESS_FLAG_LINUX_CGROUP 0x00000800
|
||||||
#define PROCESS_FLAG_LINUX_OOM 0x00001000
|
#define PROCESS_FLAG_LINUX_OOM 0x00001000
|
||||||
|
|
|
@ -11,6 +11,7 @@ in the source distribution for its full text.
|
||||||
|
|
||||||
#include "pcp/PCPProcessList.h"
|
#include "pcp/PCPProcessList.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -24,12 +25,13 @@ in the source distribution for its full text.
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
#include "XUtils.h"
|
#include "XUtils.h"
|
||||||
|
|
||||||
|
#include "pcp/PCPMetric.h"
|
||||||
#include "pcp/PCPProcess.h"
|
#include "pcp/PCPProcess.h"
|
||||||
|
|
||||||
|
|
||||||
static void PCPProcessList_updateCPUcount(PCPProcessList* this) {
|
static void PCPProcessList_updateCPUcount(PCPProcessList* this) {
|
||||||
ProcessList* pl = &(this->super);
|
ProcessList* pl = &(this->super);
|
||||||
pl->activeCPUs = Metric_instanceCount(PCP_PERCPU_SYSTEM);
|
pl->activeCPUs = PCPMetric_instanceCount(PCP_PERCPU_SYSTEM);
|
||||||
unsigned int cpus = Platform_getMaxCPU();
|
unsigned int cpus = Platform_getMaxCPU();
|
||||||
if (cpus == pl->existingCPUs)
|
if (cpus == pl->existingCPUs)
|
||||||
return;
|
return;
|
||||||
|
@ -54,7 +56,7 @@ static char* setUser(UsersTable* this, unsigned int uid, int pid, int offset) {
|
||||||
return name;
|
return name;
|
||||||
|
|
||||||
pmAtomValue value;
|
pmAtomValue value;
|
||||||
if (Metric_instance(PCP_PROC_ID_USER, pid, offset, &value, PM_TYPE_STRING)) {
|
if (PCPMetric_instance(PCP_PROC_ID_USER, pid, offset, &value, PM_TYPE_STRING)) {
|
||||||
Hashtable_put(this->users, uid, value.cp);
|
Hashtable_put(this->users, uid, value.cp);
|
||||||
name = value.cp;
|
name = value.cp;
|
||||||
}
|
}
|
||||||
|
@ -90,49 +92,49 @@ void ProcessList_delete(ProcessList* pl) {
|
||||||
|
|
||||||
static inline long Metric_instance_s32(int metric, int pid, int offset, long fallback) {
|
static inline long Metric_instance_s32(int metric, int pid, int offset, long fallback) {
|
||||||
pmAtomValue value;
|
pmAtomValue value;
|
||||||
if (Metric_instance(metric, pid, offset, &value, PM_TYPE_32))
|
if (PCPMetric_instance(metric, pid, offset, &value, PM_TYPE_32))
|
||||||
return value.l;
|
return value.l;
|
||||||
return fallback;
|
return fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline long long Metric_instance_s64(int metric, int pid, int offset, long long fallback) {
|
static inline long long Metric_instance_s64(int metric, int pid, int offset, long long fallback) {
|
||||||
pmAtomValue value;
|
pmAtomValue value;
|
||||||
if (Metric_instance(metric, pid, offset, &value, PM_TYPE_64))
|
if (PCPMetric_instance(metric, pid, offset, &value, PM_TYPE_64))
|
||||||
return value.l;
|
return value.l;
|
||||||
return fallback;
|
return fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned long Metric_instance_u32(int metric, int pid, int offset, unsigned long fallback) {
|
static inline unsigned long Metric_instance_u32(int metric, int pid, int offset, unsigned long fallback) {
|
||||||
pmAtomValue value;
|
pmAtomValue value;
|
||||||
if (Metric_instance(metric, pid, offset, &value, PM_TYPE_U32))
|
if (PCPMetric_instance(metric, pid, offset, &value, PM_TYPE_U32))
|
||||||
return value.ul;
|
return value.ul;
|
||||||
return fallback;
|
return fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned long long Metric_instance_u64(int metric, int pid, int offset, unsigned long long fallback) {
|
static inline unsigned long long Metric_instance_u64(int metric, int pid, int offset, unsigned long long fallback) {
|
||||||
pmAtomValue value;
|
pmAtomValue value;
|
||||||
if (Metric_instance(metric, pid, offset, &value, PM_TYPE_U64))
|
if (PCPMetric_instance(metric, pid, offset, &value, PM_TYPE_U64))
|
||||||
return value.ull;
|
return value.ull;
|
||||||
return fallback;
|
return fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned long long Metric_instance_time(int metric, int pid, int offset) {
|
static inline unsigned long long Metric_instance_time(int metric, int pid, int offset) {
|
||||||
pmAtomValue value;
|
pmAtomValue value;
|
||||||
if (Metric_instance(metric, pid, offset, &value, PM_TYPE_U64))
|
if (PCPMetric_instance(metric, pid, offset, &value, PM_TYPE_U64))
|
||||||
return value.ull / 10;
|
return value.ull / 10;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned long long Metric_instance_ONE_K(int metric, int pid, int offset) {
|
static inline unsigned long long Metric_instance_ONE_K(int metric, int pid, int offset) {
|
||||||
pmAtomValue value;
|
pmAtomValue value;
|
||||||
if (Metric_instance(metric, pid, offset, &value, PM_TYPE_U64))
|
if (PCPMetric_instance(metric, pid, offset, &value, PM_TYPE_U64))
|
||||||
return value.ull / ONE_K;
|
return value.ull / ONE_K;
|
||||||
return ULLONG_MAX;
|
return ULLONG_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline char Metric_instance_char(int metric, int pid, int offset, char fallback) {
|
static inline char Metric_instance_char(int metric, int pid, int offset, char fallback) {
|
||||||
pmAtomValue value;
|
pmAtomValue value;
|
||||||
if (Metric_instance(metric, pid, offset, &value, PM_TYPE_STRING)) {
|
if (PCPMetric_instance(metric, pid, offset, &value, PM_TYPE_STRING)) {
|
||||||
char uchar = value.cp[0];
|
char uchar = value.cp[0];
|
||||||
free(value.cp);
|
free(value.cp);
|
||||||
return uchar;
|
return uchar;
|
||||||
|
@ -150,7 +152,7 @@ static void PCPProcessList_updateInfo(Process* process, int pid, int offset, cha
|
||||||
PCPProcess* pp = (PCPProcess*) process;
|
PCPProcess* pp = (PCPProcess*) process;
|
||||||
pmAtomValue value;
|
pmAtomValue value;
|
||||||
|
|
||||||
if (!Metric_instance(PCP_PROC_CMD, pid, offset, &value, PM_TYPE_STRING))
|
if (!PCPMetric_instance(PCP_PROC_CMD, pid, offset, &value, PM_TYPE_STRING))
|
||||||
value.cp = xStrdup("<unknown>");
|
value.cp = xStrdup("<unknown>");
|
||||||
String_safeStrncpy(command, value.cp, commLen);
|
String_safeStrncpy(command, value.cp, commLen);
|
||||||
free(value.cp);
|
free(value.cp);
|
||||||
|
@ -185,7 +187,7 @@ static void PCPProcessList_updateIO(PCPProcess* pp, int pid, int offset, unsigne
|
||||||
pp->io_syscw = Metric_instance_u64(PCP_PROC_IO_SYSCW, pid, offset, ULLONG_MAX);
|
pp->io_syscw = Metric_instance_u64(PCP_PROC_IO_SYSCW, pid, offset, ULLONG_MAX);
|
||||||
pp->io_cancelled_write_bytes = Metric_instance_ONE_K(PCP_PROC_IO_CANCELLED, pid, offset);
|
pp->io_cancelled_write_bytes = Metric_instance_ONE_K(PCP_PROC_IO_CANCELLED, pid, offset);
|
||||||
|
|
||||||
if (Metric_instance(PCP_PROC_IO_READB, pid, offset, &value, PM_TYPE_U64)) {
|
if (PCPMetric_instance(PCP_PROC_IO_READB, pid, offset, &value, PM_TYPE_U64)) {
|
||||||
unsigned long long last_read = pp->io_read_bytes;
|
unsigned long long last_read = pp->io_read_bytes;
|
||||||
pp->io_read_bytes = value.ull / ONE_K;
|
pp->io_read_bytes = value.ull / ONE_K;
|
||||||
pp->io_rate_read_bps = ONE_K * (pp->io_read_bytes - last_read) /
|
pp->io_rate_read_bps = ONE_K * (pp->io_read_bytes - last_read) /
|
||||||
|
@ -195,7 +197,7 @@ static void PCPProcessList_updateIO(PCPProcess* pp, int pid, int offset, unsigne
|
||||||
pp->io_rate_read_bps = NAN;
|
pp->io_rate_read_bps = NAN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Metric_instance(PCP_PROC_IO_WRITEB, pid, offset, &value, PM_TYPE_U64)) {
|
if (PCPMetric_instance(PCP_PROC_IO_WRITEB, pid, offset, &value, PM_TYPE_U64)) {
|
||||||
unsigned long long last_write = pp->io_write_bytes;
|
unsigned long long last_write = pp->io_write_bytes;
|
||||||
pp->io_write_bytes = value.ull;
|
pp->io_write_bytes = value.ull;
|
||||||
pp->io_rate_write_bps = ONE_K * (pp->io_write_bytes - last_write) /
|
pp->io_rate_write_bps = ONE_K * (pp->io_write_bytes - last_write) /
|
||||||
|
@ -237,20 +239,20 @@ static void PCPProcessList_readCtxtData(PCPProcess* pp, int pid, int offset) {
|
||||||
pmAtomValue value;
|
pmAtomValue value;
|
||||||
unsigned long ctxt = 0;
|
unsigned long ctxt = 0;
|
||||||
|
|
||||||
if (Metric_instance(PCP_PROC_VCTXSW, pid, offset, &value, PM_TYPE_U32))
|
if (PCPMetric_instance(PCP_PROC_VCTXSW, pid, offset, &value, PM_TYPE_U32))
|
||||||
ctxt += value.ul;
|
ctxt += value.ul;
|
||||||
if (Metric_instance(PCP_PROC_NVCTXSW, pid, offset, &value, PM_TYPE_U32))
|
if (PCPMetric_instance(PCP_PROC_NVCTXSW, pid, offset, &value, PM_TYPE_U32))
|
||||||
ctxt += value.ul;
|
ctxt += value.ul;
|
||||||
|
|
||||||
pp->ctxt_diff = ctxt > pp->ctxt_total ? ctxt - pp->ctxt_total : 0;
|
pp->ctxt_diff = ctxt > pp->ctxt_total ? ctxt - pp->ctxt_total : 0;
|
||||||
pp->ctxt_total = ctxt;
|
pp->ctxt_total = ctxt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char* setString(Metric metric, int pid, int offset, char* string) {
|
static char* setString(PCPMetric metric, int pid, int offset, char* string) {
|
||||||
if (string)
|
if (string)
|
||||||
free(string);
|
free(string);
|
||||||
pmAtomValue value;
|
pmAtomValue value;
|
||||||
if (Metric_instance(metric, pid, offset, &value, PM_TYPE_STRING))
|
if (PCPMetric_instance(metric, pid, offset, &value, PM_TYPE_STRING))
|
||||||
string = value.cp;
|
string = value.cp;
|
||||||
else
|
else
|
||||||
string = NULL;
|
string = NULL;
|
||||||
|
@ -280,7 +282,7 @@ static void PCPProcessList_updateUsername(Process* process, int pid, int offset,
|
||||||
|
|
||||||
static void PCPProcessList_updateCmdline(Process* process, int pid, int offset, const char* comm) {
|
static void PCPProcessList_updateCmdline(Process* process, int pid, int offset, const char* comm) {
|
||||||
pmAtomValue value;
|
pmAtomValue value;
|
||||||
if (!Metric_instance(PCP_PROC_PSARGS, pid, offset, &value, PM_TYPE_STRING)) {
|
if (!PCPMetric_instance(PCP_PROC_PSARGS, pid, offset, &value, PM_TYPE_STRING)) {
|
||||||
if (process->state != 'Z')
|
if (process->state != 'Z')
|
||||||
process->isKernelThread = true;
|
process->isKernelThread = true;
|
||||||
Process_updateCmdline(process, NULL, 0, 0);
|
Process_updateCmdline(process, NULL, 0, 0);
|
||||||
|
@ -314,7 +316,7 @@ static void PCPProcessList_updateCmdline(Process* process, int pid, int offset,
|
||||||
|
|
||||||
Process_updateComm(process, comm);
|
Process_updateComm(process, comm);
|
||||||
|
|
||||||
if (Metric_instance(PCP_PROC_EXE, pid, offset, &value, PM_TYPE_STRING)) {
|
if (PCPMetric_instance(PCP_PROC_EXE, pid, offset, &value, PM_TYPE_STRING)) {
|
||||||
Process_updateExe(process, value.cp);
|
Process_updateExe(process, value.cp);
|
||||||
free(value.cp);
|
free(value.cp);
|
||||||
}
|
}
|
||||||
|
@ -331,7 +333,7 @@ static bool PCPProcessList_updateProcesses(PCPProcessList* this, double period,
|
||||||
int pid = -1, offset = -1;
|
int pid = -1, offset = -1;
|
||||||
|
|
||||||
/* for every process ... */
|
/* for every process ... */
|
||||||
while (Metric_iterate(PCP_PROC_PID, &pid, &offset)) {
|
while (PCPMetric_iterate(PCP_PROC_PID, &pid, &offset)) {
|
||||||
|
|
||||||
bool preExisting;
|
bool preExisting;
|
||||||
Process* proc = ProcessList_getProcess(pl, pid, &preExisting, PCPProcess_new);
|
Process* proc = ProcessList_getProcess(pl, pid, &preExisting, PCPProcess_new);
|
||||||
|
@ -372,7 +374,7 @@ static bool PCPProcessList_updateProcesses(PCPProcessList* this, double period,
|
||||||
|
|
||||||
if ((settings->flags & PROCESS_FLAG_LINUX_SMAPS) &&
|
if ((settings->flags & PROCESS_FLAG_LINUX_SMAPS) &&
|
||||||
(Process_isKernelThread(proc) == false)) {
|
(Process_isKernelThread(proc) == false)) {
|
||||||
if (Metric_enabled(PCP_PROC_SMAPS_PSS))
|
if (PCPMetric_enabled(PCP_PROC_SMAPS_PSS))
|
||||||
PCPProcessList_updateSmaps(pp, pid, offset);
|
PCPProcessList_updateSmaps(pp, pid, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,30 +454,30 @@ static void PCPProcessList_updateMemoryInfo(ProcessList* super) {
|
||||||
super->usedSwap = super->totalSwap = super->sharedMem = 0;
|
super->usedSwap = super->totalSwap = super->sharedMem = 0;
|
||||||
|
|
||||||
pmAtomValue value;
|
pmAtomValue value;
|
||||||
if (Metric_values(PCP_MEM_TOTAL, &value, 1, PM_TYPE_U64) != NULL)
|
if (PCPMetric_values(PCP_MEM_TOTAL, &value, 1, PM_TYPE_U64) != NULL)
|
||||||
super->totalMem = value.ull;
|
super->totalMem = value.ull;
|
||||||
if (Metric_values(PCP_MEM_FREE, &value, 1, PM_TYPE_U64) != NULL)
|
if (PCPMetric_values(PCP_MEM_FREE, &value, 1, PM_TYPE_U64) != NULL)
|
||||||
freeMem = value.ull;
|
freeMem = value.ull;
|
||||||
if (Metric_values(PCP_MEM_BUFFERS, &value, 1, PM_TYPE_U64) != NULL)
|
if (PCPMetric_values(PCP_MEM_BUFFERS, &value, 1, PM_TYPE_U64) != NULL)
|
||||||
super->buffersMem = value.ull;
|
super->buffersMem = value.ull;
|
||||||
if (Metric_values(PCP_MEM_SRECLAIM, &value, 1, PM_TYPE_U64) != NULL)
|
if (PCPMetric_values(PCP_MEM_SRECLAIM, &value, 1, PM_TYPE_U64) != NULL)
|
||||||
sreclaimableMem = value.ull;
|
sreclaimableMem = value.ull;
|
||||||
if (Metric_values(PCP_MEM_SHARED, &value, 1, PM_TYPE_U64) != NULL)
|
if (PCPMetric_values(PCP_MEM_SHARED, &value, 1, PM_TYPE_U64) != NULL)
|
||||||
super->sharedMem = value.ull;
|
super->sharedMem = value.ull;
|
||||||
if (Metric_values(PCP_MEM_CACHED, &value, 1, PM_TYPE_U64) != NULL)
|
if (PCPMetric_values(PCP_MEM_CACHED, &value, 1, PM_TYPE_U64) != NULL)
|
||||||
super->cachedMem = value.ull + sreclaimableMem - super->sharedMem;
|
super->cachedMem = value.ull + sreclaimableMem - super->sharedMem;
|
||||||
const memory_t usedDiff = freeMem + super->cachedMem + sreclaimableMem + super->buffersMem;
|
const memory_t usedDiff = freeMem + super->cachedMem + sreclaimableMem + super->buffersMem;
|
||||||
super->usedMem = (super->totalMem >= usedDiff) ?
|
super->usedMem = (super->totalMem >= usedDiff) ?
|
||||||
super->totalMem - usedDiff : super->totalMem - freeMem;
|
super->totalMem - usedDiff : super->totalMem - freeMem;
|
||||||
if (Metric_values(PCP_MEM_AVAILABLE, &value, 1, PM_TYPE_U64) != NULL)
|
if (PCPMetric_values(PCP_MEM_AVAILABLE, &value, 1, PM_TYPE_U64) != NULL)
|
||||||
super->availableMem = MINIMUM(value.ull, super->totalMem);
|
super->availableMem = MINIMUM(value.ull, super->totalMem);
|
||||||
else
|
else
|
||||||
super->availableMem = freeMem;
|
super->availableMem = freeMem;
|
||||||
if (Metric_values(PCP_MEM_SWAPFREE, &value, 1, PM_TYPE_U64) != NULL)
|
if (PCPMetric_values(PCP_MEM_SWAPFREE, &value, 1, PM_TYPE_U64) != NULL)
|
||||||
swapFreeMem = value.ull;
|
swapFreeMem = value.ull;
|
||||||
if (Metric_values(PCP_MEM_SWAPTOTAL, &value, 1, PM_TYPE_U64) != NULL)
|
if (PCPMetric_values(PCP_MEM_SWAPTOTAL, &value, 1, PM_TYPE_U64) != NULL)
|
||||||
super->totalSwap = value.ull;
|
super->totalSwap = value.ull;
|
||||||
if (Metric_values(PCP_MEM_SWAPCACHED, &value, 1, PM_TYPE_U64) != NULL)
|
if (PCPMetric_values(PCP_MEM_SWAPCACHED, &value, 1, PM_TYPE_U64) != NULL)
|
||||||
super->cachedSwap = value.ull;
|
super->cachedSwap = value.ull;
|
||||||
super->usedSwap = super->totalSwap - swapFreeMem - super->cachedSwap;
|
super->usedSwap = super->totalSwap - swapFreeMem - super->cachedSwap;
|
||||||
}
|
}
|
||||||
|
@ -547,26 +549,26 @@ static void PCPProcessList_deriveCPUTime(pmAtomValue* values) {
|
||||||
PCPProcessList_saveCPUTimePeriod(values, CPU_TOTAL_PERIOD, totaltime);
|
PCPProcessList_saveCPUTimePeriod(values, CPU_TOTAL_PERIOD, totaltime);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PCPProcessList_updateAllCPUTime(PCPProcessList* this, Metric metric, CPUMetric cpumetric)
|
static void PCPProcessList_updateAllCPUTime(PCPProcessList* this, PCPMetric metric, CPUMetric cpumetric)
|
||||||
{
|
{
|
||||||
pmAtomValue* value = &this->cpu[cpumetric];
|
pmAtomValue* value = &this->cpu[cpumetric];
|
||||||
if (Metric_values(metric, value, 1, PM_TYPE_U64) == NULL)
|
if (PCPMetric_values(metric, value, 1, PM_TYPE_U64) == NULL)
|
||||||
memset(&value, 0, sizeof(pmAtomValue));
|
memset(&value, 0, sizeof(pmAtomValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PCPProcessList_updatePerCPUTime(PCPProcessList* this, Metric metric, CPUMetric cpumetric)
|
static void PCPProcessList_updatePerCPUTime(PCPProcessList* this, PCPMetric metric, CPUMetric cpumetric)
|
||||||
{
|
{
|
||||||
int cpus = this->super.existingCPUs;
|
int cpus = this->super.existingCPUs;
|
||||||
if (Metric_values(metric, this->values, cpus, PM_TYPE_U64) == NULL)
|
if (PCPMetric_values(metric, this->values, cpus, PM_TYPE_U64) == NULL)
|
||||||
memset(this->values, 0, cpus * sizeof(pmAtomValue));
|
memset(this->values, 0, cpus * sizeof(pmAtomValue));
|
||||||
for (int i = 0; i < cpus; i++)
|
for (int i = 0; i < cpus; i++)
|
||||||
this->percpu[i][cpumetric].ull = this->values[i].ull;
|
this->percpu[i][cpumetric].ull = this->values[i].ull;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PCPProcessList_updatePerCPUReal(PCPProcessList* this, Metric metric, CPUMetric cpumetric)
|
static void PCPProcessList_updatePerCPUReal(PCPProcessList* this, PCPMetric metric, CPUMetric cpumetric)
|
||||||
{
|
{
|
||||||
int cpus = this->super.existingCPUs;
|
int cpus = this->super.existingCPUs;
|
||||||
if (Metric_values(metric, this->values, cpus, PM_TYPE_DOUBLE) == NULL)
|
if (PCPMetric_values(metric, this->values, cpus, PM_TYPE_DOUBLE) == NULL)
|
||||||
memset(this->values, 0, cpus * sizeof(pmAtomValue));
|
memset(this->values, 0, cpus * sizeof(pmAtomValue));
|
||||||
for (int i = 0; i < cpus; i++)
|
for (int i = 0; i < cpus; i++)
|
||||||
this->percpu[i][cpumetric].d = this->values[i].d;
|
this->percpu[i][cpumetric].d = this->values[i].d;
|
||||||
|
@ -579,27 +581,27 @@ static inline void PCPProcessList_scanZfsArcstats(PCPProcessList* this) {
|
||||||
pmAtomValue value;
|
pmAtomValue value;
|
||||||
|
|
||||||
memset(&this->zfs, 0, sizeof(ZfsArcStats));
|
memset(&this->zfs, 0, sizeof(ZfsArcStats));
|
||||||
if (Metric_values(PCP_ZFS_ARC_ANON_SIZE, &value, 1, PM_TYPE_U64))
|
if (PCPMetric_values(PCP_ZFS_ARC_ANON_SIZE, &value, 1, PM_TYPE_U64))
|
||||||
this->zfs.anon = value.ull / ONE_K;
|
this->zfs.anon = value.ull / ONE_K;
|
||||||
if (Metric_values(PCP_ZFS_ARC_C_MAX, &value, 1, PM_TYPE_U64))
|
if (PCPMetric_values(PCP_ZFS_ARC_C_MAX, &value, 1, PM_TYPE_U64))
|
||||||
this->zfs.max = value.ull / ONE_K;
|
this->zfs.max = value.ull / ONE_K;
|
||||||
if (Metric_values(PCP_ZFS_ARC_BONUS_SIZE, &value, 1, PM_TYPE_U64))
|
if (PCPMetric_values(PCP_ZFS_ARC_BONUS_SIZE, &value, 1, PM_TYPE_U64))
|
||||||
bonusSize = value.ull / ONE_K;
|
bonusSize = value.ull / ONE_K;
|
||||||
if (Metric_values(PCP_ZFS_ARC_DBUF_SIZE, &value, 1, PM_TYPE_U64))
|
if (PCPMetric_values(PCP_ZFS_ARC_DBUF_SIZE, &value, 1, PM_TYPE_U64))
|
||||||
dbufSize = value.ull / ONE_K;
|
dbufSize = value.ull / ONE_K;
|
||||||
if (Metric_values(PCP_ZFS_ARC_DNODE_SIZE, &value, 1, PM_TYPE_U64))
|
if (PCPMetric_values(PCP_ZFS_ARC_DNODE_SIZE, &value, 1, PM_TYPE_U64))
|
||||||
dnodeSize = value.ull / ONE_K;
|
dnodeSize = value.ull / ONE_K;
|
||||||
if (Metric_values(PCP_ZFS_ARC_COMPRESSED_SIZE, &value, 1, PM_TYPE_U64))
|
if (PCPMetric_values(PCP_ZFS_ARC_COMPRESSED_SIZE, &value, 1, PM_TYPE_U64))
|
||||||
this->zfs.compressed = value.ull / ONE_K;
|
this->zfs.compressed = value.ull / ONE_K;
|
||||||
if (Metric_values(PCP_ZFS_ARC_UNCOMPRESSED_SIZE, &value, 1, PM_TYPE_U64))
|
if (PCPMetric_values(PCP_ZFS_ARC_UNCOMPRESSED_SIZE, &value, 1, PM_TYPE_U64))
|
||||||
this->zfs.uncompressed = value.ull / ONE_K;
|
this->zfs.uncompressed = value.ull / ONE_K;
|
||||||
if (Metric_values(PCP_ZFS_ARC_HDR_SIZE, &value, 1, PM_TYPE_U64))
|
if (PCPMetric_values(PCP_ZFS_ARC_HDR_SIZE, &value, 1, PM_TYPE_U64))
|
||||||
this->zfs.header = value.ull / ONE_K;
|
this->zfs.header = value.ull / ONE_K;
|
||||||
if (Metric_values(PCP_ZFS_ARC_MFU_SIZE, &value, 1, PM_TYPE_U64))
|
if (PCPMetric_values(PCP_ZFS_ARC_MFU_SIZE, &value, 1, PM_TYPE_U64))
|
||||||
this->zfs.MFU = value.ull / ONE_K;
|
this->zfs.MFU = value.ull / ONE_K;
|
||||||
if (Metric_values(PCP_ZFS_ARC_MRU_SIZE, &value, 1, PM_TYPE_U64))
|
if (PCPMetric_values(PCP_ZFS_ARC_MRU_SIZE, &value, 1, PM_TYPE_U64))
|
||||||
this->zfs.MRU = value.ull / ONE_K;
|
this->zfs.MRU = value.ull / ONE_K;
|
||||||
if (Metric_values(PCP_ZFS_ARC_SIZE, &value, 1, PM_TYPE_U64))
|
if (PCPMetric_values(PCP_ZFS_ARC_SIZE, &value, 1, PM_TYPE_U64))
|
||||||
this->zfs.size = value.ull / ONE_K;
|
this->zfs.size = value.ull / ONE_K;
|
||||||
|
|
||||||
this->zfs.other = (dbufSize + dnodeSize + bonusSize) / ONE_K;
|
this->zfs.other = (dbufSize + dnodeSize + bonusSize) / ONE_K;
|
||||||
|
@ -651,34 +653,34 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
|
||||||
bool enabled = !pauseProcessUpdate;
|
bool enabled = !pauseProcessUpdate;
|
||||||
|
|
||||||
bool flagged = settings->showCPUFrequency;
|
bool flagged = settings->showCPUFrequency;
|
||||||
Metric_enable(PCP_HINV_CPUCLOCK, flagged);
|
PCPMetric_enable(PCP_HINV_CPUCLOCK, flagged);
|
||||||
|
|
||||||
/* In pause mode do not sample per-process metric values at all */
|
/* In pause mode do not sample per-process metric values at all */
|
||||||
for (int metric = PCP_PROC_PID; metric < PCP_METRIC_COUNT; metric++)
|
for (int metric = PCP_PROC_PID; metric < PCP_METRIC_COUNT; metric++)
|
||||||
Metric_enable(metric, enabled);
|
PCPMetric_enable(metric, enabled);
|
||||||
|
|
||||||
flagged = settings->flags & PROCESS_FLAG_LINUX_CGROUP;
|
flagged = settings->flags & PROCESS_FLAG_LINUX_CGROUP;
|
||||||
Metric_enable(PCP_PROC_CGROUPS, flagged && enabled);
|
PCPMetric_enable(PCP_PROC_CGROUPS, flagged && enabled);
|
||||||
flagged = settings->flags & PROCESS_FLAG_LINUX_OOM;
|
flagged = settings->flags & PROCESS_FLAG_LINUX_OOM;
|
||||||
Metric_enable(PCP_PROC_OOMSCORE, flagged && enabled);
|
PCPMetric_enable(PCP_PROC_OOMSCORE, flagged && enabled);
|
||||||
flagged = settings->flags & PROCESS_FLAG_LINUX_CTXT;
|
flagged = settings->flags & PROCESS_FLAG_LINUX_CTXT;
|
||||||
Metric_enable(PCP_PROC_VCTXSW, flagged && enabled);
|
PCPMetric_enable(PCP_PROC_VCTXSW, flagged && enabled);
|
||||||
Metric_enable(PCP_PROC_NVCTXSW, flagged && enabled);
|
PCPMetric_enable(PCP_PROC_NVCTXSW, flagged && enabled);
|
||||||
flagged = settings->flags & PROCESS_FLAG_LINUX_SECATTR;
|
flagged = settings->flags & PROCESS_FLAG_LINUX_SECATTR;
|
||||||
Metric_enable(PCP_PROC_LABELS, flagged && enabled);
|
PCPMetric_enable(PCP_PROC_LABELS, flagged && enabled);
|
||||||
flagged = settings->flags & PROCESS_FLAG_LINUX_AUTOGROUP;
|
flagged = settings->flags & PROCESS_FLAG_LINUX_AUTOGROUP;
|
||||||
Metric_enable(PCP_PROC_AUTOGROUP_ID, flagged && enabled);
|
PCPMetric_enable(PCP_PROC_AUTOGROUP_ID, flagged && enabled);
|
||||||
Metric_enable(PCP_PROC_AUTOGROUP_NICE, flagged && enabled);
|
PCPMetric_enable(PCP_PROC_AUTOGROUP_NICE, flagged && enabled);
|
||||||
|
|
||||||
/* Sample smaps metrics on every second pass to improve performance */
|
/* Sample smaps metrics on every second pass to improve performance */
|
||||||
static int smaps_flag;
|
static int smaps_flag;
|
||||||
smaps_flag = !!smaps_flag;
|
smaps_flag = !!smaps_flag;
|
||||||
Metric_enable(PCP_PROC_SMAPS_PSS, smaps_flag && enabled);
|
PCPMetric_enable(PCP_PROC_SMAPS_PSS, smaps_flag && enabled);
|
||||||
Metric_enable(PCP_PROC_SMAPS_SWAP, smaps_flag && enabled);
|
PCPMetric_enable(PCP_PROC_SMAPS_SWAP, smaps_flag && enabled);
|
||||||
Metric_enable(PCP_PROC_SMAPS_SWAPPSS, smaps_flag && enabled);
|
PCPMetric_enable(PCP_PROC_SMAPS_SWAPPSS, smaps_flag && enabled);
|
||||||
|
|
||||||
struct timeval timestamp;
|
struct timeval timestamp;
|
||||||
Metric_fetch(×tamp);
|
PCPMetric_fetch(×tamp);
|
||||||
|
|
||||||
double sample = this->timestamp;
|
double sample = this->timestamp;
|
||||||
this->timestamp = pmtimevalToReal(×tamp);
|
this->timestamp = pmtimevalToReal(×tamp);
|
||||||
|
@ -698,7 +700,7 @@ bool ProcessList_isCPUonline(const ProcessList* super, unsigned int id) {
|
||||||
(void) super;
|
(void) super;
|
||||||
|
|
||||||
pmAtomValue value;
|
pmAtomValue value;
|
||||||
if (Metric_instance(PCP_PERCPU_SYSTEM, id, id, &value, PM_TYPE_U32))
|
if (PCPMetric_instance(PCP_PERCPU_SYSTEM, id, id, &value, PM_TYPE_U32))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
274
pcp/Platform.c
274
pcp/Platform.c
|
@ -12,26 +12,26 @@ in the source distribution for its full text.
|
||||||
#include "pcp/Platform.h"
|
#include "pcp/Platform.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "BatteryMeter.h"
|
#include "BatteryMeter.h"
|
||||||
#include "ClockMeter.h"
|
|
||||||
#include "Compat.h"
|
|
||||||
#include "CPUMeter.h"
|
#include "CPUMeter.h"
|
||||||
|
#include "ClockMeter.h"
|
||||||
#include "DateMeter.h"
|
#include "DateMeter.h"
|
||||||
#include "DateTimeMeter.h"
|
#include "DateTimeMeter.h"
|
||||||
#include "DiskIOMeter.h"
|
#include "DiskIOMeter.h"
|
||||||
|
#include "DynamicColumn.h"
|
||||||
#include "DynamicMeter.h"
|
#include "DynamicMeter.h"
|
||||||
#include "HostnameMeter.h"
|
#include "HostnameMeter.h"
|
||||||
#include "LoadAverageMeter.h"
|
#include "LoadAverageMeter.h"
|
||||||
#include "Macros.h"
|
#include "Macros.h"
|
||||||
#include "MainPanel.h"
|
|
||||||
#include "MemoryMeter.h"
|
#include "MemoryMeter.h"
|
||||||
#include "Meter.h"
|
#include "Meter.h"
|
||||||
#include "NetworkIOMeter.h"
|
#include "NetworkIOMeter.h"
|
||||||
#include "Object.h"
|
|
||||||
#include "Panel.h"
|
|
||||||
#include "ProcessList.h"
|
#include "ProcessList.h"
|
||||||
#include "ProvideCurses.h"
|
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
#include "SwapMeter.h"
|
#include "SwapMeter.h"
|
||||||
#include "SysArchMeter.h"
|
#include "SysArchMeter.h"
|
||||||
|
@ -44,30 +44,13 @@ in the source distribution for its full text.
|
||||||
#include "linux/ZramStats.h"
|
#include "linux/ZramStats.h"
|
||||||
#include "pcp/PCPDynamicColumn.h"
|
#include "pcp/PCPDynamicColumn.h"
|
||||||
#include "pcp/PCPDynamicMeter.h"
|
#include "pcp/PCPDynamicMeter.h"
|
||||||
#include "pcp/PCPProcess.h"
|
#include "pcp/PCPMetric.h"
|
||||||
#include "pcp/PCPProcessList.h"
|
#include "pcp/PCPProcessList.h"
|
||||||
#include "zfs/ZfsArcMeter.h"
|
#include "zfs/ZfsArcMeter.h"
|
||||||
#include "zfs/ZfsArcStats.h"
|
#include "zfs/ZfsArcStats.h"
|
||||||
#include "zfs/ZfsCompressedArcMeter.h"
|
#include "zfs/ZfsCompressedArcMeter.h"
|
||||||
|
|
||||||
|
|
||||||
typedef struct Platform_ {
|
|
||||||
int context; /* PMAPI(3) context identifier */
|
|
||||||
size_t totalMetrics; /* total number of all metrics */
|
|
||||||
const char** names; /* name array indexed by Metric */
|
|
||||||
pmID* pmids; /* all known metric identifiers */
|
|
||||||
pmID* fetch; /* enabled identifiers for sampling */
|
|
||||||
pmDesc* descs; /* metric desc array indexed by Metric */
|
|
||||||
pmResult* result; /* sample values result indexed by Metric */
|
|
||||||
PCPDynamicMeters meters; /* dynamic meters via configuration files */
|
|
||||||
PCPDynamicColumns columns; /* dynamic columns via configuration files */
|
|
||||||
struct timeval offset; /* time offset used in archive mode only */
|
|
||||||
long long btime; /* boottime in seconds since the epoch */
|
|
||||||
char* release; /* uname and distro from this context */
|
|
||||||
int pidmax; /* maximum platform process identifier */
|
|
||||||
int ncpu; /* maximum processor count configured */
|
|
||||||
} Platform;
|
|
||||||
|
|
||||||
Platform* pcp;
|
Platform* pcp;
|
||||||
|
|
||||||
ProcessField Platform_defaultFields[] = { PID, USER, PRIORITY, NICE, M_VIRT, M_RESIDENT, (int)M_SHARE, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 };
|
ProcessField Platform_defaultFields[] = { PID, USER, PRIORITY, NICE, M_VIRT, M_RESIDENT, (int)M_SHARE, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 };
|
||||||
|
@ -251,162 +234,7 @@ static const char* Platform_metricNames[] = {
|
||||||
[PCP_METRIC_COUNT] = NULL
|
[PCP_METRIC_COUNT] = NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
const pmDesc* Metric_desc(Metric metric) {
|
size_t Platform_addMetric(PCPMetric id, const char* name) {
|
||||||
return &pcp->descs[metric];
|
|
||||||
}
|
|
||||||
|
|
||||||
int Metric_type(Metric metric) {
|
|
||||||
return pcp->descs[metric].type;
|
|
||||||
}
|
|
||||||
|
|
||||||
pmAtomValue* Metric_values(Metric metric, pmAtomValue* atom, int count, int type) {
|
|
||||||
if (pcp->result == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
pmValueSet* vset = pcp->result->vset[metric];
|
|
||||||
if (!vset || vset->numval <= 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* extract requested number of values as requested type */
|
|
||||||
const pmDesc* desc = &pcp->descs[metric];
|
|
||||||
for (int i = 0; i < vset->numval; i++) {
|
|
||||||
if (i == count)
|
|
||||||
break;
|
|
||||||
const pmValue* value = &vset->vlist[i];
|
|
||||||
int sts = pmExtractValue(vset->valfmt, value, desc->type, &atom[i], type);
|
|
||||||
if (sts < 0) {
|
|
||||||
if (pmDebugOptions.appl0)
|
|
||||||
fprintf(stderr, "Error: cannot extract metric value: %s\n",
|
|
||||||
pmErrStr(sts));
|
|
||||||
memset(&atom[i], 0, sizeof(pmAtomValue));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return atom;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Metric_instanceCount(Metric metric) {
|
|
||||||
pmValueSet* vset = pcp->result->vset[metric];
|
|
||||||
if (vset)
|
|
||||||
return vset->numval;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Metric_instanceOffset(Metric metric, int inst) {
|
|
||||||
pmValueSet* vset = pcp->result->vset[metric];
|
|
||||||
if (!vset || vset->numval <= 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* search for optimal offset for subsequent inst lookups to begin */
|
|
||||||
for (int i = 0; i < vset->numval; i++) {
|
|
||||||
if (inst == vset->vlist[i].inst)
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static pmAtomValue* Metric_extract(Metric metric, int inst, int offset, pmValueSet* vset, pmAtomValue* atom, int type) {
|
|
||||||
|
|
||||||
/* extract value (using requested type) of given metric instance */
|
|
||||||
const pmDesc* desc = &pcp->descs[metric];
|
|
||||||
const pmValue* value = &vset->vlist[offset];
|
|
||||||
int sts = pmExtractValue(vset->valfmt, value, desc->type, atom, type);
|
|
||||||
if (sts < 0) {
|
|
||||||
if (pmDebugOptions.appl0)
|
|
||||||
fprintf(stderr, "Error: cannot extract %s instance %d value: %s\n",
|
|
||||||
pcp->names[metric], inst, pmErrStr(sts));
|
|
||||||
memset(atom, 0, sizeof(pmAtomValue));
|
|
||||||
}
|
|
||||||
return atom;
|
|
||||||
}
|
|
||||||
|
|
||||||
pmAtomValue* Metric_instance(Metric metric, int inst, int offset, pmAtomValue* atom, int type) {
|
|
||||||
|
|
||||||
pmValueSet* vset = pcp->result->vset[metric];
|
|
||||||
if (!vset || vset->numval <= 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* fast-path using heuristic offset based on expected location */
|
|
||||||
if (offset >= 0 && offset < vset->numval && inst == vset->vlist[offset].inst)
|
|
||||||
return Metric_extract(metric, inst, offset, vset, atom, type);
|
|
||||||
|
|
||||||
/* slow-path using a linear search for the requested instance */
|
|
||||||
for (int i = 0; i < vset->numval; i++) {
|
|
||||||
if (inst == vset->vlist[i].inst)
|
|
||||||
return Metric_extract(metric, inst, i, vset, atom, type);
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Iterate over a set of instances (incl PM_IN_NULL)
|
|
||||||
* returning the next instance identifier and offset.
|
|
||||||
*
|
|
||||||
* Start it off by passing offset -1 into the routine.
|
|
||||||
*/
|
|
||||||
bool Metric_iterate(Metric metric, int* instp, int* offsetp) {
|
|
||||||
if (!pcp->result)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
pmValueSet* vset = pcp->result->vset[metric];
|
|
||||||
if (!vset || vset->numval <= 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int offset = *offsetp;
|
|
||||||
offset = (offset < 0) ? 0 : offset + 1;
|
|
||||||
if (offset > vset->numval - 1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
*offsetp = offset;
|
|
||||||
*instp = vset->vlist[offset].inst;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Switch on/off a metric for value fetching (sampling) */
|
|
||||||
void Metric_enable(Metric metric, bool enable) {
|
|
||||||
pcp->fetch[metric] = enable ? pcp->pmids[metric] : PM_ID_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Metric_enabled(Metric metric) {
|
|
||||||
return pcp->fetch[metric] != PM_ID_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Metric_enableThreads(void) {
|
|
||||||
pmValueSet* vset = xCalloc(1, sizeof(pmValueSet));
|
|
||||||
vset->vlist[0].inst = PM_IN_NULL;
|
|
||||||
vset->vlist[0].value.lval = 1;
|
|
||||||
vset->valfmt = PM_VAL_INSITU;
|
|
||||||
vset->numval = 1;
|
|
||||||
vset->pmid = pcp->pmids[PCP_CONTROL_THREADS];
|
|
||||||
|
|
||||||
pmResult* result = xCalloc(1, sizeof(pmResult));
|
|
||||||
result->vset[0] = vset;
|
|
||||||
result->numpmid = 1;
|
|
||||||
|
|
||||||
int sts = pmStore(result);
|
|
||||||
if (sts < 0 && pmDebugOptions.appl0)
|
|
||||||
fprintf(stderr, "Error: cannot enable threads: %s\n", pmErrStr(sts));
|
|
||||||
|
|
||||||
pmFreeResult(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Metric_fetch(struct timeval* timestamp) {
|
|
||||||
if (pcp->result) {
|
|
||||||
pmFreeResult(pcp->result);
|
|
||||||
pcp->result = NULL;
|
|
||||||
}
|
|
||||||
int sts = pmFetch(pcp->totalMetrics, pcp->fetch, &pcp->result);
|
|
||||||
if (sts < 0) {
|
|
||||||
if (pmDebugOptions.appl0)
|
|
||||||
fprintf(stderr, "Error: cannot fetch metric values: %s\n",
|
|
||||||
pmErrStr(sts));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (timestamp)
|
|
||||||
*timestamp = pcp->result->timestamp;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Platform_addMetric(Metric id, const char* name) {
|
|
||||||
unsigned int i = (unsigned int)id;
|
unsigned int i = (unsigned int)id;
|
||||||
|
|
||||||
if (i >= PCP_METRIC_COUNT && i >= pcp->totalMetrics) {
|
if (i >= PCP_METRIC_COUNT && i >= pcp->totalMetrics) {
|
||||||
|
@ -500,31 +328,31 @@ void Platform_init(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set proc.control.perclient.threads to 1 for live contexts */
|
/* set proc.control.perclient.threads to 1 for live contexts */
|
||||||
Metric_enableThreads();
|
PCPMetric_enableThreads();
|
||||||
|
|
||||||
/* extract values needed for setup - e.g. cpu count, pid_max */
|
/* extract values needed for setup - e.g. cpu count, pid_max */
|
||||||
Metric_enable(PCP_PID_MAX, true);
|
PCPMetric_enable(PCP_PID_MAX, true);
|
||||||
Metric_enable(PCP_BOOTTIME, true);
|
PCPMetric_enable(PCP_BOOTTIME, true);
|
||||||
Metric_enable(PCP_HINV_NCPU, true);
|
PCPMetric_enable(PCP_HINV_NCPU, true);
|
||||||
Metric_enable(PCP_PERCPU_SYSTEM, true);
|
PCPMetric_enable(PCP_PERCPU_SYSTEM, true);
|
||||||
Metric_enable(PCP_UNAME_SYSNAME, true);
|
PCPMetric_enable(PCP_UNAME_SYSNAME, true);
|
||||||
Metric_enable(PCP_UNAME_RELEASE, true);
|
PCPMetric_enable(PCP_UNAME_RELEASE, true);
|
||||||
Metric_enable(PCP_UNAME_MACHINE, true);
|
PCPMetric_enable(PCP_UNAME_MACHINE, true);
|
||||||
Metric_enable(PCP_UNAME_DISTRO, true);
|
PCPMetric_enable(PCP_UNAME_DISTRO, true);
|
||||||
|
|
||||||
for (size_t i = pcp->columns.offset; i < pcp->columns.offset + pcp->columns.count; i++)
|
for (size_t i = pcp->columns.offset; i < pcp->columns.offset + pcp->columns.count; i++)
|
||||||
Metric_enable(i, true);
|
PCPMetric_enable(i, true);
|
||||||
|
|
||||||
Metric_fetch(NULL);
|
PCPMetric_fetch(NULL);
|
||||||
|
|
||||||
for (Metric metric = 0; metric < PCP_PROC_PID; metric++)
|
for (PCPMetric metric = 0; metric < PCP_PROC_PID; metric++)
|
||||||
Metric_enable(metric, true);
|
PCPMetric_enable(metric, true);
|
||||||
Metric_enable(PCP_PID_MAX, false); /* needed one time only */
|
PCPMetric_enable(PCP_PID_MAX, false); /* needed one time only */
|
||||||
Metric_enable(PCP_BOOTTIME, false);
|
PCPMetric_enable(PCP_BOOTTIME, false);
|
||||||
Metric_enable(PCP_UNAME_SYSNAME, false);
|
PCPMetric_enable(PCP_UNAME_SYSNAME, false);
|
||||||
Metric_enable(PCP_UNAME_RELEASE, false);
|
PCPMetric_enable(PCP_UNAME_RELEASE, false);
|
||||||
Metric_enable(PCP_UNAME_MACHINE, false);
|
PCPMetric_enable(PCP_UNAME_MACHINE, false);
|
||||||
Metric_enable(PCP_UNAME_DISTRO, false);
|
PCPMetric_enable(PCP_UNAME_DISTRO, false);
|
||||||
|
|
||||||
/* first sample (fetch) performed above, save constants */
|
/* first sample (fetch) performed above, save constants */
|
||||||
Platform_getBootTime();
|
Platform_getBootTime();
|
||||||
|
@ -552,7 +380,7 @@ void Platform_setBindings(Htop_Action* keys) {
|
||||||
|
|
||||||
int Platform_getUptime(void) {
|
int Platform_getUptime(void) {
|
||||||
pmAtomValue value;
|
pmAtomValue value;
|
||||||
if (Metric_values(PCP_UPTIME, &value, 1, PM_TYPE_32) == NULL)
|
if (PCPMetric_values(PCP_UPTIME, &value, 1, PM_TYPE_32) == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
return value.l;
|
return value.l;
|
||||||
}
|
}
|
||||||
|
@ -561,7 +389,7 @@ void Platform_getLoadAverage(double* one, double* five, double* fifteen) {
|
||||||
*one = *five = *fifteen = 0.0;
|
*one = *five = *fifteen = 0.0;
|
||||||
|
|
||||||
pmAtomValue values[3] = {0};
|
pmAtomValue values[3] = {0};
|
||||||
if (Metric_values(PCP_LOAD_AVERAGE, values, 3, PM_TYPE_DOUBLE) != NULL) {
|
if (PCPMetric_values(PCP_LOAD_AVERAGE, values, 3, PM_TYPE_DOUBLE) != NULL) {
|
||||||
*one = values[0].d;
|
*one = values[0].d;
|
||||||
*five = values[1].d;
|
*five = values[1].d;
|
||||||
*fifteen = values[2].d;
|
*fifteen = values[2].d;
|
||||||
|
@ -573,7 +401,7 @@ int Platform_getMaxCPU(void) {
|
||||||
return pcp->ncpu;
|
return pcp->ncpu;
|
||||||
|
|
||||||
pmAtomValue value;
|
pmAtomValue value;
|
||||||
if (Metric_values(PCP_HINV_NCPU, &value, 1, PM_TYPE_32) != NULL)
|
if (PCPMetric_values(PCP_HINV_NCPU, &value, 1, PM_TYPE_32) != NULL)
|
||||||
pcp->ncpu = value.l;
|
pcp->ncpu = value.l;
|
||||||
else
|
else
|
||||||
pcp->ncpu = -1;
|
pcp->ncpu = -1;
|
||||||
|
@ -585,7 +413,7 @@ int Platform_getMaxPid(void) {
|
||||||
return pcp->pidmax;
|
return pcp->pidmax;
|
||||||
|
|
||||||
pmAtomValue value;
|
pmAtomValue value;
|
||||||
if (Metric_values(PCP_PID_MAX, &value, 1, PM_TYPE_32) == NULL)
|
if (PCPMetric_values(PCP_PID_MAX, &value, 1, PM_TYPE_32) == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
pcp->pidmax = value.l;
|
pcp->pidmax = value.l;
|
||||||
return pcp->pidmax;
|
return pcp->pidmax;
|
||||||
|
@ -596,7 +424,7 @@ long long Platform_getBootTime(void) {
|
||||||
return pcp->btime;
|
return pcp->btime;
|
||||||
|
|
||||||
pmAtomValue value;
|
pmAtomValue value;
|
||||||
if (Metric_values(PCP_BOOTTIME, &value, 1, PM_TYPE_64) != NULL)
|
if (PCPMetric_values(PCP_BOOTTIME, &value, 1, PM_TYPE_64) != NULL)
|
||||||
pcp->btime = value.ll;
|
pcp->btime = value.ll;
|
||||||
return pcp->btime;
|
return pcp->btime;
|
||||||
}
|
}
|
||||||
|
@ -671,7 +499,7 @@ void Platform_setSwapValues(Meter* this) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Platform_setZramValues(Meter* this) {
|
void Platform_setZramValues(Meter* this) {
|
||||||
int i, count = Metric_instanceCount(PCP_ZRAM_CAPACITY);
|
int i, count = PCPMetric_instanceCount(PCP_ZRAM_CAPACITY);
|
||||||
if (!count) {
|
if (!count) {
|
||||||
this->total = 0;
|
this->total = 0;
|
||||||
this->values[0] = 0;
|
this->values[0] = 0;
|
||||||
|
@ -682,15 +510,15 @@ void Platform_setZramValues(Meter* this) {
|
||||||
pmAtomValue* values = xCalloc(count, sizeof(pmAtomValue));
|
pmAtomValue* values = xCalloc(count, sizeof(pmAtomValue));
|
||||||
ZramStats stats = {0};
|
ZramStats stats = {0};
|
||||||
|
|
||||||
if (Metric_values(PCP_ZRAM_CAPACITY, values, count, PM_TYPE_U64)) {
|
if (PCPMetric_values(PCP_ZRAM_CAPACITY, values, count, PM_TYPE_U64)) {
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
stats.totalZram += values[i].ull;
|
stats.totalZram += values[i].ull;
|
||||||
}
|
}
|
||||||
if (Metric_values(PCP_ZRAM_ORIGINAL, values, count, PM_TYPE_U64)) {
|
if (PCPMetric_values(PCP_ZRAM_ORIGINAL, values, count, PM_TYPE_U64)) {
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
stats.usedZramOrig += values[i].ull;
|
stats.usedZramOrig += values[i].ull;
|
||||||
}
|
}
|
||||||
if (Metric_values(PCP_ZRAM_COMPRESSED, values, count, PM_TYPE_U64)) {
|
if (PCPMetric_values(PCP_ZRAM_COMPRESSED, values, count, PM_TYPE_U64)) {
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
stats.usedZramComp += values[i].ull;
|
stats.usedZramComp += values[i].ull;
|
||||||
}
|
}
|
||||||
|
@ -728,13 +556,13 @@ void Platform_getRelease(char** string) {
|
||||||
|
|
||||||
/* first call, extract just-sampled values */
|
/* first call, extract just-sampled values */
|
||||||
pmAtomValue sysname, release, machine, distro;
|
pmAtomValue sysname, release, machine, distro;
|
||||||
if (!Metric_values(PCP_UNAME_SYSNAME, &sysname, 1, PM_TYPE_STRING))
|
if (!PCPMetric_values(PCP_UNAME_SYSNAME, &sysname, 1, PM_TYPE_STRING))
|
||||||
sysname.cp = NULL;
|
sysname.cp = NULL;
|
||||||
if (!Metric_values(PCP_UNAME_RELEASE, &release, 1, PM_TYPE_STRING))
|
if (!PCPMetric_values(PCP_UNAME_RELEASE, &release, 1, PM_TYPE_STRING))
|
||||||
release.cp = NULL;
|
release.cp = NULL;
|
||||||
if (!Metric_values(PCP_UNAME_MACHINE, &machine, 1, PM_TYPE_STRING))
|
if (!PCPMetric_values(PCP_UNAME_MACHINE, &machine, 1, PM_TYPE_STRING))
|
||||||
machine.cp = NULL;
|
machine.cp = NULL;
|
||||||
if (!Metric_values(PCP_UNAME_DISTRO, &distro, 1, PM_TYPE_STRING))
|
if (!PCPMetric_values(PCP_UNAME_DISTRO, &distro, 1, PM_TYPE_STRING))
|
||||||
distro.cp = NULL;
|
distro.cp = NULL;
|
||||||
|
|
||||||
size_t length = 16; /* padded for formatting characters */
|
size_t length = 16; /* padded for formatting characters */
|
||||||
|
@ -782,7 +610,7 @@ void Platform_getRelease(char** string) {
|
||||||
|
|
||||||
char* Platform_getProcessEnv(pid_t pid) {
|
char* Platform_getProcessEnv(pid_t pid) {
|
||||||
pmAtomValue value;
|
pmAtomValue value;
|
||||||
if (!Metric_instance(PCP_PROC_ENVIRON, pid, 0, &value, PM_TYPE_STRING))
|
if (!PCPMetric_instance(PCP_PROC_ENVIRON, pid, 0, &value, PM_TYPE_STRING))
|
||||||
return NULL;
|
return NULL;
|
||||||
return value.cp;
|
return value.cp;
|
||||||
}
|
}
|
||||||
|
@ -801,7 +629,7 @@ FileLocks_ProcessData* Platform_getProcessLocks(pid_t pid) {
|
||||||
void Platform_getPressureStall(const char* file, bool some, double* ten, double* sixty, double* threehundred) {
|
void Platform_getPressureStall(const char* file, bool some, double* ten, double* sixty, double* threehundred) {
|
||||||
*ten = *sixty = *threehundred = 0;
|
*ten = *sixty = *threehundred = 0;
|
||||||
|
|
||||||
Metric metric;
|
PCPMetric metric;
|
||||||
if (String_eq(file, "cpu"))
|
if (String_eq(file, "cpu"))
|
||||||
metric = PCP_PSI_CPUSOME;
|
metric = PCP_PSI_CPUSOME;
|
||||||
else if (String_eq(file, "io"))
|
else if (String_eq(file, "io"))
|
||||||
|
@ -812,7 +640,7 @@ void Platform_getPressureStall(const char* file, bool some, double* ten, double*
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pmAtomValue values[3] = {0};
|
pmAtomValue values[3] = {0};
|
||||||
if (Metric_values(metric, values, 3, PM_TYPE_DOUBLE) != NULL) {
|
if (PCPMetric_values(metric, values, 3, PM_TYPE_DOUBLE) != NULL) {
|
||||||
*ten = values[0].d;
|
*ten = values[0].d;
|
||||||
*sixty = values[1].d;
|
*sixty = values[1].d;
|
||||||
*threehundred = values[2].d;
|
*threehundred = values[2].d;
|
||||||
|
@ -823,11 +651,11 @@ bool Platform_getDiskIO(DiskIOData* data) {
|
||||||
memset(data, 0, sizeof(*data));
|
memset(data, 0, sizeof(*data));
|
||||||
|
|
||||||
pmAtomValue value;
|
pmAtomValue value;
|
||||||
if (Metric_values(PCP_DISK_READB, &value, 1, PM_TYPE_U64) != NULL)
|
if (PCPMetric_values(PCP_DISK_READB, &value, 1, PM_TYPE_U64) != NULL)
|
||||||
data->totalBytesRead = value.ull;
|
data->totalBytesRead = value.ull;
|
||||||
if (Metric_values(PCP_DISK_WRITEB, &value, 1, PM_TYPE_U64) != NULL)
|
if (PCPMetric_values(PCP_DISK_WRITEB, &value, 1, PM_TYPE_U64) != NULL)
|
||||||
data->totalBytesWritten = value.ull;
|
data->totalBytesWritten = value.ull;
|
||||||
if (Metric_values(PCP_DISK_ACTIVE, &value, 1, PM_TYPE_U64) != NULL)
|
if (PCPMetric_values(PCP_DISK_ACTIVE, &value, 1, PM_TYPE_U64) != NULL)
|
||||||
data->totalMsTimeSpend = value.ull;
|
data->totalMsTimeSpend = value.ull;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -836,13 +664,13 @@ bool Platform_getNetworkIO(NetworkIOData* data) {
|
||||||
memset(data, 0, sizeof(*data));
|
memset(data, 0, sizeof(*data));
|
||||||
|
|
||||||
pmAtomValue value;
|
pmAtomValue value;
|
||||||
if (Metric_values(PCP_NET_RECVB, &value, 1, PM_TYPE_U64) != NULL)
|
if (PCPMetric_values(PCP_NET_RECVB, &value, 1, PM_TYPE_U64) != NULL)
|
||||||
data->bytesReceived = value.ull;
|
data->bytesReceived = value.ull;
|
||||||
if (Metric_values(PCP_NET_SENDB, &value, 1, PM_TYPE_U64) != NULL)
|
if (PCPMetric_values(PCP_NET_SENDB, &value, 1, PM_TYPE_U64) != NULL)
|
||||||
data->bytesTransmitted = value.ull;
|
data->bytesTransmitted = value.ull;
|
||||||
if (Metric_values(PCP_NET_RECVP, &value, 1, PM_TYPE_U64) != NULL)
|
if (PCPMetric_values(PCP_NET_RECVP, &value, 1, PM_TYPE_U64) != NULL)
|
||||||
data->packetsReceived = value.ull;
|
data->packetsReceived = value.ull;
|
||||||
if (Metric_values(PCP_NET_SENDP, &value, 1, PM_TYPE_U64) != NULL)
|
if (PCPMetric_values(PCP_NET_SENDP, &value, 1, PM_TYPE_U64) != NULL)
|
||||||
data->packetsTransmitted = value.ull;
|
data->packetsTransmitted = value.ull;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -946,7 +774,7 @@ Hashtable* Platform_dynamicColumns(void) {
|
||||||
const char* Platform_dynamicColumnInit(unsigned int key) {
|
const char* Platform_dynamicColumnInit(unsigned int key) {
|
||||||
PCPDynamicColumn* this = Hashtable_get(pcp->columns.table, key);
|
PCPDynamicColumn* this = Hashtable_get(pcp->columns.table, key);
|
||||||
if (this) {
|
if (this) {
|
||||||
Metric_enable(this->id, true);
|
PCPMetric_enable(this->id, true);
|
||||||
if (this->super.caption)
|
if (this->super.caption)
|
||||||
return this->super.caption;
|
return this->super.caption;
|
||||||
if (this->super.heading)
|
if (this->super.heading)
|
||||||
|
|
182
pcp/Platform.h
182
pcp/Platform.h
|
@ -9,11 +9,12 @@ Released under the GNU GPLv2, see the COPYING file
|
||||||
in the source distribution for its full text.
|
in the source distribution for its full text.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <pcp/pmapi.h>
|
#include <pcp/pmapi.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
/* use htop config.h values for these macros, not pcp values */
|
/* use htop config.h values for these macros, not pcp values */
|
||||||
#undef PACKAGE_URL
|
#undef PACKAGE_URL
|
||||||
|
@ -33,8 +34,28 @@ in the source distribution for its full text.
|
||||||
#include "ProcessLocksScreen.h"
|
#include "ProcessLocksScreen.h"
|
||||||
#include "RichString.h"
|
#include "RichString.h"
|
||||||
#include "SignalsPanel.h"
|
#include "SignalsPanel.h"
|
||||||
#include "SysArchMeter.h"
|
|
||||||
|
|
||||||
|
#include "pcp/PCPDynamicColumn.h"
|
||||||
|
#include "pcp/PCPDynamicMeter.h"
|
||||||
|
#include "pcp/PCPMetric.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct Platform_ {
|
||||||
|
int context; /* PMAPI(3) context identifier */
|
||||||
|
size_t totalMetrics; /* total number of all metrics */
|
||||||
|
const char** names; /* name array indexed by Metric */
|
||||||
|
pmID* pmids; /* all known metric identifiers */
|
||||||
|
pmID* fetch; /* enabled identifiers for sampling */
|
||||||
|
pmDesc* descs; /* metric desc array indexed by Metric */
|
||||||
|
pmResult* result; /* sample values result indexed by Metric */
|
||||||
|
PCPDynamicMeters meters; /* dynamic meters via configuration files */
|
||||||
|
PCPDynamicColumns columns; /* dynamic columns via configuration files */
|
||||||
|
struct timeval offset; /* time offset used in archive mode only */
|
||||||
|
long long btime; /* boottime in seconds since the epoch */
|
||||||
|
char* release; /* uname and distro from this context */
|
||||||
|
int pidmax; /* maximum platform process identifier */
|
||||||
|
int ncpu; /* maximum processor count configured */
|
||||||
|
} Platform;
|
||||||
|
|
||||||
extern ProcessField Platform_defaultFields[];
|
extern ProcessField Platform_defaultFields[];
|
||||||
|
|
||||||
|
@ -109,162 +130,7 @@ bool Platform_getLongOption(int opt, int argc, char** argv);
|
||||||
|
|
||||||
extern pmOptions opts;
|
extern pmOptions opts;
|
||||||
|
|
||||||
|
size_t Platform_addMetric(PCPMetric id, const char* name);
|
||||||
typedef enum Metric_ {
|
|
||||||
PCP_CONTROL_THREADS, /* proc.control.perclient.threads */
|
|
||||||
|
|
||||||
PCP_HINV_NCPU, /* hinv.ncpu */
|
|
||||||
PCP_HINV_CPUCLOCK, /* hinv.cpu.clock */
|
|
||||||
PCP_UNAME_SYSNAME, /* kernel.uname.sysname */
|
|
||||||
PCP_UNAME_RELEASE, /* kernel.uname.release */
|
|
||||||
PCP_UNAME_MACHINE, /* kernel.uname.machine */
|
|
||||||
PCP_UNAME_DISTRO, /* kernel.uname.distro */
|
|
||||||
PCP_LOAD_AVERAGE, /* kernel.all.load */
|
|
||||||
PCP_PID_MAX, /* kernel.all.pid_max */
|
|
||||||
PCP_UPTIME, /* kernel.all.uptime */
|
|
||||||
PCP_BOOTTIME, /* kernel.all.boottime */
|
|
||||||
PCP_CPU_USER, /* kernel.all.cpu.user */
|
|
||||||
PCP_CPU_NICE, /* kernel.all.cpu.nice */
|
|
||||||
PCP_CPU_SYSTEM, /* kernel.all.cpu.sys */
|
|
||||||
PCP_CPU_IDLE, /* kernel.all.cpu.idle */
|
|
||||||
PCP_CPU_IOWAIT, /* kernel.all.cpu.wait.total */
|
|
||||||
PCP_CPU_IRQ, /* kernel.all.cpu.intr */
|
|
||||||
PCP_CPU_SOFTIRQ, /* kernel.all.cpu.irq.soft */
|
|
||||||
PCP_CPU_STEAL, /* kernel.all.cpu.steal */
|
|
||||||
PCP_CPU_GUEST, /* kernel.all.cpu.guest */
|
|
||||||
PCP_CPU_GUESTNICE, /* kernel.all.cpu.guest_nice */
|
|
||||||
PCP_PERCPU_USER, /* kernel.percpu.cpu.user */
|
|
||||||
PCP_PERCPU_NICE, /* kernel.percpu.cpu.nice */
|
|
||||||
PCP_PERCPU_SYSTEM, /* kernel.percpu.cpu.sys */
|
|
||||||
PCP_PERCPU_IDLE, /* kernel.percpu.cpu.idle */
|
|
||||||
PCP_PERCPU_IOWAIT, /* kernel.percpu.cpu.wait.total */
|
|
||||||
PCP_PERCPU_IRQ, /* kernel.percpu.cpu.intr */
|
|
||||||
PCP_PERCPU_SOFTIRQ, /* kernel.percpu.cpu.irq.soft */
|
|
||||||
PCP_PERCPU_STEAL, /* kernel.percpu.cpu.steal */
|
|
||||||
PCP_PERCPU_GUEST, /* kernel.percpu.cpu.guest */
|
|
||||||
PCP_PERCPU_GUESTNICE, /* kernel.percpu.cpu.guest_nice */
|
|
||||||
PCP_MEM_TOTAL, /* mem.physmem */
|
|
||||||
PCP_MEM_FREE, /* mem.util.free */
|
|
||||||
PCP_MEM_BUFFERS, /* mem.util.bufmem */
|
|
||||||
PCP_MEM_CACHED, /* mem.util.cached */
|
|
||||||
PCP_MEM_SHARED, /* mem.util.shared */
|
|
||||||
PCP_MEM_AVAILABLE, /* mem.util.available */
|
|
||||||
PCP_MEM_SRECLAIM, /* mem.util.slabReclaimable */
|
|
||||||
PCP_MEM_SWAPCACHED, /* mem.util.swapCached */
|
|
||||||
PCP_MEM_SWAPTOTAL, /* mem.util.swapTotal */
|
|
||||||
PCP_MEM_SWAPFREE, /* mem.util.swapFree */
|
|
||||||
PCP_DISK_READB, /* disk.all.read_bytes */
|
|
||||||
PCP_DISK_WRITEB, /* disk.all.write_bytes */
|
|
||||||
PCP_DISK_ACTIVE, /* disk.all.avactive */
|
|
||||||
PCP_NET_RECVB, /* network.all.in.bytes */
|
|
||||||
PCP_NET_SENDB, /* network.all.out.bytes */
|
|
||||||
PCP_NET_RECVP, /* network.all.in.packets */
|
|
||||||
PCP_NET_SENDP, /* network.all.out.packets */
|
|
||||||
PCP_PSI_CPUSOME, /* kernel.all.pressure.cpu.some.avg */
|
|
||||||
PCP_PSI_IOSOME, /* kernel.all.pressure.io.some.avg */
|
|
||||||
PCP_PSI_IOFULL, /* kernel.all.pressure.io.full.avg */
|
|
||||||
PCP_PSI_MEMSOME, /* kernel.all.pressure.memory.some.avg */
|
|
||||||
PCP_PSI_MEMFULL, /* kernel.all.pressure.memory.full.avg */
|
|
||||||
PCP_ZFS_ARC_ANON_SIZE, /* zfs.arc.anon_size */
|
|
||||||
PCP_ZFS_ARC_BONUS_SIZE, /* zfs.arc.bonus_size */
|
|
||||||
PCP_ZFS_ARC_COMPRESSED_SIZE, /* zfs.arc.compressed_size */
|
|
||||||
PCP_ZFS_ARC_UNCOMPRESSED_SIZE, /* zfs.arc.uncompressed_size */
|
|
||||||
PCP_ZFS_ARC_C_MAX, /* zfs.arc.c_max */
|
|
||||||
PCP_ZFS_ARC_DBUF_SIZE, /* zfs.arc.dbuf_size */
|
|
||||||
PCP_ZFS_ARC_DNODE_SIZE, /* zfs.arc.dnode_size */
|
|
||||||
PCP_ZFS_ARC_HDR_SIZE, /* zfs.arc.hdr_size */
|
|
||||||
PCP_ZFS_ARC_MFU_SIZE, /* zfs.arc.mfu_size */
|
|
||||||
PCP_ZFS_ARC_MRU_SIZE, /* zfs.arc.mru_size */
|
|
||||||
PCP_ZFS_ARC_SIZE, /* zfs.arc.size */
|
|
||||||
PCP_ZRAM_CAPACITY, /* zram.capacity */
|
|
||||||
PCP_ZRAM_ORIGINAL, /* zram.mm_stat.data_size.original */
|
|
||||||
PCP_ZRAM_COMPRESSED, /* zram.mm_stat.data_size.compressed */
|
|
||||||
|
|
||||||
PCP_PROC_PID, /* proc.psinfo.pid */
|
|
||||||
PCP_PROC_PPID, /* proc.psinfo.ppid */
|
|
||||||
PCP_PROC_TGID, /* proc.psinfo.tgid */
|
|
||||||
PCP_PROC_PGRP, /* proc.psinfo.pgrp */
|
|
||||||
PCP_PROC_SESSION, /* proc.psinfo.session */
|
|
||||||
PCP_PROC_STATE, /* proc.psinfo.sname */
|
|
||||||
PCP_PROC_TTY, /* proc.psinfo.tty */
|
|
||||||
PCP_PROC_TTYPGRP, /* proc.psinfo.tty_pgrp */
|
|
||||||
PCP_PROC_MINFLT, /* proc.psinfo.minflt */
|
|
||||||
PCP_PROC_MAJFLT, /* proc.psinfo.maj_flt */
|
|
||||||
PCP_PROC_CMINFLT, /* proc.psinfo.cmin_flt */
|
|
||||||
PCP_PROC_CMAJFLT, /* proc.psinfo.cmaj_flt */
|
|
||||||
PCP_PROC_UTIME, /* proc.psinfo.utime */
|
|
||||||
PCP_PROC_STIME, /* proc.psinfo.stime */
|
|
||||||
PCP_PROC_CUTIME, /* proc.psinfo.cutime */
|
|
||||||
PCP_PROC_CSTIME, /* proc.psinfo.cstime */
|
|
||||||
PCP_PROC_PRIORITY, /* proc.psinfo.priority */
|
|
||||||
PCP_PROC_NICE, /* proc.psinfo.nice */
|
|
||||||
PCP_PROC_THREADS, /* proc.psinfo.threads */
|
|
||||||
PCP_PROC_STARTTIME, /* proc.psinfo.start_time */
|
|
||||||
PCP_PROC_PROCESSOR, /* proc.psinfo.processor */
|
|
||||||
PCP_PROC_CMD, /* proc.psinfo.cmd */
|
|
||||||
PCP_PROC_PSARGS, /* proc.psinfo.psargs */
|
|
||||||
PCP_PROC_CGROUPS, /* proc.psinfo.cgroups */
|
|
||||||
PCP_PROC_OOMSCORE, /* proc.psinfo.oom_score */
|
|
||||||
PCP_PROC_VCTXSW, /* proc.psinfo.vctxsw */
|
|
||||||
PCP_PROC_NVCTXSW, /* proc.psinfo.nvctxsw */
|
|
||||||
PCP_PROC_LABELS, /* proc.psinfo.labels */
|
|
||||||
PCP_PROC_ENVIRON, /* proc.psinfo.environ */
|
|
||||||
PCP_PROC_TTYNAME, /* proc.psinfo.ttyname */
|
|
||||||
PCP_PROC_EXE, /* proc.psinfo.exe */
|
|
||||||
PCP_PROC_CWD, /* proc.psinfo.cwd */
|
|
||||||
|
|
||||||
PCP_PROC_AUTOGROUP_ID, /* proc.autogroup.id */
|
|
||||||
PCP_PROC_AUTOGROUP_NICE, /* proc.autogroup.nice */
|
|
||||||
|
|
||||||
PCP_PROC_ID_UID, /* proc.id.uid */
|
|
||||||
PCP_PROC_ID_USER, /* proc.id.uid_nm */
|
|
||||||
|
|
||||||
PCP_PROC_IO_RCHAR, /* proc.io.rchar */
|
|
||||||
PCP_PROC_IO_WCHAR, /* proc.io.wchar */
|
|
||||||
PCP_PROC_IO_SYSCR, /* proc.io.syscr */
|
|
||||||
PCP_PROC_IO_SYSCW, /* proc.io.syscw */
|
|
||||||
PCP_PROC_IO_READB, /* proc.io.read_bytes */
|
|
||||||
PCP_PROC_IO_WRITEB, /* proc.io.write_bytes */
|
|
||||||
PCP_PROC_IO_CANCELLED, /* proc.io.cancelled_write_bytes */
|
|
||||||
|
|
||||||
PCP_PROC_MEM_SIZE, /* proc.memory.size */
|
|
||||||
PCP_PROC_MEM_RSS, /* proc.memory.rss */
|
|
||||||
PCP_PROC_MEM_SHARE, /* proc.memory.share */
|
|
||||||
PCP_PROC_MEM_TEXTRS, /* proc.memory.textrss */
|
|
||||||
PCP_PROC_MEM_LIBRS, /* proc.memory.librss */
|
|
||||||
PCP_PROC_MEM_DATRS, /* proc.memory.datrss */
|
|
||||||
PCP_PROC_MEM_DIRTY, /* proc.memory.dirty */
|
|
||||||
|
|
||||||
PCP_PROC_SMAPS_PSS, /* proc.smaps.pss */
|
|
||||||
PCP_PROC_SMAPS_SWAP, /* proc.smaps.swap */
|
|
||||||
PCP_PROC_SMAPS_SWAPPSS, /* proc.smaps.swappss */
|
|
||||||
|
|
||||||
PCP_METRIC_COUNT /* total metric count */
|
|
||||||
} Metric;
|
|
||||||
|
|
||||||
void Metric_enable(Metric metric, bool enable);
|
|
||||||
|
|
||||||
bool Metric_enabled(Metric metric);
|
|
||||||
|
|
||||||
void Metric_enableThreads(void);
|
|
||||||
|
|
||||||
bool Metric_fetch(struct timeval* timestamp);
|
|
||||||
|
|
||||||
bool Metric_iterate(Metric metric, int* instp, int* offsetp);
|
|
||||||
|
|
||||||
pmAtomValue* Metric_values(Metric metric, pmAtomValue* atom, int count, int type);
|
|
||||||
|
|
||||||
const pmDesc* Metric_desc(Metric metric);
|
|
||||||
|
|
||||||
int Metric_type(Metric metric);
|
|
||||||
|
|
||||||
int Metric_instanceCount(Metric metric);
|
|
||||||
|
|
||||||
int Metric_instanceOffset(Metric metric, int inst);
|
|
||||||
|
|
||||||
pmAtomValue* Metric_instance(Metric metric, int inst, int offset, pmAtomValue* atom, int type);
|
|
||||||
|
|
||||||
size_t Platform_addMetric(Metric id, const char* name);
|
|
||||||
|
|
||||||
void Platform_gettime_realtime(struct timeval* tv, uint64_t* msec);
|
void Platform_gettime_realtime(struct timeval* tv, uint64_t* msec);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue