summaryrefslogtreecommitdiff
path: root/src/charts.c
AgeCommit message (Collapse)Author
20 hourscharts: fix skipped overlay render in stalls when deferredHEADmasterVito Caputo
The deferred pass only enters draw_chart() once regardless of this_sample_duration, with the idx always 0. So when this_sample_duration > 1 (stalls/repeated samples), the conditional draw_overlay_row() would only get entered in the non-deferred passes in deferred mode, which are short-circuited within draw_overlay_row() because we don't want to do render that stuff in those passes in deferred mode. The fix is trivial; always enter draw_overlay_row() for the deferred pass. This fixes a cosmetic artifact where you'd see stale / missing overlays in the hierarchy rows of output, when sample durations were falling behind schedule enough for this_sample_duration to be greater than 1.
2024-10-19vcr: pass vwm_charts_t.marker_distance ref to vcr_new()Vito Caputo
Since vcr_t implements rendering of borders and backgrounds, to such an extent that when serializing mem->png for headless mode it produces the background and border on the fly on a per-row basis, let's just give it the ability to access the marker distance in vwm_charts_t and draw the markers as needed. It feels hacky to be passing pointers to these values but I really despise repeating setters across abstractions to plumb things through, so I'm doing the stupid simple thing here.
2024-10-19charts: stub out marker APIVito Caputo
This introduces the concept of border markers intended to serve as timeline references/milestones. Here only the minimal API for setting their distance is added, nothing is actually implemented yet.
2024-10-19charts: remove shadow_row() wrapperVito Caputo
Now that this just wraps vcr_shadow_row() in a post-vcr world it's pointless, so let's get rid of it. No functional difference.
2024-10-19charts: use named define for default intervalVito Caputo
Purely cosmetic, no functional change.
2024-10-19charts/vcr: s/double/float/Vito Caputo
Double precision is unnecessary for this, use floats throughout, at least for everything vmon related.
2024-10-19charts: use multiplicative inverse in some placesVito Caputo
This is a minor trivial optimization turning some frequent divides into multiplies which are generally less costly to compute.
2024-10-08charts: use clock_gettime(CLOCK_MONOTONIC_RAW)Vito Caputo
This really needs to be a clock unaffected by ntp adjustments, which CLOCK_MONOTONIC_RAW seems to provide.
2024-10-08charts: move vwm logo / $name / Hz back to topVito Caputo
I prefer this be on its own in the upper right corner.
2024-10-08charts: introduce a scheduling "adherence" rowVito Caputo
This draws the new scheduling "adherence" metric in a row below the top IOWait/Idle% row. The headings have moved down one to cover "adherence" instead, which I think should help make the important IOWait/Idle% row more visible as well as improving headings readability. The adherence row should generally be either black or red, rarely cyan. Red indicates %age of sampling interval behind schedule for the given sample, Cyan indicates same but ahead of schedule which should be unusual/almost never happen. Infact I think the current sharing of the "close enough" epsilon as adherence truncating threshold the ahead of schedule "close enough" situations will always get truncated to zero. So it might be impossible to see any cyan adherence as-is right now. A future commit will move the '\/\/\ # %name @ Hz' heading up to the IOWait/Idle% putting it back in the upper right corner, but only that one.
2024-10-08charts: move fixed pre-hierarchy rows to a defineVito Caputo
This will likely be made more dynamic in the future, but for now there's a need to shift "rest" down another row to make room for the "adherence" row. This is a simple way to accomodate that, another preparatory commit.
2024-10-08charts: compute an "adherence" valueVito Caputo
This is an attempt to add a schedule adherence metric which a subsequent commit will plot in a row below the top IOWait/%Idle % row. Ideally the adherence metric's value would always be 0, because we're always exactly on-time with our samples. But what tends to happen is falling behind, or rarely being slightly ahead of schedule (particularly with the epsilon introduction). This metric can serve as a sort of proxy for userspace's ability to get scheduled on time, which is a useful thing to see.
2024-10-08charts: try compute a real desired_delay_usVito Caputo
This introduces a concept of a "close enough" epsilon value. Where if the attempted update's current time is within very small temporal distance from the precisely scheduled time dictated by the interval, the update will still take a sample, rather than try introduce a tiny dely the host/kernel/ppoll will likely fail to adhere to without being tardy. Previously the desired delay was just a third of the interval, with no consideration for how long sampling took. This was dead simple, but made no attempt to schedule the poll timeout to align with the next sampling deadline, and would either cause excessive wakeups, or excessive tardiness, depending on the host's speed. I think this technically also fixed a bug where this_delta wouldn't get assigned if one of the earlier conditions short-circuited the later condition where it was being assigned.
2024-10-08vcr: switch to ppoll() and return microseconds delayVito Caputo
This is mostly preparotory for having more precision in a computed delay, but is also arguably just finishing what was started when adding the _us suffixes throughout. A future commit should also rework signal stuff to only unblock signals in ppoll().
2024-10-08charts: {depth,row}=0 in draw_chart() not maintain_chart()Vito Caputo
This should have been done when draw_chart() and draw_chart_rest() were split apart making draw_chart() non-recursive. But it becomes much more glaringly obvious in a world where maintain_chart() is calling draw_chart() in multiple places.
2024-10-08charts: parameterize heading toggle in draw_columns()Vito Caputo
This is preparatory for shifting heading off row 0 which until now has been the safe assumption, but I'm intending to add an "adherence" row below the IOWait/Idle top row. The headings will be moving down to that.
2024-10-08charts: some cosmetic fixupsVito Caputo
primarily s/sampling_interval/sampling_interval_secs/ units clarification
2024-10-08charts: repeat samples on missed deadlinesVito Caputo
This applies charts->this_sample_duration by advancing and drawing the graph bars this_sample_duration times. It's a bit crufty with conditionals especially where it overlaps with deferred_pass handling... but seems to work ok in initial tests. Future work will have to add a row indicating how far we've deviated from the scheduled sample time... Maybe cyan would show how premature we were, and red how late we were. Where 100% would be the entire sample interval was exceeded, but < 100% would show our still more or less on-schedule scheduling deviations.
2024-10-05charts: compute a "sample duration" for current sampleVito Caputo
This turns the time passed since the last sample taken into a "sample duration". Ideally this would always be 1, and up until now in the main use case, vwm, it's been assumed to generally be 1 and drops in the timeline treated benign/fleeting because of the live viewing. But with the introduction of --headless and increasing use on my servers / embedded interests, this has become more problematic. In this commit the duration is only being maintained, but not applied. Subsequent commits will have to repeat the current sample in the graphs (this_sample_duration - 1) times.
2024-10-05charts: s/monitor/proc/Vito Caputo
Mechanical renaming of this vestigial name choice from when vmon_proc_t was below the "monitor". Now it's just the vmon_proc_t pointed at from the chart, so let's name accordingly. No functional change.
2024-09-29charts: clarify timeout units as microsecondsVito Caputo
This API is targeting poll() usage which implies microseconds, but let's better clarify it in naming.
2024-09-21charts: scale % bars by num_cpus when appropriateVito Caputo
For rows reflecting threads and single/non-threaded processes, let's scale the bar % by the number of cpus, so they can use the full height of the row. These tasks can't scale to multiple CPUs, so it's pointless to leave vertical space for the other cores' capacity, if present. For multi-threaded process rows, the vertical space continues to accomodate all cores. I've been on the fence about this change for a while because it increases the cognitive load of reading the graphs, now the scales are inconsistent. But when you've got 16 cores like on my AMD P14s thinkpad, combined with a row height of 16 pixels, you start wishing these rows used the full height of the row for their single-core-constrained %ages.
2024-08-24charts: s/#missed it!/# missed it!/Vito Caputo
cosmetic change; insert a space after the "#" in the string used when comm/argv can't be sampled
2024-08-13charts: experimenting with a deferred maintenance modeVito Caputo
2024-08-13charts: first stab at factoring out Xlib from charts/vmonVito Caputo
2024-07-31*: %s/heirarch/hierarch/Vito Caputo
Mechnical fix of longstanding typo I'm tired of ignoring...
2024-07-29charts: add PID column to snowflakesVito Caputo
It's actually pretty useful to see the relative PID values across snowflakes...
2024-07-28*: switch to gplv2Vito Caputo
Part of the reason for adding headless support in vmon is to facilitate embedded use cases. These are often incompatible with anti-tivoization aspects of gplv3. I am the copyright holder of all this stuff so it's entirely fine to switch to gplv2. Phil Freeman contributed one trivial patch (4183fbd), regardless I checked if he had any objections to the gplv2 switch and he had none. So here we go, gplv2 all the things.
2024-07-28charts: introduce row columnVito Caputo
2023-02-21charts: remove INFINITY (0Hz) from intervalsVito Caputo
It's nice to be able to blindly hit Mod1+Left a bunch to minimize the monitoring overhead, like when trying to preserve battery etc. But I've found myself sometimes annoyed that I've completely disabled the monitors when I reach for the overlays. This change removes the 0Hz option from the preset intervals, so now when you lower monitoring by blindly hitting Mod1+Left a bunch it'll bottom out at 1HZ. A subsequent commit will wire up disabling the monitors to an explicit vwm key combo (probably Mod1+z).
2022-02-06charts: ensure first update always samplesVito Caputo
vmon steps on this edge case, in vwm it was largely benign since nothing ever happens immediately at vwm startup. But in vmon you do things monitor commands which might immediately send SIGUSR1 to vmon for .png snapshots, producing an empty .png because the first update didn't sample because the time delta hadn't passed. This change just maintains a "primed" charts flag to ensure the initial charts update always samples. This way if got_sigusr1 is already set on the first iteration, at least the first charts update will have sampled and composited *something*.
2021-09-21charts: Wall=??s if proc_stat->start is > boottimeVito Caputo
Since libvmon samples the sys_wants before proc_wants, it's entirely possible the proc_stat->start will be later than sys_stat->boottime by the time a given process gets sampled. Simply treat this analogous to being unable to sample the start, either of which will only leave the Wall as ??s in the highly ephemeral short-lived process scenario. In the > boottime case, the next sample for the same process would have start <= boottime
2021-09-20charts: fixup VWM_COLUMN_PROC_TREE indentationVito Caputo
Tidying some vestigial cruft from the pre-VWM_COLUMN* transition, still feels relatively crufty and fragile, but this is about all I have time for spending on this at the moment...
2021-09-13charts: show ??s when proc_stat->start is unsetVito Caputo
When libvmon fails to successfully sample proc_stat, it will leave this value as 0, which isn't really otherwise a normal process start value. Handle this by producing "??s" for the Wall time normally derived from (sys_stat->boottime - proc_stat->start), to prevent producing an incorrect Wall time equal to sys_stat->boottime. There should probably be a more robust means of communicating these libvmon sampling failures to vwm/vmon, but I've thus far been resisting adding something like an errno to every sample store, or worse every sample store's datum. It's kind of non-trivial to do without bloating the sample stores, especially since the stores consolidate multiple proc files under a single store/want. Having a single errno in the store would prevent letting the valid portions of the store be usable while ignoring the errored portions. Perhaps just a per-store errno with a bitfield to indicate which subset are errored would suffice...
2021-09-12charts: kludgey fixup of scribbled columnsVito Caputo
2021-09-12charts: refactor overlay text to @runtime columnsVito Caputo
This is a first pass at cleaning up the overlay content rendering with an eye towards enabling runtime configuration of which columns are present and their layout. Nothing is runtime configurable yet, but this changes the drawing to at least be data-driven using two arrays of column structs, one for the list of active processes in the upper portion of the chart, and another for the lower "snowflakes" exited processes/threads portion.
2021-09-12charts: don't show argv for threadsVito Caputo
comm is where the thread name will be if set, and when set it can be awkward to then see the process' argv following the thread name. This reduces the amount of clutter and visual noise for threaded processes...
2021-09-12charts: darken shadow by bumping opacity a bitVito Caputo
2021-08-26charts: use composed height pixmap/ximage rendersVito Caputo
Was using the underlying chart dimensions which mirror the window dimensions, which worked fine but this wastes less space in the produced images when there's not much vertical content.
2021-08-26charts: add name to charts overlayVito Caputo
Currently only vmon wires this up to --name, but vwm could get the window title of the window being overlayed and pass that in if set...
2021-08-25charts: add vwm_chart_render_as_{pixmap,ximage}()Vito Caputo
Preparatory work for supporting --snapshot-on-sigchld to vmon; add a way to access a chart's pixels outside of the X server.
2021-01-03charts: round up Hz integral of sampling intervalVito Caputo
Cosmetic change, the plain truncation would occasionally result in unexpected Hz values in the charts like 59Hz particularly using vmon w/arbitrary --hertz values.
2019-09-23charts: introduce snprintf helper snpf()Vito Caputo
Cleanup previous commit that littered MIN length clamping everywhere %n was being used w/snprintf. Removed the %n usage altogether and just clamps the return value out of snprintf to the buffer size minus one for the null terminator. The standard C library has such awful warts :/
2019-07-14charts: clamp %n length to buffer sizeVito Caputo
It appears I overlooked that %n returns the length that would have been printed regardless of the destination buffer size, not what was actually written. The man page is misleading here: n The number of characters written so far is stored into the integer pointed to by the corresponding argument. That argument shall be an int *, or variant whose size matches the (optionally) supplied integer length modifier. No argu‐ ment is converted. (This specifier is not supported by the bionic C library.) The behavior is undefined if the conver‐ sion specification includes any flags, a field width, or a precision. In testing, it isn't the count of what's actually written. It's oblivious of truncated output scenarios where the output buffer has been exhausted before reaching the %n. The man page should be clarified here. This commit does the simplest thing and simply clamps the length to the destination buffer - 1 (for the \0). %n is being used to avoid needing an strlen() in this somewhat hot path, but it might make sense to instead use the snprintf return value similarly clamped instead of %n since %n isn't doing what was expected.
2018-10-23*: update copyright lines to include 2018Vito Caputo
2017-12-29charts: fix ancestor siblings check segfaultVito Caputo
This loop assumed ancestor->parent was !NULL, and that's not necessarily always true. Due to these circular linked lists from the kernel's list.h, they're not simply NULL delimited and we need the pointer to the actual head to detect the end of the list. In libvmon, the head for the siblings list is either the parent proc's children member, or the processes member of the vmon struct. It may be more elegant to switch to always having a root proc in libvmon, even if it's just synthetic, for simplifying this crap. But for now, just determine which head is relevant and check against it for loop termination. Under some heavy parallel kernel compilations I was seeing occasional vwm segfaults, and the addr2line of the ip in dmesg mapped to this particular loop. I'm assuming the ancestor walk landed on a top-level process and then this sibling detection tried dereferencing the top-level proc's NULL parent and boom, segfault.
2017-03-27*: update email address: s/gnugeneration/pengaru/Vito Caputo
2017-03-27charts: don't copy or free zero chartsVito Caputo
This was mixed up a bit in the cleanups... charts of !width represent the uninitialized charts, so don't copy or free them instead of inhibiting just the copy.
2017-03-27charts: reduce CHART_MAX_ARGC from 512 to 64Vito Caputo
`make tags` in the linux kernel revealed that XDrawText can return a BadLength error, which is not mentioned in the man page. Glancing at the xorg-server source for doPolyText() this is found: 1192 else { /* print a string */ 1193 1194 unsigned char *pNextElt; 1195 1196 pNextElt = c->pElt + TextEltHeader + (*c->pElt) * itemSize; 1197 if (pNextElt > c->endReq) { 1198 err = BadLength; 1199 goto bail; 1200 } So there appears to bea fairly arbitrary ceiling on how many items one can pass to XDrawText, and it probably depends on the cumulative length of the individual items overflowing the maximum request length. Well.. that's lame, and shrinking the maximum items makes it less likely to trip over this in practice, but it probably just takes a long enough individual item to trigger it again. I had erred on the side of "excessively long" assuming XDrawText would just deal and clip the text to the bounds of the destination drawable, just in case there was an argv with lots of tiny items, then that would be covered. This approach is incompatible with the potential for BadLength errors, so drastically shrinking the maximum number of items until further notice.
2017-03-25overlays: rename overlays.[ch]->charts.[ch]Vito Caputo
© All Rights Reserved