summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2021-09-09 19:25:41 -0700
committerVito Caputo <vcaputo@pengaru.com>2021-09-09 19:40:15 -0700
commitb2d4629d1776dbdef9924a0ded29e733de150ccc (patch)
treedffbd58a579ec25081b60cb61dc3b6a8cf2ddc09
parenteac2122b04b68f4abf09d2584f96c8fd8c67a144 (diff)
lbvmon: expose clock_gettime(CLOCK_BOOTTIME)
Exposed as VMON_SYS_STAT_BOOTTIME, so part of VMON_WANT_SYS_STAT, in units of ticks to normalize with SYS_STAT_CPU* times. This also introduces vmon->ticks_per_sec, which callers can access as well for convenience since vmon_t is all public and this library doesn't aspire to keep anything private. It's initialized via sysconf(_SC_CLK_TCK) @ vmon_init().
-rw-r--r--src/libvmon/defs/sys_stat.def4
-rw-r--r--src/libvmon/vmon.c24
-rw-r--r--src/libvmon/vmon.h1
3 files changed, 26 insertions, 3 deletions
diff --git a/src/libvmon/defs/sys_stat.def b/src/libvmon/defs/sys_stat.def
index ef8b9a7..9d252f6 100644
--- a/src/libvmon/defs/sys_stat.def
+++ b/src/libvmon/defs/sys_stat.def
@@ -1,6 +1,10 @@
#include "_begin.def"
/* member name, symbolic constant, human label, human description (think UI/help) */
+
+ /* clock_gettime(CLOCK_BOOTTIME) */
+vmon_datum_ulonglong( boottime, SYS_STAT_BOOTTIME, "BootTime", "Time since boot (ticks)")
+
/* /proc/stat */
/* a cpu row, this is shown once for the total prefixed with "cpu ", then again for every cpu prefixed with "cpuN ", newlines terminate rows */
diff --git a/src/libvmon/vmon.c b/src/libvmon/vmon.c
index 78ad905..83d78c4 100644
--- a/src/libvmon/vmon.c
+++ b/src/libvmon/vmon.c
@@ -28,6 +28,7 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
+#include <time.h>
#include <inttypes.h>
#include <dirent.h>
#include <errno.h>
@@ -864,9 +865,11 @@ typedef enum _vmon_sys_stat_fsm_t {
/* system-wide stat sampling, things like CPU usages, stuff in /proc/stat */
static sample_ret_t sys_sample_stat(vmon_t *vmon, vmon_sys_stat_t **store)
{
- int i, len, total = 0;
- int changes = 0;
- vmon_sys_stat_fsm_t state = VMON_PARSER_STATE_SYS_STAT_CPU_PREFIX; /* this could be defined as the "VMON_PARSER_INITIAL_STATE" */
+ int i, len, total = 0;
+ int changes = 0;
+ vmon_sys_stat_fsm_t state = VMON_PARSER_STATE_SYS_STAT_CPU_PREFIX; /* this could be defined as the "VMON_PARSER_INITIAL_STATE" */
+ struct timespec ts;
+ typeof((*store)->boottime) boottime;
#define VMON_PREPARE_PARSER
#include "defs/sys_stat.def"
@@ -880,6 +883,20 @@ static sample_ret_t sys_sample_stat(vmon_t *vmon, vmon_sys_stat_t **store)
(*store)->stat_fd = openat(dirfd(vmon->proc_dir), "stat", O_RDONLY);
}
+#ifndef NSEC_PER_SEC
+#define NSEC_PER_SEC 1000000000
+#endif
+
+ /* VMON_SYS_STAT_BOOTTIME */
+ clock_gettime(CLOCK_BOOTTIME, &ts);
+ boottime = ts.tv_sec * vmon->ticks_per_sec;
+ boottime += ts.tv_nsec * vmon->ticks_per_sec / NSEC_PER_SEC;
+ if ((*store)->boottime != boottime) {
+ (*store)->boottime = boottime;
+ BITSET((*store)->changed, VMON_SYS_STAT_BOOTTIME);
+ changes++;
+ }
+
while ((len = try_pread((*store)->stat_fd, vmon->buf, sizeof(vmon->buf), total)) > 0) {
total += len;
@@ -983,6 +1000,7 @@ int vmon_init(vmon_t *vmon, vmon_flags_t flags, vmon_sys_wants_t sys_wants, vmon
vmon->flags = flags;
vmon->sys_wants = sys_wants;
vmon->proc_wants = proc_wants;
+ vmon->ticks_per_sec = sysconf(_SC_CLK_TCK);
/* here we populate the sys and proc function tables */
#define vmon_want(_sym, _name, _func) \
diff --git a/src/libvmon/vmon.h b/src/libvmon/vmon.h
index 56c7b56..cefcb43 100644
--- a/src/libvmon/vmon.h
+++ b/src/libvmon/vmon.h
@@ -276,6 +276,7 @@ typedef struct _vmon_t {
vmon_flags_t flags; /* instance flags */
vmon_sys_wants_t sys_wants; /* system-wide wants mask */
vmon_proc_wants_t proc_wants; /* inherited per-process wants mask */
+ long ticks_per_sec; /* sysconf(_SC_CLK_TCK) */
/* function tables for mapping of wants bits to functions (sys-wide and per-process) */
int (*sys_funcs[VMON_STORE_SYS_NR])(struct _vmon_t *, void **);
© All Rights Reserved