diff options
author | Vito Caputo <vcaputo@gnugeneration.com> | 2017-03-07 18:27:41 -0800 |
---|---|---|
committer | Vito Caputo <vcaputo@gnugeneration.com> | 2017-03-14 19:41:48 -0700 |
commit | 2c9fe3973a28504e664c5d7c9d990bc2f16c0348 (patch) | |
tree | c21704ea12434680b60d4ac15ca1ba981a711f41 | |
parent | 4c0ec19811a6192ae8c3739bd9caff7d91bb725f (diff) |
libvmon: add "sys-wide" arg for sample callbacks
We need to eventually plumb an vwm_overlays_t reference back to sample_cb,
for now we'll just obviate the need for the vwm_ptr global by plumbing the
vwm_t through.
-rw-r--r-- | src/libvmon/vmon.c | 24 | ||||
-rw-r--r-- | src/libvmon/vmon.h | 9 | ||||
-rw-r--r-- | src/overlay.c | 22 |
3 files changed, 26 insertions, 29 deletions
diff --git a/src/libvmon/vmon.c b/src/libvmon/vmon.c index 5279ab7..1995228 100644 --- a/src/libvmon/vmon.c +++ b/src/libvmon/vmon.c @@ -1123,7 +1123,7 @@ static int find_proc_in_array(vmon_t *vmon, vmon_proc_t *proc, int hint) /* simple helper for installing callbacks on the callback lists, currently only used for the per-process sample callbacks */ /* will not install the same callback function & arg combination more than once, and will not install NULL-functioned callbacks at all! */ -static int maybe_install_proc_callback(vmon_t *vmon, list_head_t *callbacks, void (*func)(vmon_t *, vmon_proc_t *, void *), void *arg) +static int maybe_install_proc_callback(vmon_t *vmon, list_head_t *callbacks, void (*func)(vmon_t *, void *, vmon_proc_t *, void *), void *arg) { if(func) { vmon_proc_callback_t *cb; @@ -1152,7 +1152,7 @@ static int maybe_install_proc_callback(vmon_t *vmon, list_head_t *callbacks, voi /* monitor a process under a given vmon instance, the public interface. * XXX note it's impossible to say "none" for wants per-process, just "inherit", if vmon_init() was told a proc_wants of "inherit" then it's like having "none" * proc_wants for all proceses, perhaps improve this if there's a pressure to support this use case */ -vmon_proc_t * vmon_proc_monitor(vmon_t *vmon, vmon_proc_t *parent, int pid, vmon_proc_wants_t wants, void (*sample_cb)(vmon_t *, vmon_proc_t *, void *), void *sample_cb_data) +vmon_proc_t * vmon_proc_monitor(vmon_t *vmon, vmon_proc_t *parent, int pid, vmon_proc_wants_t wants, void (*sample_cb)(vmon_t *, void *, vmon_proc_t *, void *), void *sample_cb_arg) { vmon_proc_t *proc; int hash = (pid % VMON_HTAB_SIZE), i; @@ -1165,7 +1165,7 @@ vmon_proc_t * vmon_proc_monitor(vmon_t *vmon, vmon_proc_t *parent, int pid, vmon list_for_each_entry(proc, &vmon->htab[hash], bucket) { /* search for the process to see if it's already monitored, we allow threads to exist with the same pid hence the additional is_thread comparison */ if(proc->pid == pid && proc->is_thread == is_thread) { - if(!maybe_install_proc_callback(vmon, &proc->sample_callbacks, sample_cb, sample_cb_data)) { + if(!maybe_install_proc_callback(vmon, &proc->sample_callbacks, sample_cb, sample_cb_arg)) { return NULL; } @@ -1215,7 +1215,7 @@ vmon_proc_t * vmon_proc_monitor(vmon_t *vmon, vmon_proc_t *parent, int pid, vmon INIT_LIST_HEAD(&proc->siblings); INIT_LIST_HEAD(&proc->threads); - if(!maybe_install_proc_callback(vmon, &proc->sample_callbacks, sample_cb, sample_cb_data)) { + if(!maybe_install_proc_callback(vmon, &proc->sample_callbacks, sample_cb, sample_cb_arg)) { free(proc); return NULL; } @@ -1256,8 +1256,8 @@ vmon_proc_t * vmon_proc_monitor(vmon_t *vmon, vmon_proc_t *parent, int pid, vmon } -/* stop monitoring a process under a given vmon instance, a caller who supplied a sample_cb & sample_cb_data pair @ monitor() must also supply it @ unmonitor! */ -void vmon_proc_unmonitor(vmon_t *vmon, vmon_proc_t *proc, void (*sample_cb)(vmon_t *, vmon_proc_t *, void *), void *sample_cb_data) +/* stop monitoring a process under a given vmon instance, a caller who supplied a sample_cb & sample_cb_arg pair @ monitor() must also supply it @ unmonitor! */ +void vmon_proc_unmonitor(vmon_t *vmon, vmon_proc_t *proc, void (*sample_cb)(vmon_t *, void *, vmon_proc_t *, void *), void *sample_cb_arg) { vmon_proc_t *child, *_child; int i; @@ -1266,7 +1266,7 @@ void vmon_proc_unmonitor(vmon_t *vmon, vmon_proc_t *proc, void (*sample_cb)(vmon vmon_proc_callback_t *cb, *_cb; list_for_each_entry_safe(cb, _cb, &proc->sample_callbacks, callbacks) { - if(cb->func == sample_cb && cb->arg == sample_cb_data) { + if(cb->func == sample_cb && cb->arg == sample_cb_arg) { list_del(&cb->callbacks); free(cb); break; @@ -1374,7 +1374,7 @@ static int sample_threads(vmon_t *vmon, list_head_t *threads) vmon_proc_callback_t *cb; list_for_each_entry(cb, &proc->sample_callbacks, callbacks) { - cb->func(vmon, proc, cb->arg); + cb->func(vmon, vmon->sample_cb_arg, proc, cb->arg); } #endif } @@ -1414,7 +1414,7 @@ static int sample_siblings(vmon_t *vmon, list_head_t *siblings) * being monitored, handy when automatically following children, an immediately relevant use case (vwm) */ list_for_each_entry(cb, &proc->sample_callbacks, callbacks) { - cb->func(vmon, proc, cb->arg); + cb->func(vmon, vmon->sample_cb_arg, proc, cb->arg); } /* transition new to non-new processes where we're responsible, this is a slight problem */ @@ -1482,7 +1482,7 @@ static int sample_siblings_pass2(vmon_t *vmon, list_head_t *siblings) sample_siblings_pass2(vmon, &proc->children); /* recurse into children, we invoke callbacks as encountered on nodes from the leaves up */ list_for_each_entry(cb, &proc->sample_callbacks, callbacks) { - cb->func(vmon, proc, cb->arg); + cb->func(vmon, vmon->sample_cb_arg, proc, cb->arg); } if(!proc->parent && proc->is_new) { /* top-level processes aren't managed by a follower/sampler, so we need to clear their is_new flag, this approach is slightly deviant from the managed case, @@ -1581,7 +1581,7 @@ int vmon_sample(vmon_t *vmon) } if(vmon->sample_cb) { - vmon->sample_cb(vmon); + vmon->sample_cb(vmon, vmon->sample_cb_arg); } /* then the per-process samplers */ @@ -1607,7 +1607,7 @@ int vmon_sample(vmon_t *vmon) sample(vmon, proc); list_for_each_entry(cb, &proc->sample_callbacks, callbacks) { - cb->func(vmon, proc, cb->arg); + cb->func(vmon, vmon->sample_cb_arg, proc, cb->arg); } /* age process, we use the presence of a parent as a flag indicating if the process is managed ala follow children/threads diff --git a/src/libvmon/vmon.h b/src/libvmon/vmon.h index 06a062b..56c7b56 100644 --- a/src/libvmon/vmon.h +++ b/src/libvmon/vmon.h @@ -217,7 +217,7 @@ struct _vmon_t; /* list of callbacks is maintained for the per-process callbacks, it's convenient to do things like update multiple dynamic contexts associated with a given process monitor (think multiple windows) */ typedef struct _vmon_proc_callback_t { - void (*func)(struct _vmon_t *, struct _vmon_proc_t *, void *); + void (*func)(struct _vmon_t *, void *, struct _vmon_proc_t *, void *); void *arg; list_head_t callbacks; } vmon_proc_callback_t; @@ -283,7 +283,8 @@ typedef struct _vmon_t { vmon_sys_wants_t activity; /* bits updated when there's activity on the respective wants (stores have changes) */ void *stores[VMON_STORE_SYS_NR]; /* stores for the sys-wide wants */ - void (*sample_cb)(struct _vmon_t *); /* callback invoked after executing the selected sys wants (once per vmon_sample() call)) */ + void (*sample_cb)(struct _vmon_t *, void *); /* callback invoked after executing the selected sys wants (once per vmon_sample() call)) */ + void *sample_cb_arg; /* user pointer for sample_cb */ char buf[8192]; /* scratch buffer for private use XXX: it may make sense to dynamically size these... */ char buf_bis[8192]; /* secondary scratch buffer for private use */ @@ -301,8 +302,8 @@ typedef struct _vmon_t { int vmon_init(vmon_t *, vmon_flags_t, vmon_sys_wants_t, vmon_proc_wants_t); void vmon_destroy(vmon_t *); -vmon_proc_t * vmon_proc_monitor(vmon_t *, vmon_proc_t *, int, vmon_proc_wants_t, void (*)(vmon_t *, vmon_proc_t *, void *), void *); -void vmon_proc_unmonitor(vmon_t *, vmon_proc_t *, void (*)(vmon_t *, vmon_proc_t *, void *), void *); +vmon_proc_t * vmon_proc_monitor(vmon_t *, vmon_proc_t *, int, vmon_proc_wants_t, void (*)(vmon_t *, void *, vmon_proc_t *, void *), void *); +void vmon_proc_unmonitor(vmon_t *, vmon_proc_t *, void (*)(vmon_t *, void *, vmon_proc_t *, void *), void *); int vmon_sample(vmon_t *); #endif diff --git a/src/overlay.c b/src/overlay.c index 2616cce..34802c2 100644 --- a/src/overlay.c +++ b/src/overlay.c @@ -91,9 +91,6 @@ static XRenderColor overlay_visible_color = { 0xffff, 0xffff, 0xffff, 0xffff }, overlay_graphb_color = { 0x0000, 0xffff, 0xffff, 0x3000 }; /* ~cyan */ -/* we need a copy of this pointer for the vmon callback :( */ -static vwm_t *vwm_ptr; - /* moves what's below a given row up above it if specified, the row becoming discarded */ static void snowflake_row(vwm_t *vwm, vwm_xwindow_t *xwin, Picture pic, int copy, int row) { @@ -726,20 +723,22 @@ static void maintain_overlay(vwm_t *vwm, vwm_xwindow_t *xwin) /* this callback gets invoked at sample time for every process we've explicitly monitored (not autofollowed children/threads) * It's where we update the cumulative data for all windows, including the graph masks, regardless of their visibility * It's also where we compose the graphs and text for visible windows into a picture ready for compositing with the window contents */ -static void proc_sample_callback(vmon_t *vmon, vmon_proc_t *proc, vwm_xwindow_t *xwin) +static void proc_sample_callback(vmon_t *vmon, void *sys_cb_arg, vmon_proc_t *proc, void *proc_cb_arg) { + vwm_t *vwm = sys_cb_arg; + vwm_xwindow_t *xwin = proc_cb_arg; //VWM_TRACE("proc=%p xwin=%p", proc, xwin); /* render the various always-updated overlays, this is the component we do regardless of the overlays mode and window visibility, * essentially the incrementally rendered/historic components */ - maintain_overlay(vwm_ptr, xwin); + maintain_overlay(vwm, xwin); /* if we've updated overlays for a mapped window, kick the compositor to do the costly parts of overlay drawing and compositing. */ - if (vwm_xwin_is_mapped(vwm_ptr, xwin)) vwm_composite_repaint_needed(vwm_ptr); + if (vwm_xwin_is_mapped(vwm, xwin)) vwm_composite_repaint_needed(vwm); } /* this callback gets invoked at sample time once "per sys" */ -static void sample_callback(vmon_t *_vmon) +static void sample_callback(vmon_t *_vmon, void *sys_cb_arg) { vmon_sys_stat_t *sys_stat = vmon.stores[VMON_STORE_SYS_STAT]; this_total = sys_stat->user + sys_stat->nice + sys_stat->system + @@ -793,15 +792,12 @@ static void init_overlay(vwm_t *vwm) { if (initialized) return; initialized = 1; - /* we stow the vwm pointer so the vmon callback can access it, rather than allocating something - * to encapsulate the xwin and vwm pointers just for the callback... */ - vwm_ptr = vwm; - /* initialize libvmon */ vmon_init(&vmon, VMON_FLAG_2PASS, VMON_WANT_SYS_STAT, (VMON_WANT_PROC_STAT | VMON_WANT_PROC_FOLLOW_CHILDREN | VMON_WANT_PROC_FOLLOW_THREADS)); vmon.proc_ctor_cb = vmon_ctor_cb; vmon.proc_dtor_cb = vmon_dtor_cb; vmon.sample_cb = sample_callback; + vmon.sample_cb_arg = vwm; gettimeofday(&this_sample, NULL); /* get all the text and graphics stuff setup for overlays */ @@ -868,7 +864,7 @@ void vwm_overlay_xwin_create(vwm_t *vwm, vwm_xwindow_t *xwin) /* add the client process to the monitoring heirarchy */ /* XXX note libvmon here maintains a unique callback for each unique callback+xwin pair, so multi-window processes work */ - xwin->monitor = vmon_proc_monitor(&vmon, NULL, pid, VMON_WANT_PROC_INHERIT, (void (*)(vmon_t *, vmon_proc_t *, void *))proc_sample_callback, xwin); + xwin->monitor = vmon_proc_monitor(&vmon, NULL, pid, VMON_WANT_PROC_INHERIT, (void (*)(vmon_t *, void *, vmon_proc_t *, void *))proc_sample_callback, xwin); /* FIXME: count_rows() isn't returning the right count sometimes (off by ~1), it seems to be related to racing with the automatic child monitoring */ /* the result is an extra row sometimes appearing below the process heirarchy */ xwin->overlay.heirarchy_end = 1 + count_rows(xwin->monitor); @@ -879,7 +875,7 @@ void vwm_overlay_xwin_create(vwm_t *vwm, vwm_xwindow_t *xwin) /* remove monitoring on the window if installed */ void vwm_overlay_xwin_destroy(vwm_t *vwm, vwm_xwindow_t *xwin) { - if (xwin->monitor) vmon_proc_unmonitor(&vmon, xwin->monitor, (void (*)(vmon_t *, vmon_proc_t *, void *))proc_sample_callback, xwin); + if (xwin->monitor) vmon_proc_unmonitor(&vmon, xwin->monitor, (void (*)(vmon_t *, void *, vmon_proc_t *, void *))proc_sample_callback, xwin); } |