Two-channel graph (Graph2) meter style#1415
Conversation
f47a975 to
745f394
Compare
745f394 to
af6b927
Compare
31cb513 to
bedca8f
Compare
ade4922 to
54d3d1c
Compare
728ef87 to
3033b1d
Compare
aa96aa4 to
10bb617
Compare
10bb617 to
8ab21e9
Compare
8ab21e9 to
30691c9
Compare
f57affb to
5e3eeb1
Compare
b5560f5 to
8a8cfda
Compare
8a8cfda to
eac20b6
Compare
c7c11bc to
b446269
Compare
b446269 to
a84d790
Compare
95052ef to
d370bf3
Compare
d370bf3 to
c8d8c19
Compare
5e7bb49 to
0d092e5
Compare
|
The traditional graphical meters have a gray baseline. Does it make sense to have that here as well? |
|
Oh, and another note... Personally I do not like just adding numbers to names, at least for new functionality. How about something a little bit more descriptive? Perhaps "NGraph" (for negative) or "TCGraph" (for two-channel)? |
I've tried it. It would visually distract too much, as the "baseline" on the middle would be two times as thick. And I didn't like it.
"Graph2C" ? |
Ah, right... But I have some systems that have just little to no disk io activity, especially for reading. Some random blue dots floating around is distracting, too. 😝 Not sure what's better.
Oh, I read the name "Graph2" as "Graph, increment by one". If you take it as an abbreviation for "Graph two-channel" it makes kind of sense. 😉 Anyway, I would prefer your suggestion "Graph2C" if it is possible and fine for you. Any other opinions? |
|
Actually it's not that bad. I think that's the version I would prefer, and with proper spacing (I use font Terminus here, and my screenshot were made with that) this would look even better. |
📝 WalkthroughGraph2 meter mode implementationImplements a new two-channel graph meter mode ( Core implementationMeter.c (+1164/-72): Replaces the previous graph rendering approach with a complete cell- and dot-aware pipeline. Introduces fixed-width/graph-specific helper types (cells, offsets, compute state, draw context) and implements internal graph helpers for buffer reallocation/compaction, coordinate mapping, scale computation, and per-cell detail bitmasks. Meter.h (+2/-1): Changes MeterMode.h (+1): Adds Meter supportDiskIOMeter.c (+6/-2): DiskIORateMeter and DiskIOMeter now advertise NetworkIOMeter.c (+1/-1): Adds Platform compatibilityCPU meter display unified across platforms (linux/netbsd/openbsd/pcp/Platform.c, +43/-33 total): Simplified meter composition for non-detailed CPU time path by reducing curItems and consolidating IRQ/SOFTIRQ handling. Removes redundant CPU_METER_FREQUENCY assignments in detailed paths. Action.c (+5/-2): Updated CPU usage bar help rendering to branch on color scheme and adjust padding strings. CPUMeter.c (+0/-12): Unified CPU meter attribute configuration by removing separate Build and utilitiesXUtils.h/XUtils.c (+52/+10): Added bit-manipulation helpers: configure.ac (+55/-1): Extended compiler feature detection for Commit qualitySingle, well-scoped commit implementing the complete Graph2 feature with all interdependent changes grouped logically. Code organization is clean: Graph2-specific logic is clearly separated via conditional branches on WalkthroughThis PR adds GRAPH2_METERMODE: a cell- and dot-aware graph renderer with buffer-backed records, per-item allocation, detail masks, and per-cell rendering. It updates Meter APIs to use a generic buffer, registers GRAPH2 mode, and frees the buffer on mode change/delete. It adds powerOf2Floor/popCount8 helpers with configure probes and fallbacks. CPUMeter attributes are unified (IOWAIT added; runtime summary switching removed), platform code adjusts curItems and slot assignments across Linux, NetBSD, OpenBSD, and PCP, DiskIO/NetworkIO advertise Graph2 (DiskIO time remaps to Graph), and Action.c help text gains monochrome-specific labels. Poem
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 3b7a5791-e5f0-4fbd-a282-ecfd4dfa3748
📒 Files selected for processing (14)
Action.cCPUMeter.cDiskIOMeter.cMeter.cMeter.hMeterMode.hNetworkIOMeter.cXUtils.cXUtils.hconfigure.aclinux/Platform.cnetbsd/Platform.copenbsd/Platform.cpcp/Platform.c
💤 Files with no reviewable changes (1)
- CPUMeter.c
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 40c24eae-e11b-48b6-9b75-3394a558438b
📒 Files selected for processing (14)
Action.cCPUMeter.cDiskIOMeter.cMeter.cMeter.hMeterMode.hNetworkIOMeter.cXUtils.cXUtils.hconfigure.aclinux/Platform.cnetbsd/Platform.copenbsd/Platform.cpcp/Platform.c
💤 Files with no reviewable changes (1)
- CPUMeter.c
| assert(itemIndex < maxItems); | ||
| assert(itemIndex < Meter_maxItems(this)); | ||
| return Meter_attributes(this)[itemIndex]; |
There was a problem hiding this comment.
Honor curAttributes when resolving graph colors.
Line 1147 now hard-codes Meter_attributes(), while BarMeterMode_draw() still prefers this->curAttributes. Any meter that overrides its colors at runtime will render the wrong colors in Graph and Graph2.
Proposed fix
- return Meter_attributes(this)[itemIndex];
+ const int* attrs = this->curAttributes ? this->curAttributes : Meter_attributes(this);
+ return attrs[itemIndex];📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| assert(itemIndex < maxItems); | |
| assert(itemIndex < Meter_maxItems(this)); | |
| return Meter_attributes(this)[itemIndex]; | |
| assert(itemIndex < maxItems); | |
| assert(itemIndex < Meter_maxItems(this)); | |
| const int* attrs = this->curAttributes ? this->curAttributes : Meter_attributes(this); | |
| return attrs[itemIndex]; |
When both the options "Add guest time in CPU meter percentage" and "Detailed CPU time" are turned off, the CPU meter used to show the "virtual" CPU time in the bar display as a glitch. Now fix it. Signed-off-by: Kang-Che Sung <explorer09@gmail.com>
Signed-off-by: Kang-Che Sung <explorer09@gmail.com>
…d mode" This reverts commit 47aeb0a.
The time displayed is (steal+guest), not just guest CPU time. Regression from 3d8fa0b Signed-off-by: Kang-Che Sung <explorer09@gmail.com>
Linux and PCP platform code used to write the 'virtualized' (steal+guest) CPU time into the CPU_METER_IRQ item when the "detailed CPU time" option is off, which would result in a wrong color painted for virtual CPU time in bar mode. Write the 'virtualized' CPU time to CPU_METER_STEAL instead, which is more appropriate for the job. Also update the "virtualized" CPU meter item in the help screen: (1) The color is now CPU_STEAL for consistency. (2) In monochrome mode, two dummy items are displayed before the "virtualized" word so that the bar meter symbol mapping is correct. Signed-off-by: Kang-Che Sung <explorer09@gmail.com>
Round the graph meter's dynamic scale to a power of two and print the graph scale. For a percent graph, a "%" character is printed in place of the scale. Signed-off-by: Kang-Che Sung <explorer09@gmail.com>
This is a prerequisite for the feature "Graph meter coloring (with GraphData structure rework)". powerOf2Floor() will utilize __builtin_clz() or stdc_bit_floor_ui() (__builtin_clz() is preferred) if either is supported. popCount8() will utilize ARM NEON instructions and x86 POPCNT instruction if the machine supports either of them. I am not adopting the C23 standard interface stdc_count_ones_uc() yet, as I am not sure C libraries would implement it as fast as our version. Signed-off-by: Kang-Che Sung <explorer09@gmail.com>
Rewrite the entire graph meter drawing code to support color graph drawing in addition to the dynamic scaling (both can work together because of the new GraphData structure design). The colors of a graph are based on the percentages of item values of the meter. The rounding differences of each terminal character are addressed through the different numbers of braille dots. Due to low resolution of the character terminal, the rasterized colors may not look nice, but better than nothing. :) The new GraphData structure design has two technical limitations: * The height of a graph meter now has a limit of 8191 (terminal rows). * If dynamic scaling is used, the "total" value or scale of a graph now has to align to a power of 2. The code is designed with the anticipation that the graph height may change at runtime. No UI or option has been implemented for that yet. Signed-off-by: Kang-Che Sung <explorer09@gmail.com>
Specifically 'PIXPERROW_*' and 'GraphMeterMode_dots*' constants. They were commented out rather than removed in the previous commit (for ease of code reviewing). Now this commit removes the constant defines for good.
Introduce a new meter mode (meter style) called "Graph2". The "Graph2" name stands for "two-channel graph" or "two-quadrant graph". This meter mode is not in the list of default supported modes. This "Graph2" mode is intended for meters with two item values. It plots the first item above the x-axis and the second item below the x-axis. Items other than the first two are always hidden. This code is written with the intention to share as much code with the Graph meter mode as possible. Signed-off-by: Kang-Che Sung <explorer09@gmail.com>
Specifically it's the DiskIORateMeter part that supports "Graph2" mode. For the combined DiskIOMeter, the "IO rate" part can show as two-channel graph while the "IO time" part remains a one-channel graph. Signed-off-by: Kang-Che Sung <explorer09@gmail.com>
This special case of "details" value would print as ':' in the ASCII display mode. It is used in "Graph2" meter drawing only. Signed-off-by: Kang-Che Sung <explorer09@gmail.com>
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: a087998d-12a4-417c-bbe2-608d1288050f
📒 Files selected for processing (14)
Action.cCPUMeter.cDiskIOMeter.cMeter.cMeter.hMeterMode.hNetworkIOMeter.cXUtils.cXUtils.hconfigure.aclinux/Platform.cnetbsd/Platform.copenbsd/Platform.cpcp/Platform.c
💤 Files with no reviewable changes (1)
- CPUMeter.c
| v[CPU_METER_IRQ] = 0.0; // Accounted in 'kernel' | ||
| v[CPU_METER_SOFTIRQ] = 0.0; // Accounted in 'kernel' | ||
| v[CPU_METER_STEAL] = (cpuData->stealPeriod + cpuData->guestPeriod) / total * 100.0; | ||
| if (settings->accountGuestInCPUMeter) { | ||
| this->curItems = 6; |
There was a problem hiding this comment.
Shared CPU slot contract mismatch in non-detailed mode. Both platform implementations moved virtualization data into CPU_METER_STEAL while zeroing CPU_METER_IRQ, but the non-detailed CPU text path still reads CPU_METER_IRQ for vir:.
linux/Platform.c#L375-L379: keep non-detailed virtualization in the slot the display consumes, or update the display path to consumeCPU_METER_STEAL.pcp/Platform.c#L579-L585: apply the same producer/consumer slot alignment as Linux to avoid incorrectvir:output.
📍 Affects 2 files
linux/Platform.c#L375-L379(this comment)pcp/Platform.c#L579-L585



This pull request implements the "two-channel" graph style as the new "Graph2" meter mode. This is based on #714 so that the graphs will be shown with colors.
This new mode is designed for a few meters only— only
DiskIORateMeter(#1763, merged) andNetworkIOMetercan correctly utilise this mode by showing the input and output rates as separate channels.The feature was previously discussed in #1390.
Below is a preview screenshot taken in macOS Sequoia.

I included both Unicode mode and
--no-unicodemode.