summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2025-03-21 03:14:32 -0700
committerVito Caputo <vcaputo@pengaru.com>2025-03-21 03:14:32 -0700
commite06f003b8bf1f1e4a5c51c4e47d72a1349a98489 (patch)
tree0b70337745bd6014fad426f789b08fcd26b66788
parentbeee50c229ee2443a47b229f5b6db184bf87c4c8 (diff)
charts: consider threads as ancestors
Now that threads can have children, the tree markup needs more goo to cover those cases.
-rw-r--r--src/charts.c40
1 files changed, 37 insertions, 3 deletions
diff --git a/src/charts.c b/src/charts.c
index 7c5ce7b..8824662 100644
--- a/src/charts.c
+++ b/src/charts.c
@@ -413,6 +413,19 @@ static inline int proc_has_subsequent_siblings(vmon_t *vmon, vmon_proc_t *proc)
{
struct list_head *sib, *head = &vmon->processes;
+ if (proc->is_thread) {
+ /* Supporting threads having children arrived late in vwm's existence,
+ * but it indeed is a thing. */
+ assert(proc->parent && proc->parent->is_threaded);
+ head = &proc->parent->threads;
+ for (sib = proc->threads.next; sib != head; sib = sib->next) {
+ if (!(list_entry(sib, vmon_proc_t, threads)->is_stale))
+ return 1;
+ }
+
+ return 0;
+ }
+
if (proc->parent)
head = &proc->parent->children;
@@ -469,9 +482,29 @@ static void draw_tree_row(vwm_charts_t *charts, vwm_chart_t *chart, int x, int d
*/
/* find the last sibling (this has to be done due to the potential for stale siblings at the tail, and we'd rather not repeatedly check for it) */
- list_for_each_entry(sibling, &proc->parent->children, siblings) {
- if (!sibling->is_stale)
- last_sibling = sibling;
+ if (!proc->is_thread) {
+ list_for_each_entry(sibling, &proc->parent->children, siblings) {
+ if (!sibling->is_stale)
+ last_sibling = sibling;
+ }
+ } else {
+ list_for_each_entry(sibling, &proc->parent->threads, threads) {
+ if (!sibling->is_stale)
+ last_sibling = sibling;
+ }
+
+ /* now look for sibling threads with non-stale children to determine if a tee is needed, ignoring the last sibling */
+ list_for_each_entry(sibling, &proc->parent->threads, threads) {
+ /* skip stale siblings, they aren't interesting as they're invisible, and the last sibling has no bearing on wether we tee or not. */
+ if (sibling->is_stale || sibling == last_sibling)
+ continue;
+
+ /* if any of the other siblings have children which are not stale, put a tee in front of our name, but ignore stale children */
+ list_for_each_entry(child, &sibling->children, siblings) {
+ if (!child->is_stale)
+ goto needs_tee;
+ }
+ }
}
/* now look for siblings with non-stale children to determine if a tee is needed, ignoring the last sibling */
@@ -502,6 +535,7 @@ static void draw_tree_row(vwm_charts_t *charts, vwm_chart_t *chart, int x, int d
/* found a tee is necessary, all that's left is to determine if the tee is a corner and draw it accordingly, stopping the search. */
if (needs_tee) {
+needs_tee:
bar_x = (depth - 1) * (VCR_ROW_HEIGHT / 2) + 4;
/* if we're the last sibling, corner the tee by shortening the vbar */
© All Rights Reserved