From fefff80631e86f0296a2621a3699b16de60b86c6 Mon Sep 17 00:00:00 2001 From: Sohaib Date: Sat, 14 Aug 2021 17:30:19 -0400 Subject: [PATCH] PCP: PCPMetric.[ch] Mdoule Split the PCP Metric API (functions `Metric_*`) into their own module. as @BenBE suggested. --- Makefile.am | 2 + pcp/PCPDynamicColumn.c | 14 +-- pcp/PCPDynamicColumn.h | 3 +- pcp/PCPDynamicMeter.c | 25 ++-- pcp/PCPDynamicMeter.h | 5 + pcp/PCPMetric.c | 177 ++++++++++++++++++++++++++ pcp/PCPMetric.h | 179 +++++++++++++++++++++++++++ pcp/PCPProcess.c | 1 - pcp/PCPProcess.h | 2 - pcp/PCPProcessList.c | 124 ++++++++++--------- pcp/Platform.c | 274 ++++++++--------------------------------- pcp/Platform.h | 182 ++++----------------------- 12 files changed, 526 insertions(+), 462 deletions(-) create mode 100644 pcp/PCPMetric.c create mode 100644 pcp/PCPMetric.h diff --git a/Makefile.am b/Makefile.am index fc19e7c5..e5f51745 100644 --- a/Makefile.am +++ b/Makefile.am @@ -366,6 +366,7 @@ pcp_platform_headers = \ linux/ZramStats.h \ pcp/PCPDynamicColumn.h \ pcp/PCPDynamicMeter.h \ + pcp/PCPMetric.h \ pcp/PCPProcess.h \ pcp/PCPProcessList.h \ pcp/Platform.h \ @@ -379,6 +380,7 @@ pcp_platform_sources = \ linux/ZramMeter.c \ pcp/PCPDynamicColumn.c \ pcp/PCPDynamicMeter.c \ + pcp/PCPMetric.c \ pcp/PCPProcess.c \ pcp/PCPProcessList.c \ pcp/Platform.c \ diff --git a/pcp/PCPDynamicColumn.c b/pcp/PCPDynamicColumn.c index 2848490e..141978a7 100644 --- a/pcp/PCPDynamicColumn.c +++ b/pcp/PCPDynamicColumn.c @@ -14,21 +14,21 @@ in the source distribution for its full text. #include #include #include -#include #include #include #include #include -#include #include "CRT.h" #include "Macros.h" #include "Platform.h" #include "Process.h" +#include "ProcessList.h" #include "RichString.h" #include "XUtils.h" #include "pcp/PCPProcess.h" +#include "pcp/PCPMetric.h" 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) { const PCPProcess* pp = (const PCPProcess*) proc; - unsigned int type = Metric_type(this->id); + unsigned int type = PCPMetric_type(this->id); 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"); 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); size_t metric = column->id; - unsigned int type = Metric_type(metric); + unsigned int type = PCPMetric_type(metric); pmAtomValue atom1 = {0}, atom2 = {0}; - if (!Metric_instance(metric, p1->super.pid, p1->offset, &atom1, type) || - !Metric_instance(metric, p2->super.pid, p2->offset, &atom2, type)) { + if (!PCPMetric_instance(metric, p1->super.pid, p1->offset, &atom1, type) || + !PCPMetric_instance(metric, p2->super.pid, p2->offset, &atom2, type)) { if (type == PM_TYPE_STRING) { free(atom1.cp); free(atom2.cp); diff --git a/pcp/PCPDynamicColumn.h b/pcp/PCPDynamicColumn.h index 39f79358..28f3d5ca 100644 --- a/pcp/PCPDynamicColumn.h +++ b/pcp/PCPDynamicColumn.h @@ -1,7 +1,8 @@ #ifndef HEADER_PCPDynamicColumn #define HEADER_PCPDynamicColumn -#include "CRT.h" +#include + #include "DynamicColumn.h" #include "Hashtable.h" #include "Process.h" diff --git a/pcp/PCPDynamicMeter.c b/pcp/PCPDynamicMeter.c index b90511ec..430f41c9 100644 --- a/pcp/PCPDynamicMeter.c +++ b/pcp/PCPDynamicMeter.c @@ -9,15 +9,22 @@ in the source distribution for its full text. #include "pcp/PCPDynamicMeter.h" -#include +#include +#include +#include +#include +#include +#include +#include +#include -#include "Object.h" +#include "Macros.h" #include "Platform.h" -#include "ProcessList.h" #include "RichString.h" -#include "Settings.h" #include "XUtils.h" +#include "pcp/PCPMetric.h" + static PCPDynamicMetric* PCPDynamicMeter_lookupMetric(PCPDynamicMeters* meters, PCPDynamicMeter* meter, const char* 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) { 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) { @@ -291,10 +298,10 @@ void PCPDynamicMeter_updateValues(PCPDynamicMeter* this, Meter* meter) { buffer[bytes++] = '/'; /* separator */ PCPDynamicMetric* metric = &this->metrics[i]; - const pmDesc* desc = Metric_desc(metric->id); + const pmDesc* desc = PCPMetric_desc(metric->id); 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 */ continue; } @@ -362,11 +369,11 @@ void PCPDynamicMeter_display(PCPDynamicMeter* this, ATTR_UNUSED const Meter* met for (size_t i = 0; i < this->totalMetrics; i++) { PCPDynamicMetric* metric = &this->metrics[i]; - const pmDesc* desc = Metric_desc(metric->id); + const pmDesc* desc = PCPMetric_desc(metric->id); pmAtomValue atom, raw; char buffer[64]; - if (!Metric_values(metric->id, &raw, 1, desc->type)) + if (!PCPMetric_values(metric->id, &raw, 1, desc->type)) continue; pmUnits conv = desc->units; /* convert to canonical units */ diff --git a/pcp/PCPDynamicMeter.h b/pcp/PCPDynamicMeter.h index cfe488e5..3da7c35b 100644 --- a/pcp/PCPDynamicMeter.h +++ b/pcp/PCPDynamicMeter.h @@ -1,8 +1,13 @@ #ifndef HEADER_PCPDynamicMeter #define HEADER_PCPDynamicMeter +#include + #include "CRT.h" #include "DynamicMeter.h" +#include "Hashtable.h" +#include "Meter.h" +#include "RichString.h" typedef struct PCPDynamicMetric_ { diff --git a/pcp/PCPMetric.c b/pcp/PCPMetric.c new file mode 100644 index 00000000..c8cfe716 --- /dev/null +++ b/pcp/PCPMetric.c @@ -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 +#include +#include + +#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; +} diff --git a/pcp/PCPMetric.h b/pcp/PCPMetric.h new file mode 100644 index 00000000..7d625035 --- /dev/null +++ b/pcp/PCPMetric.h @@ -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 +#include +#include +#include + +/* 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 diff --git a/pcp/PCPProcess.c b/pcp/PCPProcess.c index 5407a021..fa61506f 100644 --- a/pcp/PCPProcess.c +++ b/pcp/PCPProcess.c @@ -15,7 +15,6 @@ in the source distribution for its full text. #include "CRT.h" #include "Macros.h" -#include "Platform.h" #include "Process.h" #include "ProvideCurses.h" #include "RichString.h" diff --git a/pcp/PCPProcess.h b/pcp/PCPProcess.h index 3593255b..e8440971 100644 --- a/pcp/PCPProcess.h +++ b/pcp/PCPProcess.h @@ -17,8 +17,6 @@ in the source distribution for its full text. #include "Process.h" #include "Settings.h" -#include "pcp/Platform.h" - #define PROCESS_FLAG_LINUX_CGROUP 0x00000800 #define PROCESS_FLAG_LINUX_OOM 0x00001000 diff --git a/pcp/PCPProcessList.c b/pcp/PCPProcessList.c index 8e644b07..e4f9a5fd 100644 --- a/pcp/PCPProcessList.c +++ b/pcp/PCPProcessList.c @@ -11,6 +11,7 @@ in the source distribution for its full text. #include "pcp/PCPProcessList.h" +#include #include #include #include @@ -24,12 +25,13 @@ in the source distribution for its full text. #include "Settings.h" #include "XUtils.h" +#include "pcp/PCPMetric.h" #include "pcp/PCPProcess.h" static void PCPProcessList_updateCPUcount(PCPProcessList* this) { ProcessList* pl = &(this->super); - pl->activeCPUs = Metric_instanceCount(PCP_PERCPU_SYSTEM); + pl->activeCPUs = PCPMetric_instanceCount(PCP_PERCPU_SYSTEM); unsigned int cpus = Platform_getMaxCPU(); if (cpus == pl->existingCPUs) return; @@ -54,7 +56,7 @@ static char* setUser(UsersTable* this, unsigned int uid, int pid, int offset) { return name; 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); 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) { 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 fallback; } static inline long long Metric_instance_s64(int metric, int pid, int offset, long long fallback) { 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 fallback; } static inline unsigned long Metric_instance_u32(int metric, int pid, int offset, unsigned long fallback) { 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 fallback; } static inline unsigned long long Metric_instance_u64(int metric, int pid, int offset, unsigned long long fallback) { 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 fallback; } static inline unsigned long long Metric_instance_time(int metric, int pid, int offset) { 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 0; } static inline unsigned long long Metric_instance_ONE_K(int metric, int pid, int offset) { 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 ULLONG_MAX; } static inline char Metric_instance_char(int metric, int pid, int offset, char fallback) { 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]; free(value.cp); return uchar; @@ -150,7 +152,7 @@ static void PCPProcessList_updateInfo(Process* process, int pid, int offset, cha PCPProcess* pp = (PCPProcess*) process; 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(""); String_safeStrncpy(command, value.cp, commLen); 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_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; pp->io_read_bytes = value.ull / ONE_K; 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; } - 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; pp->io_write_bytes = value.ull; 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; 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; - 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; pp->ctxt_diff = ctxt > pp->ctxt_total ? ctxt - pp->ctxt_total : 0; 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) free(string); 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; else 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) { 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') process->isKernelThread = true; Process_updateCmdline(process, NULL, 0, 0); @@ -314,7 +316,7 @@ static void PCPProcessList_updateCmdline(Process* process, int pid, int offset, 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); free(value.cp); } @@ -331,7 +333,7 @@ static bool PCPProcessList_updateProcesses(PCPProcessList* this, double period, int pid = -1, offset = -1; /* for every process ... */ - while (Metric_iterate(PCP_PROC_PID, &pid, &offset)) { + while (PCPMetric_iterate(PCP_PROC_PID, &pid, &offset)) { bool preExisting; 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) && (Process_isKernelThread(proc) == false)) { - if (Metric_enabled(PCP_PROC_SMAPS_PSS)) + if (PCPMetric_enabled(PCP_PROC_SMAPS_PSS)) PCPProcessList_updateSmaps(pp, pid, offset); } @@ -452,30 +454,30 @@ static void PCPProcessList_updateMemoryInfo(ProcessList* super) { super->usedSwap = super->totalSwap = super->sharedMem = 0; 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; - 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; - 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; - 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; - 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; - 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; const memory_t usedDiff = freeMem + super->cachedMem + sreclaimableMem + super->buffersMem; super->usedMem = (super->totalMem >= usedDiff) ? 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); else 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; - 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; - 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->usedSwap = super->totalSwap - swapFreeMem - super->cachedSwap; } @@ -547,26 +549,26 @@ static void PCPProcessList_deriveCPUTime(pmAtomValue* values) { 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]; - 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)); } -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; - 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)); for (int i = 0; i < cpus; i++) 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; - 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)); for (int i = 0; i < cpus; i++) this->percpu[i][cpumetric].d = this->values[i].d; @@ -579,27 +581,27 @@ static inline void PCPProcessList_scanZfsArcstats(PCPProcessList* this) { pmAtomValue value; 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; - 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; - 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; - 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; - 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; - 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; - 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; - 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; - 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; - 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; - 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.other = (dbufSize + dnodeSize + bonusSize) / ONE_K; @@ -651,34 +653,34 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { bool enabled = !pauseProcessUpdate; 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 */ 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; - Metric_enable(PCP_PROC_CGROUPS, flagged && enabled); + PCPMetric_enable(PCP_PROC_CGROUPS, flagged && enabled); 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; - Metric_enable(PCP_PROC_VCTXSW, flagged && enabled); - Metric_enable(PCP_PROC_NVCTXSW, flagged && enabled); + PCPMetric_enable(PCP_PROC_VCTXSW, flagged && enabled); + PCPMetric_enable(PCP_PROC_NVCTXSW, flagged && enabled); 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; - Metric_enable(PCP_PROC_AUTOGROUP_ID, flagged && enabled); - Metric_enable(PCP_PROC_AUTOGROUP_NICE, flagged && enabled); + PCPMetric_enable(PCP_PROC_AUTOGROUP_ID, flagged && enabled); + PCPMetric_enable(PCP_PROC_AUTOGROUP_NICE, flagged && enabled); /* Sample smaps metrics on every second pass to improve performance */ static int smaps_flag; smaps_flag = !!smaps_flag; - Metric_enable(PCP_PROC_SMAPS_PSS, smaps_flag && enabled); - Metric_enable(PCP_PROC_SMAPS_SWAP, smaps_flag && enabled); - Metric_enable(PCP_PROC_SMAPS_SWAPPSS, smaps_flag && enabled); + PCPMetric_enable(PCP_PROC_SMAPS_PSS, smaps_flag && enabled); + PCPMetric_enable(PCP_PROC_SMAPS_SWAP, smaps_flag && enabled); + PCPMetric_enable(PCP_PROC_SMAPS_SWAPPSS, smaps_flag && enabled); struct timeval timestamp; - Metric_fetch(×tamp); + PCPMetric_fetch(×tamp); double sample = this->timestamp; this->timestamp = pmtimevalToReal(×tamp); @@ -698,7 +700,7 @@ bool ProcessList_isCPUonline(const ProcessList* super, unsigned int id) { (void) super; 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 false; } diff --git a/pcp/Platform.c b/pcp/Platform.c index 5c7e6c34..97788569 100644 --- a/pcp/Platform.c +++ b/pcp/Platform.c @@ -12,26 +12,26 @@ in the source distribution for its full text. #include "pcp/Platform.h" #include +#include +#include +#include +#include #include "BatteryMeter.h" -#include "ClockMeter.h" -#include "Compat.h" #include "CPUMeter.h" +#include "ClockMeter.h" #include "DateMeter.h" #include "DateTimeMeter.h" #include "DiskIOMeter.h" +#include "DynamicColumn.h" #include "DynamicMeter.h" #include "HostnameMeter.h" #include "LoadAverageMeter.h" #include "Macros.h" -#include "MainPanel.h" #include "MemoryMeter.h" #include "Meter.h" #include "NetworkIOMeter.h" -#include "Object.h" -#include "Panel.h" #include "ProcessList.h" -#include "ProvideCurses.h" #include "Settings.h" #include "SwapMeter.h" #include "SysArchMeter.h" @@ -44,30 +44,13 @@ in the source distribution for its full text. #include "linux/ZramStats.h" #include "pcp/PCPDynamicColumn.h" #include "pcp/PCPDynamicMeter.h" -#include "pcp/PCPProcess.h" +#include "pcp/PCPMetric.h" #include "pcp/PCPProcessList.h" #include "zfs/ZfsArcMeter.h" #include "zfs/ZfsArcStats.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; 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 }; -const pmDesc* Metric_desc(Metric metric) { - 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) { +size_t Platform_addMetric(PCPMetric id, const char* name) { unsigned int i = (unsigned int)id; 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 */ - Metric_enableThreads(); + PCPMetric_enableThreads(); /* extract values needed for setup - e.g. cpu count, pid_max */ - Metric_enable(PCP_PID_MAX, true); - Metric_enable(PCP_BOOTTIME, true); - Metric_enable(PCP_HINV_NCPU, true); - Metric_enable(PCP_PERCPU_SYSTEM, true); - Metric_enable(PCP_UNAME_SYSNAME, true); - Metric_enable(PCP_UNAME_RELEASE, true); - Metric_enable(PCP_UNAME_MACHINE, true); - Metric_enable(PCP_UNAME_DISTRO, true); + PCPMetric_enable(PCP_PID_MAX, true); + PCPMetric_enable(PCP_BOOTTIME, true); + PCPMetric_enable(PCP_HINV_NCPU, true); + PCPMetric_enable(PCP_PERCPU_SYSTEM, true); + PCPMetric_enable(PCP_UNAME_SYSNAME, true); + PCPMetric_enable(PCP_UNAME_RELEASE, true); + PCPMetric_enable(PCP_UNAME_MACHINE, true); + PCPMetric_enable(PCP_UNAME_DISTRO, true); 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++) - Metric_enable(metric, true); - Metric_enable(PCP_PID_MAX, false); /* needed one time only */ - Metric_enable(PCP_BOOTTIME, false); - Metric_enable(PCP_UNAME_SYSNAME, false); - Metric_enable(PCP_UNAME_RELEASE, false); - Metric_enable(PCP_UNAME_MACHINE, false); - Metric_enable(PCP_UNAME_DISTRO, false); + for (PCPMetric metric = 0; metric < PCP_PROC_PID; metric++) + PCPMetric_enable(metric, true); + PCPMetric_enable(PCP_PID_MAX, false); /* needed one time only */ + PCPMetric_enable(PCP_BOOTTIME, false); + PCPMetric_enable(PCP_UNAME_SYSNAME, false); + PCPMetric_enable(PCP_UNAME_RELEASE, false); + PCPMetric_enable(PCP_UNAME_MACHINE, false); + PCPMetric_enable(PCP_UNAME_DISTRO, false); /* first sample (fetch) performed above, save constants */ Platform_getBootTime(); @@ -552,7 +380,7 @@ void Platform_setBindings(Htop_Action* keys) { int Platform_getUptime(void) { 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 value.l; } @@ -561,7 +389,7 @@ void Platform_getLoadAverage(double* one, double* five, double* fifteen) { *one = *five = *fifteen = 0.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; *five = values[1].d; *fifteen = values[2].d; @@ -573,7 +401,7 @@ int Platform_getMaxCPU(void) { return pcp->ncpu; 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; else pcp->ncpu = -1; @@ -585,7 +413,7 @@ int Platform_getMaxPid(void) { return pcp->pidmax; 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; pcp->pidmax = value.l; return pcp->pidmax; @@ -596,7 +424,7 @@ long long Platform_getBootTime(void) { return pcp->btime; 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; return pcp->btime; } @@ -671,7 +499,7 @@ void Platform_setSwapValues(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) { this->total = 0; this->values[0] = 0; @@ -682,15 +510,15 @@ void Platform_setZramValues(Meter* this) { pmAtomValue* values = xCalloc(count, sizeof(pmAtomValue)); 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++) 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++) 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++) stats.usedZramComp += values[i].ull; } @@ -728,13 +556,13 @@ void Platform_getRelease(char** string) { /* first call, extract just-sampled values */ 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; - 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; - 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; - 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; size_t length = 16; /* padded for formatting characters */ @@ -782,7 +610,7 @@ void Platform_getRelease(char** string) { char* Platform_getProcessEnv(pid_t pid) { 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 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) { *ten = *sixty = *threehundred = 0; - Metric metric; + PCPMetric metric; if (String_eq(file, "cpu")) metric = PCP_PSI_CPUSOME; else if (String_eq(file, "io")) @@ -812,7 +640,7 @@ void Platform_getPressureStall(const char* file, bool some, double* ten, double* return; 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; *sixty = values[1].d; *threehundred = values[2].d; @@ -823,11 +651,11 @@ bool Platform_getDiskIO(DiskIOData* data) { memset(data, 0, sizeof(*data)); 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; - 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; - 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; return true; } @@ -836,13 +664,13 @@ bool Platform_getNetworkIO(NetworkIOData* data) { memset(data, 0, sizeof(*data)); 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; - 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; - 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; - 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; return true; } @@ -946,7 +774,7 @@ Hashtable* Platform_dynamicColumns(void) { const char* Platform_dynamicColumnInit(unsigned int key) { PCPDynamicColumn* this = Hashtable_get(pcp->columns.table, key); if (this) { - Metric_enable(this->id, true); + PCPMetric_enable(this->id, true); if (this->super.caption) return this->super.caption; if (this->super.heading) diff --git a/pcp/Platform.h b/pcp/Platform.h index 3f98a733..9d0c8f53 100644 --- a/pcp/Platform.h +++ b/pcp/Platform.h @@ -9,11 +9,12 @@ Released under the GNU GPLv2, see the COPYING file in the source distribution for its full text. */ -#include #include #include #include #include +#include +#include /* use htop config.h values for these macros, not pcp values */ #undef PACKAGE_URL @@ -33,8 +34,28 @@ in the source distribution for its full text. #include "ProcessLocksScreen.h" #include "RichString.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[]; @@ -109,162 +130,7 @@ bool Platform_getLongOption(int opt, int argc, char** argv); extern pmOptions opts; - -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); +size_t Platform_addMetric(PCPMetric id, const char* name); void Platform_gettime_realtime(struct timeval* tv, uint64_t* msec);