@@ -21,14 +21,25 @@ in the source distribution for its full text.
2121#include "XUtils.h"
2222
2323
24+ static const int DiskIORateMeter_attributes [] = {
25+ METER_VALUE_IOREAD ,
26+ METER_VALUE_IOWRITE ,
27+ };
28+
29+ static const int DiskIOTimeMeter_attributes [] = {
30+ METER_VALUE_NOTICE ,
31+ };
32+
2433static const int DiskIOMeter_attributes [] = {
2534 METER_VALUE_NOTICE ,
2635 METER_VALUE_IOREAD ,
2736 METER_VALUE_IOWRITE ,
2837};
2938
3039static MeterRateStatus status = RATESTATUS_INIT ;
40+ static double cached_read_diff ;
3141static char cached_read_diff_str [6 ];
42+ static double cached_write_diff ;
3243static char cached_write_diff_str [6 ];
3344static double cached_utilisation_diff ;
3445static double cached_utilisation_norm ;
@@ -73,6 +84,7 @@ static void DiskIOUpdateCache(const Machine* host) {
7384 } else {
7485 diff = 0 ;
7586 }
87+ cached_read_diff = diff ;
7688 Meter_humanUnit (cached_read_diff_str , diff , sizeof (cached_read_diff_str ));
7789
7890 if (data .totalBytesWritten > cached_write_total ) {
@@ -82,6 +94,7 @@ static void DiskIOUpdateCache(const Machine* host) {
8294 } else {
8395 diff = 0 ;
8496 }
97+ cached_write_diff = diff ;
8598 Meter_humanUnit (cached_write_diff_str , diff , sizeof (cached_write_diff_str ));
8699
87100 cached_utilisation_diff = 0.0 ;
@@ -101,6 +114,97 @@ static void DiskIOUpdateCache(const Machine* host) {
101114 cached_msTimeSpend_total = data .totalMsTimeSpend ;
102115}
103116
117+ static void DiskIORateMeter_updateValues (Meter * this ) {
118+ DiskIOUpdateCache (this -> host );
119+
120+ this -> values [0 ] = cached_read_diff ;
121+ this -> values [1 ] = cached_write_diff ;
122+
123+ switch (status ) {
124+ case RATESTATUS_NODATA :
125+ xSnprintf (this -> txtBuffer , sizeof (this -> txtBuffer ), "no data" );
126+ return ;
127+ case RATESTATUS_INIT :
128+ xSnprintf (this -> txtBuffer , sizeof (this -> txtBuffer ), "init" );
129+ return ;
130+ case RATESTATUS_STALE :
131+ xSnprintf (this -> txtBuffer , sizeof (this -> txtBuffer ), "stale" );
132+ return ;
133+ case RATESTATUS_DATA :
134+ break ;
135+ }
136+
137+ xSnprintf (this -> txtBuffer , sizeof (this -> txtBuffer ), "r:%siB/s w:%siB/s" , cached_read_diff_str , cached_write_diff_str );
138+ }
139+
140+ static void DiskIORateMeter_display (ATTR_UNUSED const Object * cast , RichString * out ) {
141+ switch (status ) {
142+ case RATESTATUS_NODATA :
143+ RichString_writeAscii (out , CRT_colors [METER_VALUE_ERROR ], "no data" );
144+ return ;
145+ case RATESTATUS_INIT :
146+ RichString_writeAscii (out , CRT_colors [METER_VALUE ], "initializing..." );
147+ return ;
148+ case RATESTATUS_STALE :
149+ RichString_writeAscii (out , CRT_colors [METER_VALUE_WARN ], "stale data" );
150+ return ;
151+ case RATESTATUS_DATA :
152+ break ;
153+ }
154+
155+ RichString_appendAscii (out , CRT_colors [METER_TEXT ], "read: " );
156+ RichString_appendAscii (out , CRT_colors [METER_VALUE_IOREAD ], cached_read_diff_str );
157+ RichString_appendAscii (out , CRT_colors [METER_VALUE_IOREAD ], "iB/s" );
158+
159+ RichString_appendAscii (out , CRT_colors [METER_TEXT ], " write: " );
160+ RichString_appendAscii (out , CRT_colors [METER_VALUE_IOWRITE ], cached_write_diff_str );
161+ RichString_appendAscii (out , CRT_colors [METER_VALUE_IOWRITE ], "iB/s" );
162+ }
163+
164+ static void DiskIOTimeMeter_updateValues (Meter * this ) {
165+ DiskIOUpdateCache (this -> host );
166+
167+ this -> values [0 ] = cached_utilisation_norm ;
168+
169+ switch (status ) {
170+ case RATESTATUS_NODATA :
171+ xSnprintf (this -> txtBuffer , sizeof (this -> txtBuffer ), "no data" );
172+ return ;
173+ case RATESTATUS_INIT :
174+ xSnprintf (this -> txtBuffer , sizeof (this -> txtBuffer ), "init" );
175+ return ;
176+ case RATESTATUS_STALE :
177+ xSnprintf (this -> txtBuffer , sizeof (this -> txtBuffer ), "stale" );
178+ return ;
179+ case RATESTATUS_DATA :
180+ break ;
181+ }
182+
183+ xSnprintf (this -> txtBuffer , sizeof (this -> txtBuffer ), "%.1f%%" , cached_utilisation_diff );
184+ }
185+
186+ static void DiskIOTimeMeter_display (ATTR_UNUSED const Object * cast , RichString * out ) {
187+ switch (status ) {
188+ case RATESTATUS_NODATA :
189+ RichString_writeAscii (out , CRT_colors [METER_VALUE_ERROR ], "no data" );
190+ return ;
191+ case RATESTATUS_INIT :
192+ RichString_writeAscii (out , CRT_colors [METER_VALUE ], "initializing..." );
193+ return ;
194+ case RATESTATUS_STALE :
195+ RichString_writeAscii (out , CRT_colors [METER_VALUE_WARN ], "stale data" );
196+ return ;
197+ case RATESTATUS_DATA :
198+ break ;
199+ }
200+
201+ char buffer [16 ];
202+
203+ int color = cached_utilisation_diff > 40.0 ? METER_VALUE_NOTICE : METER_VALUE ;
204+ int len = xSnprintf (buffer , sizeof (buffer ), "%.1f%%" , cached_utilisation_diff );
205+ RichString_appendnAscii (out , CRT_colors [color ], buffer , len );
206+ }
207+
104208static void DiskIOMeter_updateValues (Meter * this ) {
105209 DiskIOUpdateCache (this -> host );
106210
@@ -153,6 +257,44 @@ static void DiskIOMeter_display(ATTR_UNUSED const Object* cast, RichString* out)
153257 RichString_appendAscii (out , CRT_colors [METER_VALUE_IOWRITE ], "iB/s" );
154258}
155259
260+ const MeterClass DiskIORateMeter_class = {
261+ .super = {
262+ .extends = Class (Meter ),
263+ .delete = Meter_delete ,
264+ .display = DiskIORateMeter_display
265+ },
266+ .updateValues = DiskIORateMeter_updateValues ,
267+ .defaultMode = TEXT_METERMODE ,
268+ .supportedModes = METERMODE_DEFAULT_SUPPORTED ,
269+ .maxItems = 2 ,
270+ .isPercentChart = false,
271+ .total = 1.0 ,
272+ .attributes = DiskIORateMeter_attributes ,
273+ .name = "DiskIORate" ,
274+ .uiName = "Disk IO Rate" ,
275+ .description = "Disk IO read & write bytes per second" ,
276+ .caption = "Dsk: "
277+ };
278+
279+ const MeterClass DiskIOTimeMeter_class = {
280+ .super = {
281+ .extends = Class (Meter ),
282+ .delete = Meter_delete ,
283+ .display = DiskIOTimeMeter_display
284+ },
285+ .updateValues = DiskIOTimeMeter_updateValues ,
286+ .defaultMode = TEXT_METERMODE ,
287+ .supportedModes = METERMODE_DEFAULT_SUPPORTED ,
288+ .maxItems = 1 ,
289+ .isPercentChart = true,
290+ .total = 1.0 ,
291+ .attributes = DiskIOTimeMeter_attributes ,
292+ .name = "DiskIOTime" ,
293+ .uiName = "Disk IO Time" ,
294+ .description = "Disk percent time busy" ,
295+ .caption = "Dsk: "
296+ };
297+
156298const MeterClass DiskIOMeter_class = {
157299 .super = {
158300 .extends = Class (Meter ),
0 commit comments