Age | Commit message (Collapse) | Author |
|
|
|
just need to put this somewhere
|
|
I've picked some colors just to have /something/ populating these.
For now only the first two (red and cyan) are being used, but
subsequent commits will wire these up to a per-row palette
selector which the charts code will set appropriately and vcr
will need to consult when presenting the charts to png/X.
It's tempting to make the colors user-definable at run-time. But
that actually seems like a bad idea. Instead, I expect to
iterate on these until a Good Enough set of colors is arrived at,
then leave them hard-coded in the source. Why? you may ask...
well, it's simple - I want everyone using vmon to develop a
familiarity with grokking the output in a way that's consistent
and transferrable if they encounter it elsewhere, or if people
pass around the snapshots / attach them to GH/JIRA tickets etc.
We shouldn't need a decoder wheel to understand what the colors
mean to a given use case. The source defines the meaning of the
colors, and once the dust settles, it should try stay as
consistent as possible.
|
|
Preparatory commit for supporting more bar colors for non-CPU rows.
It's this or move from 4bpp(16-color) to 8bpp(256-color). 8bpp
produces significantly larger PNG files, so I'm opting for
keeping things small.
The down side is now you can't identify bar pixels in shadow,
because all text shadow pixels will be the same DARK_WHITE.
Maybe in the future I'll introduce support for picking 4bpp vs.
8bpp at runtime, then you can pick which trade-off you prefer.
|
|
This adds overlay text rendering of the per-proc mem rows.
It's not entirely complete yet, the main missing piece is the
hierarchy branches need to get drawn into the per-proc mem row.
It's not readily possible yet, since there's no way to inherit
the offset of the tree column from the cpu row-column - and
there's no way or the mem row-column to replicate the same
horizontal offset, since it lacks the other columns like
uesr/sys/wall to cumulatively get to the same offset.
|
|
|
|
|
|
|
|
Instead of assigning top-down vs. bottom-up semantics to the
layers behind vcr, let's use negative values to indicate
top-down.
This may change again in the future, but presently there's no
support for signed bar graphs within a given layer.
|
|
Not taking advantage of this yet, but may in the future as rendering
of mem (and maybe pgflts) evolves with the existing cpu bars...
|
|
The extra per-proc row showing RSS needs overlay text for at least showing
the numeric RSS KiB value, that's achieved via row-columns
This only adds and initalizes the columns, they're not being drawn anywhere
yet.
|
|
With how wide the charts can be, it's helpful to have the Row
enumeration visible at both sides, if you need to correlate
something you see at one edge with information at the opposite
one - look at the Row #.
|
|
This is necessary if we're going to actually rendering an RSS
value in overlay text.
|
|
Rather than hard-coding justification in draw_row_column() cases
by column type, the row-column instances should be able to
specify it own along with the side.
|
|
Particularly with designated struct initializers it's
particularly convenient to have the default value the zero value,
since you get that for free via silent omission.
Preparatory commit for row-columns specifying their
justification.
|
|
This is basically just an indirection table so there's somewhere
to represent row-column intersection state and instantiate
columns in muliple places from within the same row to across
different rows even differently located/justified horizontally,
while still being able to share the column's width for the
current draw/sample.
|
|
These are CPU-specific columns, so prefix them appropriately, in
preparation for memory columns accompnaying them in an additional
per-proc row.
|
|
This helps reading the precise magnitude of these numbers when large.
I considered also adding more units for the times, but I kinda
like the ability to scan the width of the time columns to see
short vs. long durations without actually reading what they
contain, as a broad-phase scan. If they were simply HH:MM:SS
it'd require scanning the colon-separated columns with enough
scrutiny to parse zeroes vs. non-zeroes...
|
|
I'd like to get thousands markers in some of the numbers produced
via snprintf in the charts, so call setlocale() with "" so it
gets set to whatever the environment has.
e.g.
LC_ALL=$LANG src/vmon
In Arch here gets my LC_ALL set to "en_US.UTF-8", which will put
commas in for thousands separators wherever the format modifier
"'" has been added.
|
|
If we're not showing the threads, the caption shouldn't mention
it.
|
|
This adds a [$n_current_threads] prefix to the argv/~threadname
part of the tree column, for non-stale processes.
It's suppressed for stale processes because we don't actually
have a meaningful count to render at that point; it'd always be
zero. This would be visible as an oddity in the snowflakes.
The count is also suppressed for non-threaded processes, leaving
a bare "[]", which may change again in the future. It seems like
noise in the chart, but it also serves to prevent an argv somehow
starting with "[N]" being ambiguous - perhaps not something worth
caring about *shrug*.
|
|
This introduces vmon_proc_t.n_current_threads, a counter
reflecting the currently non-stale number of threads in an
is_threaded process.
You could get this by walking the threads linked list and
filtering out the is_stale entries, but in preparation of showing
this count in the charts hierarchy I'm caching the incrementally
maintained count so the list doesn't need to be walked
repeatedly.
Note it's important to suppress the is_stale nodes from the
count, so the count isn't being decremented when stale nodes get
finally removed from the list - instead when nodes transition to
being stale. The count shown in charts should reflect the number
of thread rows seen at the same time (when --no-threads isn't in
use)
|
|
|
|
This is a first stab at supporting --no-threads, which is a
little awkward because of how threads must still be followed to
maintain an awareness of the potential children processes of
threads.
So in libvmon there's a flag now for neglecting monitoring of
threads, while still following them. This retains the same
libvmon topology as before, where threads were always monitored,
and threads still get their own vmon_proc_t instances in the
in-memory representation of the vmon_proc_t hierarchy.
What the libvmon flag changes is it prevents the vmon_proc_t
instances representing threads from allocating sampler states and
opening the various proc files used for sampling that information
from threads. So it reduces the number of proc files held open
when there are threaded processes monitored, and saves some
memory allocation for eliding storage for those samples.
For the charts rendering side, since libvmon's representation is
essentially unchanged with --no-threads, and actually breaks some
assumptions rendering previously made about proc_ctxt's always
being allocated for any vmon_proc_t in the tree because
these allocations are suppressed when neglecting threads, there
needs to be an awareness of --no-threads mode and a pile of
conditional goo to prevent rendering the threads both
statistically/informationally and hierarchically.
This commit adds that goo to the charts rendering while
simultaneously actually wiring up this flag to libvmon. On a
high level the primary facets of what this goo does are:
1. Suppress the effects of vmon_proc_t.is_thread nodes on the
rendered hierarchy, keeping these rows invisible, preventing
their impact on the row and depth variables, suppressing their
counting towards row counts in snowflaking of subtrees, and
suppressing their influence on the connectivity branches
normally drawn to link siblings separated by threaded
processes.
2. Bypass the usual ommission of rendering wchan and process
state on multithreaded processes. Normally we'd rely on the
main thread's rendering of these fields, but when the threads
aren't being shown, we'd like to still see at least a single
wchan and state for that main thread in the still shown
process' row. But this is barely useful, you really need to
see all the threads' wchans and states if you have any hope to
understand what multithreaded processes are doing.
I think this also highlights a shortcoming in that there's no
obvious indicator showing which processes are multithreaded
when --no-threads is in use. A subsequent commit will likely
add something like a [$threads_count] at the start of the
Argv/~ThreadName field.
|
|
Still no actual implementation yet
|
|
No actual implementation here, just flag propagation.
|
|
|
|
This will suppress showing threads in the output, and save on
much of the overhead associated with monitoring them.
Subsequent commits will augment libvmon to support this use case,
followed by charts changes to support a threads-hidden mode which
must still consider any of the threads children.
|
|
--hide-threads needs a way to tell libvmon to both follow threads
and neglect to actually sample them.
Note this will still allocate the vmon_proc_t for every thread,
but conserves in the open proc files department by not
opening/reading everything other than the children proc file for
threads - regardless of what other proc wants have been specified.
So front-ends still need to traverse threads of processes, and if
they want to collapse the children of threads as if they're all
children of the threads' parent, that's up to the front-end to do
so. In the vwm/vmon case, that's a detail for charts.c to
handle, when --hide-threads is in effect. It will have to render
the children of threads as if they're children of the threads'
parent, to hide this clusterfuck from what's visible to the user.
|
|
This is better than nothing, but the screens should be cycled in
MRU order like everything else. The way things are as-is with
the bare bones RandR integration, screens are just an array of
the underlying X type. There isn't really a vwm-native type
representing the screen, it's just an alias for the X type.
So there should be a refactor surrounding screens and a switch to
MRU order.
Anyhow, even though it's not ideal, I've been using this daily on
a multihead setup and it's a marked usability improvement.
|
|
|
|
This is an attempt to minimally support autoconfing windows to
different screens on multihead setups.
|
|
Vestigial from long ago when this all got hastily split up into separate headers
|
|
Now that threads can have children, the tree markup needs more
goo to cover those cases.
|
|
no functional difference
|
|
Long ago an assumption was made that only the main thread having
tid matching the pid would ever be the parent of children
processes.
This was an optimization done to avoid having to keep open the
/proc/$pid/task/$tid/children node for every thread being
monitored.
For the longest time this seemed to be fine, as most things
weren't forking from threaded programs, and if they were it
didn't seem to produce descendants from threads other than for
tid==pid.
But that's not the case anymore. Running `go test` on things
it's pretty apparent that go is cloning children from any old
thread and those children are under
/proc/$pid/tasks/$tid/children, and vmon is missing them from
monitoring as a result.
The bummer here is with large numbers of threads under
monitoring, there's an added fd for every one of those threads.
Each of those fds pins 4KiB in the kernel for the seq_file
buffer, it adds up.
Note this is only the libvmon side of things, there are other
assumptions in charts.c resulting in awkward rendering of this
new children-of-threads possibility. But other than some
weirdness in the visual details, it's surprisingly mostly correct
as-is.
|
|
There's potential for spending a whole lot of cycles filling a
huge time delta from the time things became paused to the current
time.
The output from that is pretty much pointless, so let's prevent
it from happening by simply bumping the sample time to the
current time whenever we're unpausing.
|
|
This shifts everything below IOWait/Idle% down one row.
|
|
|
|
Now when holding down XK_m during focus changing operations the
pointer will follow the focus, which should be handy on
multihead.
Also simply pressing Mod1+XK_m without doing anything else will
chase the currently focused window, so you can bring the pointer
where you are immediately on demand using the keyboard.
|
|
Particularly on large multi-head display setups it can be
annoying to have to find the mouse pointer after long periods of
not using it, on the rare occasion one must bring it to the
currently focused window to do a pointer operation.
This commit introduces XK_m for controlling a "chase_it" flag,
which future commits will utilize for augmenting focus-changing
operations, and maybe window configuring operations, by warping
the pointer to the center of the focused window /after/ the
augmented operation has been performed.
|
|
trivial fixup, no functional difference
|
|
|
|
|
|
|
|
These are just some potentially helpful warnings, they're not
treated as fatal... just informative regarding somewhat obviously
confused combinations.
|
|
If vmon ran a command as its child and was told to be the reaper,
we probably want to see any inherited orphans vmon becomes
responsible for reaping in the graph.
The simplest robust way to achieve this is to monitor vmon's PID
as the root instead of the pid of the command being executed.
There's an argument to be made that this is how it should always
be done when executing a command, but for now I'm only going to
do it when being the reaper. I think there's also an argument to
be made that becoming a subreaper should also be the default when
executing a command.
|
|
This adds minimal support for becoming a child subreaper.
Exited orphans are handled correctly by being identified and
ignored without triggering SIGCHLD snapshots nor exiting vmon.
A subsequent commit will make vmon monitor itself as the root pid
when reaper mode is active and vmon is parent of the command
being executed, making it possible to observe any orphans vmon
inherits as subreaper.
|
|
Beginnings of PR_SET_CHILD_SUBREAPER mode, this only adds the
CLI flags.
Becoming a subreaper is only relevant to running commands via
vmon. If the commands being executed fork/exec/daemonize or
otherwise may produce orphaned processes, they escape the
scoped hierarchical monitoring when init inherits them, so you
lose visibility into their actions once orphaned.
By becoming a subreaper, vmon can be the process inheriting those
orphans, so they may continue being monitored, as if vmon were
init, for its descendants.
|
|
This is an early stab at writing down some vmon-specific TODO
items along with some cash bounties for any frends/users
interested in hacking on this stuff for some cash on the side.
I may work on these myself, anyone interested in doing these
things and expecting to get paid _must_ email me first to avoid
racing with me or others working on the same thing. Also I am
fairly opinionated in how these things should be done, so we'll
have to discuss the details or be prepared for disappointment.
|