Skip to content

Commit d619528

Browse files
committed
Introduce DiskIORateMeter and DiskIOTimeMeter
The two meters are split from DiskIOMeter and they allow separate display of disk read & write rates and the busy time percentage, including drawing the data as separate bars and graphs. The old DiskIOMeter is kept for backward compatibility. It will be reworked in the next commit. Note that DiskIORateMeter and DiskIOTimeMeter have different 'isPercentChart' values. Signed-off-by: Kang-Che Sung <explorer09@gmail.com>
1 parent c9b997d commit d619528

File tree

8 files changed

+158
-0
lines changed

8 files changed

+158
-0
lines changed

DiskIOMeter.c

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
2433
static const int DiskIOMeter_attributes[] = {
2534
METER_VALUE_NOTICE,
2635
METER_VALUE_IOREAD,
2736
METER_VALUE_IOWRITE,
2837
};
2938

3039
static MeterRateStatus status = RATESTATUS_INIT;
40+
static double cached_read_diff;
3141
static char cached_read_diff_str[6];
42+
static double cached_write_diff;
3243
static char cached_write_diff_str[6];
3344
static double cached_utilisation_diff;
3445
static 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+
104208
static 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+
156298
const MeterClass DiskIOMeter_class = {
157299
.super = {
158300
.extends = Class(Meter),

DiskIOMeter.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ typedef struct DiskIOData_ {
1919
uint64_t numDisks;
2020
} DiskIOData;
2121

22+
extern const MeterClass DiskIORateMeter_class;
23+
24+
extern const MeterClass DiskIOTimeMeter_class;
25+
2226
extern const MeterClass DiskIOMeter_class;
2327

2428
#endif /* HEADER_DiskIOMeter */

darwin/Platform.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ const MeterClass* const Platform_meterTypes[] = {
143143
&RightCPUs8Meter_class,
144144
&ZfsArcMeter_class,
145145
&ZfsCompressedArcMeter_class,
146+
&DiskIORateMeter_class,
147+
&DiskIOTimeMeter_class,
146148
&DiskIOMeter_class,
147149
&NetworkIOMeter_class,
148150
&FileDescriptorMeter_class,

dragonflybsd/Platform.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ const MeterClass* const Platform_meterTypes[] = {
120120
&RightCPUs4Meter_class,
121121
&LeftCPUs8Meter_class,
122122
&RightCPUs8Meter_class,
123+
&DiskIORateMeter_class,
124+
&DiskIOTimeMeter_class,
123125
&DiskIOMeter_class,
124126
&NetworkIOMeter_class,
125127
&FileDescriptorMeter_class,

freebsd/Platform.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ const MeterClass* const Platform_meterTypes[] = {
130130
&BlankMeter_class,
131131
&ZfsArcMeter_class,
132132
&ZfsCompressedArcMeter_class,
133+
&DiskIORateMeter_class,
134+
&DiskIOTimeMeter_class,
133135
&DiskIOMeter_class,
134136
&FileDescriptorMeter_class,
135137
&NetworkIOMeter_class,

linux/Platform.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,8 @@ const MeterClass* const Platform_meterTypes[] = {
247247
&ZfsArcMeter_class,
248248
&ZfsCompressedArcMeter_class,
249249
&ZramMeter_class,
250+
&DiskIORateMeter_class,
251+
&DiskIOTimeMeter_class,
250252
&DiskIOMeter_class,
251253
&NetworkIOMeter_class,
252254
&SELinuxMeter_class,

netbsd/Platform.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,8 @@ const MeterClass* const Platform_meterTypes[] = {
180180
&LeftCPUs8Meter_class,
181181
&RightCPUs8Meter_class,
182182
&BlankMeter_class,
183+
&DiskIORateMeter_class,
184+
&DiskIOTimeMeter_class,
183185
&DiskIOMeter_class,
184186
&NetworkIOMeter_class,
185187
&FileDescriptorMeter_class,

pcp/Platform.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ const MeterClass* const Platform_meterTypes[] = {
114114
&ZfsArcMeter_class,
115115
&ZfsCompressedArcMeter_class,
116116
&ZramMeter_class,
117+
&DiskIORateMeter_class,
118+
&DiskIOTimeMeter_class,
117119
&DiskIOMeter_class,
118120
&NetworkIOMeter_class,
119121
&SysArchMeter_class,

0 commit comments

Comments
 (0)