diff options
Diffstat (limited to 'src/charts.c')
-rw-r--r-- | src/charts.c | 230 |
1 files changed, 197 insertions, 33 deletions
diff --git a/src/charts.c b/src/charts.c index aeacb18..9daa1b5 100644 --- a/src/charts.c +++ b/src/charts.c @@ -84,6 +84,7 @@ typedef enum _vwm_column_type_t { VWM_COLUMN_PROC_WCHAN, VWM_COLUMN_PROC_STATE, VWM_COLUMN_PROC_RSS, + VWM_COLUMN_PROC_PGFLT, VWM_COLUMN_CNT } vwm_column_type_t; @@ -99,14 +100,23 @@ typedef enum _vwm_justify_t { VWM_JUSTIFY_CENTER, VWM_JUSTIFY_LEFT, VWM_JUSTIFY_RIGHT, + VWM_JUSTIFY_UNIFORM, VWM_JUSTIFY_CNT } vwm_justify_t; +/* extra indentation to apply (added to shift rowsub fields)*/ +typedef enum _vwm_indent_t { + VWM_INDENT_NONE, + VWM_INDENT_ROWSUB, + VWM_INDENT_CNT +} vwm_indent_t; + typedef struct _vwm_column_t { /* TODO: make the columns configurable and add more description/toggled state here */ unsigned enabled:1; vwm_column_type_t type; int width; + int last_offset; } vwm_column_t; /* a row-column is a row's instance of a column, to facilitate rows that want to reference a column multiple times, @@ -119,6 +129,7 @@ typedef struct _vwm_row_column_t { vwm_column_t *column; vwm_side_t side; vwm_justify_t justify; + vwm_indent_t indent; } vwm_row_column_t; /* everything needed by the per-window chart's context */ @@ -145,8 +156,10 @@ typedef struct _vwm_chart_t { vwm_row_column_t top_row_columns[CHART_MAX_COLUMNS]; /* "top" columns in the chart (vwm logo, hz) */ vwm_row_column_t proc_cpu_row_columns[CHART_MAX_COLUMNS]; vwm_row_column_t proc_mem_row_columns[CHART_MAX_COLUMNS]; + vwm_row_column_t proc_flt_row_columns[CHART_MAX_COLUMNS]; vwm_row_column_t snowflake_cpu_row_columns[CHART_MAX_COLUMNS]; /* per-proc+thread CPU columns in the snowflaked rows */ vwm_row_column_t snowflake_mem_row_columns[CHART_MAX_COLUMNS]; /* per-proc Memory columns in the snowflaked rows */ + vwm_row_column_t snowflake_flt_row_columns[CHART_MAX_COLUMNS]; /* per-proc PgFlt columns in the snowflaked rows */ } vwm_chart_t; /* space we need for every process being monitored */ @@ -156,9 +169,16 @@ typedef struct _vwm_perproc_ctxt_t { typeof(((vmon_proc_stat_t *)0)->stime) last_stime; typeof(((vmon_proc_stat_t *)0)->utime) utime_delta; typeof(((vmon_proc_stat_t *)0)->stime) stime_delta; + typeof(((vmon_proc_stat_t *)0)->rss) max_rss; typeof(((vmon_proc_stat_t *)0)->rss) prev_rss; typeof(((vmon_proc_stat_t *)0)->rss) rss; int rss_log2_delta; + typeof(((vmon_proc_stat_t *)0)->majflt) prev_majflt; + typeof(((vmon_proc_stat_t *)0)->majflt) majflt; + int majflt_log2_delta; + typeof(((vmon_proc_stat_t *)0)->minflt) prev_minflt; + typeof(((vmon_proc_stat_t *)0)->minflt) minflt; + int minflt_log2_delta; int row; } vwm_perproc_ctxt_t; @@ -378,6 +398,7 @@ static int count_rows(vmon_proc_t *proc, unsigned no_threads) if (!proc->is_thread) { count++; // add the mem row + count++; // add the flt row list_for_each_entry(child, &proc->threads, threads) count += count_rows(child, no_threads); } @@ -468,9 +489,9 @@ static void print_argv(const vwm_charts_t *charts, const vwm_chart_t *chart, int /* determine if a given process has subsequent siblings in the hierarchy */ -static inline int proc_has_subsequent_siblings(vwm_charts_t *charts, vmon_proc_t *proc) +static inline int proc_has_subsequent_siblings(const vwm_charts_t *charts, const vmon_proc_t *proc) { - struct list_head *sib, *head = &charts->vmon.processes; + const struct list_head *sib, *head = &charts->vmon.processes; if (proc->is_thread) { if (!charts->no_threads) { @@ -509,11 +530,31 @@ static unsigned interval_as_hz(vwm_charts_t *charts) /* draw a process' row slice of a process tree */ -static void draw_tree_row(vwm_charts_t *charts, vwm_chart_t *chart, int x, int depth, int row, const vmon_proc_t *proc, int *res_width) +static void draw_tree_row(vwm_charts_t *charts, vwm_chart_t *chart, int x, int depth, int row, int rowsub, const vmon_proc_t *proc, int *res_width) { int bar_x = 0, bar_y = (row + 1) * VCR_ROW_HEIGHT; vmon_proc_t *child, *sibling, *last_sibling = NULL; + if (rowsub) { + /* with the advent of rowsub this does need to hook up the potential tree lines across the top rowsub rows */ + list_for_each_entry(sibling, &proc->children, siblings) { + if (sibling->is_stale) + continue; + + if (list_empty(&sibling->children) && (list_empty(&sibling->threads) || charts->no_threads)) + continue; + + if (proc_has_subsequent_siblings(charts, sibling)) { + bar_x = depth * (VCR_ROW_HEIGHT / 2) + 4; + vcr_draw_ortho_line(chart->vcr, VCR_LAYER_TEXT, + x + bar_x, bar_y - VCR_ROW_HEIGHT, /* dst x1, y1 */ + x + bar_x, bar_y); /* dst x2, y2 (vertical line) */ + + break; + } + } + } + /* only if this process isn't the root process @ the window shall we consider all relational drawing conditions */ if (proc == chart->proc) return; @@ -593,7 +634,7 @@ static void draw_tree_row(vwm_charts_t *charts, vwm_chart_t *chart, int x, int d } /* if we still don't think we need a tee, check if there are threads */ - if (!needs_tee) { + if (!needs_tee && !charts->no_threads) { list_for_each_entry(child, &sibling->threads, threads) { if (!child->is_stale) { needs_tee = 1; @@ -609,18 +650,22 @@ needs_tee: /* if we're the last sibling, corner the tee by shortening the vbar */ if (proc == last_sibling) { - vcr_draw_ortho_line(chart->vcr, VCR_LAYER_TEXT, - x + bar_x, bar_y - VCR_ROW_HEIGHT, /* dst x1, y1 */ - x + bar_x, bar_y - 4); /* dst x2, y2 (vertical bar) */ + if (!rowsub) { + vcr_draw_ortho_line(chart->vcr, VCR_LAYER_TEXT, + x + bar_x, bar_y - VCR_ROW_HEIGHT, /* dst x1, y1 */ + x + bar_x, bar_y - 4); /* dst x2, y2 (vertical bar) */ + } } else { vcr_draw_ortho_line(chart->vcr, VCR_LAYER_TEXT, x + bar_x, bar_y - VCR_ROW_HEIGHT, /* dst x1, y1 */ x + bar_x, bar_y); /* dst x2, y2 (vertical bar) */ } - vcr_draw_ortho_line(chart->vcr, VCR_LAYER_TEXT, - x + bar_x, bar_y - 4, /* dst x1, y1 */ - x + bar_x + 2, bar_y - 4); /* dst x2, y2 (horizontal bar) */ + if (!rowsub) { + vcr_draw_ortho_line(chart->vcr, VCR_LAYER_TEXT, + x + bar_x, bar_y - 4, /* dst x1, y1 */ + x + bar_x + 4, bar_y - 4); /* dst x2, y2 (horizontal bar) */ + } /* terminate the outer sibling loop upon drawing the tee... */ break; @@ -635,7 +680,7 @@ needs_tee: /* draw a proc row according to the columns configured in columns, * row==0 is treated specially as the heading row */ -static void draw_row_columns(vwm_charts_t *charts, vwm_chart_t *chart, vwm_row_column_t *row_columns, int heading, int depth, int row, const vmon_proc_t *proc) +static void draw_row_columns(vwm_charts_t *charts, vwm_chart_t *chart, vwm_row_column_t *row_columns, int heading, int depth, int row, int rowsub, const vmon_proc_t *proc) { vmon_sys_stat_t *sys_stat = charts->vmon.stores[VMON_STORE_SYS_STAT]; vmon_proc_stat_t *proc_stat = proc->stores[VMON_STORE_PROC_STAT]; @@ -651,6 +696,17 @@ static void draw_row_columns(vwm_charts_t *charts, vwm_chart_t *chart, vwm_row_c if (!c || !c->enabled) continue; + switch (rc->indent) { + case VWM_INDENT_NONE: + break; + case VWM_INDENT_ROWSUB: + if (rowsub) + left += 2 * VCR_ROW_HEIGHT; + break; + default: + assert(0); + } + /* XXX FIXME: i don't constrain columns using a clip mask or restrained drawing, so they can scribble * on neighboring cells, this is especially problematic with long ARGVs like when compiling. * As a kludge to work around this for now, clear the column's area immediately before drawing it, @@ -723,8 +779,15 @@ static void draw_row_columns(vwm_charts_t *charts, vwm_chart_t *chart, vwm_row_c assert(rc->side == VWM_SIDE_LEFT); /* XXX: technically SIDE_RIGHT could work, but doesn't currently */ - draw_tree_row(charts, chart, left, depth, row, proc, &width); + /* draw_tree_row() needs to be augmented to do the right thing in multi-rows; I'm not sure what that means yet. + */ + draw_tree_row(charts, chart, rc->justify == VWM_JUSTIFY_UNIFORM ? c->last_offset : left, depth, row, rowsub, proc, &width); + if (rc->justify == VWM_JUSTIFY_UNIFORM) + left = c->last_offset; + + c->last_offset = left; left += width; + break; } @@ -791,7 +854,22 @@ static void draw_row_columns(vwm_charts_t *charts, vwm_chart_t *chart, vwm_row_c assert(!proc->is_thread); /* why are we printing RSS for threads? */ - str_len = snpf(str, sizeof(str), "%'u KiB ^", proc_stat->rss * (4096 / 1024)); + str_len = snpf(str, sizeof(str), "%'llu KiB (%'llu Max)", + (unsigned long long)proc_stat->rss * (4096 / 1024), + (unsigned long long)proc_ctxt->max_rss * (4096 / 1024)); + + break; + } + + case VWM_COLUMN_PROC_PGFLT: { /* print the process' page faults */ + if (heading) /* page faults don't get a heading currently, as it's always below the process row and considered obvious */ + break; + + assert(!proc->is_thread); /* do page faults get accounted per-thread ? */ + + str_len = snpf(str, sizeof(str), "%'llu MajFlts, %'llu MinFlts", + (unsigned long long)proc_stat->majflt, + (unsigned long long)proc_stat->minflt); break; } @@ -840,11 +918,17 @@ static void draw_row_columns(vwm_charts_t *charts, vwm_chart_t *chart, vwm_row_c xpos += (c->width - str_width) / 2; break; + case VWM_JUSTIFY_UNIFORM: + xpos = c->last_offset; + break; + default: assert(0); } vcr_draw_text(chart->vcr, VCR_LAYER_TEXT, xpos, row, strs, 1, NULL); + + c->last_offset = xpos; } if (advance) { @@ -924,21 +1008,26 @@ static void draw_overlay_row(vwm_charts_t *charts, vwm_chart_t *chart, vmon_proc /* skip if obviously unnecessary (this can be further improved, but this makes a big difference as-is) */ if (!deferred_pass && !chart->redraw_needed && !columns_changed(charts, chart, chart->proc_cpu_columns, row, proc) && - (proc->is_thread || !columns_changed(charts, chart, chart->proc_mem_columns, row + 1, proc))) + (proc->is_thread || !columns_changed(charts, chart, chart->proc_mem_columns, row /* FIXME FIXME */, proc))) return; if (!proc->is_new) { /* XXX for now always clear the row, this should be capable of being optimized in the future (if the datums driving the text haven't changed...) */ vcr_clear_row(chart->vcr, VCR_LAYER_TEXT, row, -1, -1); - if (!proc->is_thread) + if (!proc->is_thread) { vcr_clear_row(chart->vcr, VCR_LAYER_TEXT, row + 1, -1, -1); + vcr_clear_row(chart->vcr, VCR_LAYER_TEXT, row + 2, -1, -1); + } } - draw_row_columns(charts, chart, chart->proc_cpu_row_columns, 0 /* heading */, depth, row, proc); + draw_row_columns(charts, chart, chart->proc_cpu_row_columns, 0 /* heading */, depth, row, 0, proc); vcr_shadow_row(chart->vcr, VCR_LAYER_TEXT, row); if (!proc->is_thread) { - draw_row_columns(charts, chart, chart->proc_mem_row_columns, 0 /* heading */, depth, row + 1, proc); + draw_row_columns(charts, chart, chart->proc_mem_row_columns, 0 /* heading */, depth, row + 1, 1, proc); vcr_shadow_row(chart->vcr, VCR_LAYER_TEXT, row + 1); + + draw_row_columns(charts, chart, chart->proc_flt_row_columns, 0 /* heading */, depth, row + 2, 2, proc); + vcr_shadow_row(chart->vcr, VCR_LAYER_TEXT, row + 2); } } @@ -1048,8 +1137,22 @@ static void draw_chart_rest(vwm_charts_t *charts, vwm_chart_t *chart, vmon_proc_ snowflake_row(charts, chart, (*row)); chart->snowflakes_cnt++; + /* stamp the final pgflts (and whatever else we include) into chart.text_picture */ + draw_row_columns(charts, chart, chart->snowflake_flt_row_columns, 0 /* heading */, 0 /* depth */, chart->hierarchy_end, 2, proc); + vcr_shadow_row(chart->vcr, VCR_LAYER_TEXT, chart->hierarchy_end); + + chart->hierarchy_end--; + (*row)--; + + + + mark_finish(charts, chart, (*row)); + /* extract the row from the various layers */ + snowflake_row(charts, chart, (*row)); + chart->snowflakes_cnt++; + /* stamp the final RSS (and whatever else we include) into chart.text_picture */ - draw_row_columns(charts, chart, chart->snowflake_mem_row_columns, 0 /* heading */, 0 /* depth */, chart->hierarchy_end, proc); + draw_row_columns(charts, chart, chart->snowflake_mem_row_columns, 0 /* heading */, 0 /* depth */, chart->hierarchy_end, 1, proc); vcr_shadow_row(chart->vcr, VCR_LAYER_TEXT, chart->hierarchy_end); chart->hierarchy_end--; @@ -1063,7 +1166,7 @@ static void draw_chart_rest(vwm_charts_t *charts, vwm_chart_t *chart, vmon_proc_ chart->snowflakes_cnt++; /* stamp the name (and whatever else we include) into chart.text_picture */ - draw_row_columns(charts, chart, chart->snowflake_cpu_row_columns, 0 /* heading */, 0 /* depth */, chart->hierarchy_end, proc); + draw_row_columns(charts, chart, chart->snowflake_cpu_row_columns, 0 /* heading */, 0 /* depth */, chart->hierarchy_end, 0, proc); vcr_shadow_row(chart->vcr, VCR_LAYER_TEXT, chart->hierarchy_end); chart->hierarchy_end--; @@ -1089,7 +1192,9 @@ static void draw_chart_rest(vwm_charts_t *charts, vwm_chart_t *chart, vmon_proc_ proc_ctxt->last_utime = proc_stat->utime; proc_ctxt->last_stime = proc_stat->stime; - /* TODO: this should probably be skipped if proc->is_thread? */ + /* TODO: this rss stuff should probably be skipped if proc->is_thread? */ + if (proc_stat->rss > proc_ctxt->max_rss) + proc_ctxt->max_rss = proc_stat->rss; proc_ctxt->prev_rss = proc_ctxt->rss; proc_ctxt->rss = proc_stat->rss; if (proc_ctxt->rss > proc_ctxt->prev_rss) { @@ -1098,6 +1203,20 @@ static void draw_chart_rest(vwm_charts_t *charts, vwm_chart_t *chart, vmon_proc_ proc_ctxt->rss_log2_delta = -(int)ilog2_ish(proc_ctxt->prev_rss - proc_ctxt->rss); } + proc_ctxt->prev_minflt = proc_ctxt->minflt; + proc_ctxt->minflt = proc_stat->minflt; + if (proc_ctxt->minflt > proc_ctxt->prev_minflt) + proc_ctxt->minflt_log2_delta = ilog2_ish(proc_ctxt->minflt - proc_ctxt->prev_minflt); + else + proc_ctxt->minflt_log2_delta = 0; + + proc_ctxt->prev_majflt = proc_ctxt->majflt; + proc_ctxt->majflt = proc_stat->majflt; + if (proc_ctxt->majflt > proc_ctxt->prev_majflt) + proc_ctxt->majflt_log2_delta = ilog2_ish(proc_ctxt->majflt - proc_ctxt->prev_majflt); + else + proc_ctxt->majflt_log2_delta = 0; + proc_ctxt->generation = charts->vmon.generation; } } @@ -1138,6 +1257,10 @@ static void draw_chart_rest(vwm_charts_t *charts, vwm_chart_t *chart, vmon_proc_ allocate_row(charts, chart, (*row) + 1); vcr_set_row_palette(chart->vcr, (*row) + 1, VCR_ROW_PALETTE_1); chart->hierarchy_end++; + + allocate_row(charts, chart, (*row) + 2); + vcr_set_row_palette(chart->vcr, (*row) + 2, VCR_ROW_PALETTE_2); + chart->hierarchy_end++; } /* we need a minimum of two samples before we can compute a delta to plot, @@ -1167,17 +1290,46 @@ static void draw_chart_rest(vwm_charts_t *charts, vwm_chart_t *chart, vmon_proc_ 1.f, 1.f, VCR_LAYER_GRAPHA); - } else if (proc_ctxt->rss != proc_ctxt->prev_rss) { - // fprintf(stderr, "row=%i rss_delta=%i rss=%llu\n", (*row) + 1, proc_ctxt->rss_log2_delta, proc_ctxt->rss); - draw_bars(charts, chart, *row + 1, + draw_bars(charts, chart, *row + 2, 1.f /* mult */, - proc_ctxt->rss_log2_delta < 0 ? -proc_ctxt->rss_log2_delta : 0.f, - 1.f / VCR_ROW_HEIGHT, + 1.f, + 1.f, VCR_LAYER_GRAPHB, - proc_ctxt->rss_log2_delta > 0 ? proc_ctxt->rss_log2_delta : 0.f, - 1.f / VCR_ROW_HEIGHT, + 1.f, + 1.f, VCR_LAYER_GRAPHA); + } else { + if (proc_ctxt->rss != proc_ctxt->prev_rss) { + // fprintf(stderr, "row=%i rss_delta=%i rss=%llu\n", (*row) + 1, proc_ctxt->rss_log2_delta, proc_ctxt->rss); + draw_bars(charts, chart, *row + 1, + 1.f /* mult */, + proc_ctxt->rss_log2_delta < 0 ? -proc_ctxt->rss_log2_delta : 0.f, + 1.f / VCR_ROW_HEIGHT, + VCR_LAYER_GRAPHB, + proc_ctxt->rss_log2_delta > 0 ? proc_ctxt->rss_log2_delta : 0.f, + 1.f / VCR_ROW_HEIGHT, + VCR_LAYER_GRAPHA); + } + + if (proc_ctxt->majflt != proc_ctxt->prev_majflt || + proc_ctxt->minflt != proc_ctxt->prev_minflt) { + // fprintf(stderr, "row=%i rss_delta=%i rss=%llu\n", (*row) + 1, proc_ctxt->rss_log2_delta, proc_ctxt->rss); + draw_bars(charts, chart, *row + 2, + 1.f /* mult */, + proc_ctxt->majflt_log2_delta > 0 ? proc_ctxt->majflt_log2_delta : 0.f, + 1.f / VCR_ROW_HEIGHT, + VCR_LAYER_GRAPHB, + proc_ctxt->minflt_log2_delta > 0 ? proc_ctxt->minflt_log2_delta : 0.f, + 1.f / VCR_ROW_HEIGHT, + VCR_LAYER_GRAPHA); + } } + /* TODO TODO TODO */ + /* TODO TODO TODO */ + /* TODO TODO TODO */ +//#error "pagfaults" + /* TODO TODO TODO */ + /* TODO TODO TODO */ } } @@ -1187,8 +1339,10 @@ static void draw_chart_rest(vwm_charts_t *charts, vwm_chart_t *chart, vmon_proc_ /* note these are suppressed for --no-threads */ (*row)++; - if (!proc->is_thread) + if (!proc->is_thread) { (*row)++; /* per-proc RSS row */ + (*row)++; /* per-proc flts row */ + } (*depth)++; } @@ -1248,13 +1402,13 @@ static void draw_chart(vwm_charts_t *charts, vwm_chart_t *chart, vmon_proc_t *pr if (sample_duration_idx == (charts->this_sample_duration - 1)) { if (deferred_pass || (!charts->defer_maintenance && (chart->redraw_needed || charts->prev_sampling_interval_secs != charts->sampling_interval_secs))) { vcr_clear_row(chart->vcr, VCR_LAYER_TEXT, row, -1, -1); - draw_row_columns(charts, chart, chart->top_row_columns, 1 /* heading */, 0 /* depth */, row, proc); + draw_row_columns(charts, chart, chart->top_row_columns, 1 /* heading */, 0 /* depth */, row, 0, proc); vcr_shadow_row(chart->vcr, VCR_LAYER_TEXT, row); /* XXX: note at this time there's no overlay text for the IRQ/SoftIRQ (row + 1) (which should probably change) */ vcr_clear_row(chart->vcr, VCR_LAYER_TEXT, row + 1, -1, -1); - draw_row_columns(charts, chart, chart->proc_cpu_row_columns, 1 /* heading */, 0 /* depth */, row + 2, proc); + draw_row_columns(charts, chart, chart->proc_cpu_row_columns, 1 /* heading */, 0 /* depth */, row + 2, 0, proc); vcr_shadow_row(chart->vcr, VCR_LAYER_TEXT, row + 1); } @@ -1400,6 +1554,7 @@ vwm_chart_t * vwm_chart_create(vwm_charts_t *charts, int pid, int width, int hei chart->proc_mem_columns[0] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_ROW }; chart->proc_mem_columns[1] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_RSS }; + chart->proc_mem_columns[2] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_PGFLT }; chart->snowflake_cpu_columns[0] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_PID }; chart->snowflake_cpu_columns[1] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_USER }; @@ -1408,6 +1563,7 @@ vwm_chart_t * vwm_chart_create(vwm_charts_t *charts, int pid, int width, int hei chart->snowflake_cpu_columns[4] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_ARGV }; chart->snowflake_mem_columns[0] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_RSS }; + chart->snowflake_mem_columns[1] = (vwm_column_t){ .enabled = 1, .type = VWM_COLUMN_PROC_PGFLT }; chart->top_row_columns[0] = (vwm_row_column_t){ .column = &chart->top_columns[0], .side = VWM_SIDE_RIGHT, .justify = VWM_JUSTIFY_RIGHT }; @@ -1424,8 +1580,14 @@ vwm_chart_t * vwm_chart_create(vwm_charts_t *charts, int pid, int width, int hei chart->proc_cpu_row_columns[9] = (vwm_row_column_t){ .column = &chart->proc_cpu_columns[8], .side = VWM_SIDE_RIGHT, .justify = VWM_JUSTIFY_RIGHT }; chart->proc_mem_row_columns[0] = (vwm_row_column_t){ .column = &chart->proc_mem_columns[0], .side = VWM_SIDE_LEFT, .justify = VWM_JUSTIFY_LEFT }; - chart->proc_mem_row_columns[1] = (vwm_row_column_t){ .column = &chart->proc_cpu_columns[0], .side = VWM_SIDE_RIGHT, .justify = VWM_JUSTIFY_RIGHT }; - chart->proc_mem_row_columns[2] = (vwm_row_column_t){ .column = &chart->proc_mem_columns[1], .side = VWM_SIDE_RIGHT, .justify = VWM_JUSTIFY_RIGHT }; + chart->proc_mem_row_columns[1] = (vwm_row_column_t){ .column = &chart->proc_cpu_columns[4], .side = VWM_SIDE_LEFT, .justify = VWM_JUSTIFY_UNIFORM }; + chart->proc_mem_row_columns[2] = (vwm_row_column_t){ .column = &chart->proc_mem_columns[1], .side = VWM_SIDE_LEFT, .justify = VWM_JUSTIFY_LEFT, .indent = VWM_INDENT_ROWSUB }; + chart->proc_mem_row_columns[3] = (vwm_row_column_t){ .column = &chart->proc_mem_columns[0], .side = VWM_SIDE_RIGHT, .justify = VWM_JUSTIFY_RIGHT }; + + chart->proc_flt_row_columns[0] = (vwm_row_column_t){ .column = &chart->proc_mem_columns[0], .side = VWM_SIDE_LEFT, .justify = VWM_JUSTIFY_LEFT }; + chart->proc_flt_row_columns[1] = (vwm_row_column_t){ .column = &chart->proc_cpu_columns[4], .side = VWM_SIDE_LEFT, .justify = VWM_JUSTIFY_UNIFORM }; + chart->proc_flt_row_columns[2] = (vwm_row_column_t){ .column = &chart->proc_mem_columns[2], .side = VWM_SIDE_LEFT, .justify = VWM_JUSTIFY_LEFT, .indent = VWM_INDENT_ROWSUB }; + chart->proc_flt_row_columns[3] = (vwm_row_column_t){ .column = &chart->proc_mem_columns[0], .side = VWM_SIDE_RIGHT, .justify = VWM_JUSTIFY_RIGHT }; chart->snowflake_cpu_row_columns[0] = (vwm_row_column_t){ .column = &chart->snowflake_cpu_columns[0], .side = VWM_SIDE_LEFT, .justify = VWM_JUSTIFY_RIGHT }; chart->snowflake_cpu_row_columns[1] = (vwm_row_column_t){ .column = &chart->snowflake_cpu_columns[1], .side = VWM_SIDE_LEFT, .justify = VWM_JUSTIFY_RIGHT }; @@ -1433,7 +1595,9 @@ vwm_chart_t * vwm_chart_create(vwm_charts_t *charts, int pid, int width, int hei chart->snowflake_cpu_row_columns[3] = (vwm_row_column_t){ .column = &chart->snowflake_cpu_columns[3], .side = VWM_SIDE_LEFT, .justify = VWM_JUSTIFY_RIGHT }; chart->snowflake_cpu_row_columns[4] = (vwm_row_column_t){ .column = &chart->snowflake_cpu_columns[4], .side = VWM_SIDE_LEFT, .justify = VWM_JUSTIFY_LEFT }; - chart->snowflake_mem_row_columns[0] = (vwm_row_column_t){ .column = &chart->snowflake_mem_columns[0], .side = VWM_SIDE_LEFT, .justify = VWM_JUSTIFY_RIGHT }; + chart->snowflake_mem_row_columns[0] = (vwm_row_column_t){ .column = &chart->snowflake_mem_columns[0], .side = VWM_SIDE_LEFT, .justify = VWM_JUSTIFY_LEFT, .indent = VWM_INDENT_ROWSUB }; + + chart->snowflake_flt_row_columns[0] = (vwm_row_column_t){ .column = &chart->snowflake_mem_columns[1], .side = VWM_SIDE_LEFT, .justify = VWM_JUSTIFY_LEFT, .indent = VWM_INDENT_ROWSUB }; /* add the client process to the monitoring hierarchy */ /* XXX note libvmon here maintains a unique callback for each unique callback+xwin pair, so multi-window processes work */ |