From 63fafb4844dd619793ba1d318e2b06518666dd37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= Date: Sat, 4 Dec 2021 18:08:59 +0100 Subject: [PATCH] IOMeters: rework initial display Show a non highlighted string at the start of htop, not the failure text. Also the original fix only handled the text mode, not the bar mode. Improves: 2977414d ("Discard stale information from DiskIO and NetworkIO meters") Related: #860 --- DiskIOMeter.c | 44 ++++++++++++++++++++++++++++++++------------ Meter.h | 7 +++++++ NetworkIOMeter.c | 43 ++++++++++++++++++++++++++++++++----------- 3 files changed, 71 insertions(+), 23 deletions(-) diff --git a/DiskIOMeter.c b/DiskIOMeter.c index 11fb791e..12c87de6 100644 --- a/DiskIOMeter.c +++ b/DiskIOMeter.c @@ -12,6 +12,7 @@ in the source distribution for its full text. #include "CRT.h" #include "Macros.h" +#include "Meter.h" #include "Object.h" #include "Platform.h" #include "ProcessList.h" @@ -25,7 +26,7 @@ static const int DiskIOMeter_attributes[] = { METER_VALUE_IOWRITE, }; -static bool hasData = false; +static MeterRateStatus status = RATESTATUS_INIT; static uint32_t cached_read_diff; static uint32_t cached_write_diff; static double cached_utilisation_diff; @@ -36,20 +37,27 @@ static void DiskIOMeter_updateValues(Meter* this) { static uint64_t cached_last_update; uint64_t passedTimeInMs = pl->realtimeMs - cached_last_update; - /* update only every 500ms */ + /* update only every 500ms to have a sane span for rate calculation */ if (passedTimeInMs > 500) { static uint64_t cached_read_total; static uint64_t cached_write_total; static uint64_t cached_msTimeSpend_total; uint64_t diff; + DiskIOData data; + if (!Platform_getDiskIO(&data)) { + status = RATESTATUS_NODATA; + } else if (cached_last_update == 0) { + status = RATESTATUS_INIT; + } else if (passedTimeInMs > 30000) { + status = RATESTATUS_STALE; + } else { + status = RATESTATUS_DATA; + } + cached_last_update = pl->realtimeMs; - DiskIOData data; - - hasData = Platform_getDiskIO(&data); - if (!hasData) { - this->values[0] = 0; + if (status == RATESTATUS_NODATA) { xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "no data"); return; } @@ -81,10 +89,13 @@ static void DiskIOMeter_updateValues(Meter* this) { cached_msTimeSpend_total = data.totalMsTimeSpend; } - if (passedTimeInMs > 30000) { - // Triggers for the first initialization and - // when there was a long time we did not collect updates - hasData = false; + if (status == RATESTATUS_INIT) { + xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "init"); + return; + } + if (status == RATESTATUS_STALE) { + xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "stale"); + return; } this->values[0] = cached_utilisation_diff; @@ -97,9 +108,18 @@ static void DiskIOMeter_updateValues(Meter* this) { } static void DiskIOMeter_display(ATTR_UNUSED const Object* cast, RichString* out) { - if (!hasData) { + switch (status) { + case RATESTATUS_NODATA: RichString_writeAscii(out, CRT_colors[METER_VALUE_ERROR], "no data"); return; + case RATESTATUS_INIT: + RichString_writeAscii(out, CRT_colors[METER_VALUE], "initializing..."); + return; + case RATESTATUS_STALE: + RichString_writeAscii(out, CRT_colors[METER_VALUE_WARN], "stale data"); + return; + case RATESTATUS_DATA: + break; } char buffer[16]; diff --git a/Meter.h b/Meter.h index be8207c7..bd7604a0 100644 --- a/Meter.h +++ b/Meter.h @@ -134,6 +134,13 @@ typedef enum { LAST_METERMODE } MeterModeId; +typedef enum { + RATESTATUS_DATA, + RATESTATUS_INIT, + RATESTATUS_NODATA, + RATESTATUS_STALE +} MeterRateStatus; + extern const MeterClass Meter_class; Meter* Meter_new(const ProcessList* pl, unsigned int param, const MeterClass* type); diff --git a/NetworkIOMeter.c b/NetworkIOMeter.c index 6c429c32..dd91b75e 100644 --- a/NetworkIOMeter.c +++ b/NetworkIOMeter.c @@ -5,6 +5,7 @@ #include "CRT.h" #include "Macros.h" +#include "Meter.h" #include "Object.h" #include "Platform.h" #include "Process.h" @@ -18,8 +19,7 @@ static const int NetworkIOMeter_attributes[] = { METER_VALUE_IOWRITE, }; -static bool hasData = false; - +static MeterRateStatus status = RATESTATUS_INIT; static uint32_t cached_rxb_diff; static uint32_t cached_rxp_diff; static uint32_t cached_txb_diff; @@ -31,7 +31,7 @@ static void NetworkIOMeter_updateValues(Meter* this) { uint64_t passedTimeInMs = pl->realtimeMs - cached_last_update; - /* update only every 500ms */ + /* update only every 500ms to have a sane span for rate calculation */ if (passedTimeInMs > 500) { static uint64_t cached_rxb_total; static uint64_t cached_rxp_total; @@ -39,11 +39,20 @@ static void NetworkIOMeter_updateValues(Meter* this) { static uint64_t cached_txp_total; uint64_t diff; + NetworkIOData data; + if (!Platform_getNetworkIO(&data)) { + status = RATESTATUS_NODATA; + } else if (cached_last_update == 0) { + status = RATESTATUS_INIT; + } else if (passedTimeInMs > 30000) { + status = RATESTATUS_STALE; + } else { + status = RATESTATUS_DATA; + } + cached_last_update = pl->realtimeMs; - NetworkIOData data; - hasData = Platform_getNetworkIO(&data); - if (!hasData) { + if (status == RATESTATUS_NODATA) { xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "no data"); return; } @@ -85,10 +94,13 @@ static void NetworkIOMeter_updateValues(Meter* this) { cached_txp_total = data.packetsTransmitted; } - if (passedTimeInMs > 30000) { - // Triggers for the first initialization and - // when there was a long time we did not collect updates - hasData = false; + if (status == RATESTATUS_INIT) { + xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "init"); + return; + } + if (status == RATESTATUS_STALE) { + xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "stale"); + return; } this->values[0] = cached_rxb_diff; @@ -104,9 +116,18 @@ static void NetworkIOMeter_updateValues(Meter* this) { } static void NetworkIOMeter_display(ATTR_UNUSED const Object* cast, RichString* out) { - if (!hasData) { + switch (status) { + case RATESTATUS_NODATA: RichString_writeAscii(out, CRT_colors[METER_VALUE_ERROR], "no data"); return; + case RATESTATUS_INIT: + RichString_writeAscii(out, CRT_colors[METER_VALUE], "initializing..."); + return; + case RATESTATUS_STALE: + RichString_writeAscii(out, CRT_colors[METER_VALUE_WARN], "stale data"); + return; + case RATESTATUS_DATA: + break; } char buffer[64];