From c2fdfd99eb5bffee0f6d1e1838fb4708eac18425 Mon Sep 17 00:00:00 2001 From: Christian Goettsche Date: Wed, 21 Oct 2020 17:06:32 +0200 Subject: [PATCH] FreeBSD: implement Platform_getDiskIO() --- DiskIOMeter.c | 17 ++++++++------- DiskIOMeter.h | 6 ++++++ configure.ac | 3 +++ darwin/Platform.c | 6 ++---- darwin/Platform.h | 5 ++--- dragonflybsd/Platform.c | 6 ++---- dragonflybsd/Platform.h | 5 ++--- freebsd/Platform.c | 47 +++++++++++++++++++++++++++++++++++------ freebsd/Platform.h | 5 ++--- linux/Platform.c | 8 +++---- linux/Platform.h | 5 ++--- openbsd/Platform.c | 6 ++---- openbsd/Platform.h | 5 ++--- solaris/Platform.c | 6 ++---- solaris/Platform.h | 5 ++--- unsupported/Platform.c | 6 ++---- unsupported/Platform.h | 5 ++--- 17 files changed, 87 insertions(+), 59 deletions(-) diff --git a/DiskIOMeter.c b/DiskIOMeter.c index 9f311653..21696a33 100644 --- a/DiskIOMeter.c +++ b/DiskIOMeter.c @@ -44,23 +44,24 @@ static void DiskIOMeter_updateValues(Meter* this, char* buffer, int len) { if (passedTimeInMs > 500) { cached_last_update = timeInMilliSeconds; - unsigned long int bytesRead, bytesWrite, msTimeSpend; + DiskIOData data; - hasData = Platform_getDiskIO(&bytesRead, &bytesWrite, &msTimeSpend); + hasData = Platform_getDiskIO(&data); if (!hasData) { this->values[0] = 0; xSnprintf(buffer, len, "no data"); return; } - cached_read_diff = (bytesRead - cached_read_total) / 1024; /* Meter_humanUnit() expects unit in kilo */ - cached_read_total = bytesRead; + cached_read_diff = (data.totalBytesRead - cached_read_total) / 1024; /* Meter_humanUnit() expects unit in kilo */ + cached_read_total = data.totalBytesRead; - cached_write_diff = (bytesWrite - cached_write_total) / 1024; /* Meter_humanUnit() expects unit in kilo */ - cached_write_total = bytesWrite; + cached_write_diff = (data.totalBytesWritten - cached_write_total) / 1024; /* Meter_humanUnit() expects unit in kilo */ + cached_write_total = data.totalBytesWritten; - cached_utilisation_diff = 100 * (double)(msTimeSpend - cached_msTimeSpend_total) / passedTimeInMs; - cached_msTimeSpend_total = msTimeSpend; + cached_utilisation_diff = 100 * (double)(data.totalMsTimeSpend - cached_msTimeSpend_total) / passedTimeInMs; + + cached_msTimeSpend_total = data.totalMsTimeSpend; } this->values[0] = cached_utilisation_diff; diff --git a/DiskIOMeter.h b/DiskIOMeter.h index c7e4542a..9fca35b1 100644 --- a/DiskIOMeter.h +++ b/DiskIOMeter.h @@ -9,6 +9,12 @@ in the source distribution for its full text. #include "Meter.h" +typedef struct DiskIOData_ { + unsigned long int totalBytesRead; + unsigned long int totalBytesWritten; + unsigned long int totalMsTimeSpend; +} DiskIOData; + extern const MeterClass DiskIOMeter_class; #endif /* HEADER_DiskIOMeter */ diff --git a/configure.ac b/configure.ac index bc8592d0..70289a78 100644 --- a/configure.ac +++ b/configure.ac @@ -102,6 +102,9 @@ CFLAGS="$save_cflags" # Add -lexecinfo if needed AC_SEARCH_LIBS([backtrace], [execinfo]) +# Add -ldevstat if needed +AC_SEARCH_LIBS([devstat_checkversion], [devstat]) + # Checks for features and flags. # ---------------------------------------------------------------------- PROCDIR=/proc diff --git a/darwin/Platform.c b/darwin/Platform.c index 965da0a1..b1f9283d 100644 --- a/darwin/Platform.c +++ b/darwin/Platform.c @@ -311,11 +311,9 @@ char* Platform_getProcessEnv(pid_t pid) { return env; } -bool Platform_getDiskIO(unsigned long int *bytesRead, - unsigned long int *bytesWrite, - unsigned long int *msTimeSpend) { +bool Platform_getDiskIO(DiskIOData* data) { // TODO - *bytesRead = *bytesWrite = *msTimeSpend = 0; + (void)data; return false; } diff --git a/darwin/Platform.h b/darwin/Platform.h index bdfe226d..471b38a9 100644 --- a/darwin/Platform.h +++ b/darwin/Platform.h @@ -11,6 +11,7 @@ in the source distribution for its full text. #include "Action.h" #include "SignalsPanel.h" #include "CPUMeter.h" +#include "DiskIOMeter.h" #include "BatteryMeter.h" #include "DarwinProcess.h" @@ -48,9 +49,7 @@ void Platform_setZfsCompressedArcValues(Meter* this); char* Platform_getProcessEnv(pid_t pid); -bool Platform_getDiskIO(unsigned long int *bytesRead, - unsigned long int *bytesWrite, - unsigned long int *msTimeSpend); +bool Platform_getDiskIO(DiskIOData* data); bool Platform_getNetworkIO(unsigned long int *bytesReceived, unsigned long int *packetsReceived, diff --git a/dragonflybsd/Platform.c b/dragonflybsd/Platform.c index 3eac7deb..5b81c610 100644 --- a/dragonflybsd/Platform.c +++ b/dragonflybsd/Platform.c @@ -206,11 +206,9 @@ char* Platform_getProcessEnv(pid_t pid) { return NULL; } -bool Platform_getDiskIO(unsigned long int *bytesRead, - unsigned long int *bytesWrite, - unsigned long int *msTimeSpend) { +bool Platform_getDiskIO(DiskIOData* data) { // TODO - *bytesRead = *bytesWrite = *msTimeSpend = 0; + (void)data; return false; } diff --git a/dragonflybsd/Platform.h b/dragonflybsd/Platform.h index 7ea211ca..6c884719 100644 --- a/dragonflybsd/Platform.h +++ b/dragonflybsd/Platform.h @@ -10,6 +10,7 @@ in the source distribution for its full text. #include "Action.h" #include "BatteryMeter.h" +#include "DiskIOMeter.h" #include "SignalsPanel.h" extern ProcessFieldData Process_fields[]; @@ -40,9 +41,7 @@ void Platform_setSwapValues(Meter* this); char* Platform_getProcessEnv(pid_t pid); -bool Platform_getDiskIO(unsigned long int *bytesRead, - unsigned long int *bytesWrite, - unsigned long int *msTimeSpend); +bool Platform_getDiskIO(DiskIOData* data); bool Platform_getNetworkIO(unsigned long int *bytesReceived, unsigned long int *packetsReceived, diff --git a/freebsd/Platform.c b/freebsd/Platform.c index b23a8624..bdd49bf6 100644 --- a/freebsd/Platform.c +++ b/freebsd/Platform.c @@ -7,6 +7,7 @@ in the source distribution for its full text. #include "Platform.h" +#include #include #include #include @@ -21,6 +22,7 @@ in the source distribution for its full text. #include "ClockMeter.h" #include "DateMeter.h" #include "DateTimeMeter.h" +#include "DiskIOMeter.h" #include "FreeBSDProcess.h" #include "FreeBSDProcessList.h" #include "HostnameMeter.h" @@ -111,6 +113,7 @@ const MeterClass* const Platform_meterTypes[] = { &BlankMeter_class, &ZfsArcMeter_class, &ZfsCompressedArcMeter_class, + &DiskIOMeter_class, &NetworkIOMeter_class, NULL }; @@ -240,12 +243,44 @@ char* Platform_getProcessEnv(pid_t pid) { return env; } -bool Platform_getDiskIO(unsigned long int *bytesRead, - unsigned long int *bytesWrite, - unsigned long int *msTimeSpend) { - // TODO - *bytesRead = *bytesWrite = *msTimeSpend = 0; - return false; +bool Platform_getDiskIO(DiskIOData* data) { + + if (devstat_checkversion(NULL) < 0) + return false; + + struct devinfo info = { 0 }; + struct statinfo current = { .dinfo = &info }; + + // get number of devices + if (devstat_getdevs(NULL, ¤t) < 0) + return false; + + int count = current.dinfo->numdevs; + + unsigned long int bytesReadSum = 0, bytesWriteSum = 0, timeSpendSum = 0; + + // get data + for (int i = 0; i < count; i++) { + uint64_t bytes_read, bytes_write; + long double busy_time; + + devstat_compute_statistics(¤t.dinfo->devices[i], + NULL, + 1.0, + DSM_TOTAL_BYTES_READ, &bytes_read, + DSM_TOTAL_BYTES_WRITE, &bytes_write, + DSM_TOTAL_BUSY_TIME, &busy_time, + DSM_NONE); + + bytesReadSum += bytes_read; + bytesWriteSum += bytes_write; + timeSpendSum += 1000 * busy_time; + } + + data->totalBytesRead = bytesReadSum; + data->totalBytesWritten = bytesWriteSum; + data->totalMsTimeSpend = timeSpendSum; + return true; } bool Platform_getNetworkIO(unsigned long int *bytesReceived, diff --git a/freebsd/Platform.h b/freebsd/Platform.h index 40fb2d97..894b3e25 100644 --- a/freebsd/Platform.h +++ b/freebsd/Platform.h @@ -9,6 +9,7 @@ in the source distribution for its full text. #include "Action.h" #include "BatteryMeter.h" +#include "DiskIOMeter.h" #include "SignalsPanel.h" extern ProcessFieldData Process_fields[]; @@ -43,9 +44,7 @@ void Platform_setZfsCompressedArcValues(Meter* this); char* Platform_getProcessEnv(pid_t pid); -bool Platform_getDiskIO(unsigned long int *bytesRead, - unsigned long int *bytesWrite, - unsigned long int *msTimeSpend); +bool Platform_getDiskIO(DiskIOData* data); bool Platform_getNetworkIO(unsigned long int *bytesReceived, unsigned long int *packetsReceived, diff --git a/linux/Platform.c b/linux/Platform.c index f6f7ba19..fe9764ba 100644 --- a/linux/Platform.c +++ b/linux/Platform.c @@ -313,7 +313,7 @@ void Platform_getPressureStall(const char *file, bool some, double* ten, double* fclose(fd); } -bool Platform_getDiskIO(unsigned long int *bytesRead, unsigned long int *bytesWrite, unsigned long int *msTimeSpend) { +bool Platform_getDiskIO(DiskIOData* data) { FILE *fd = fopen(PROCDIR "/diskstats", "r"); if (!fd) return false; @@ -352,9 +352,9 @@ bool Platform_getDiskIO(unsigned long int *bytesRead, unsigned long int *bytesWr } fclose(fd); /* multiply with sector size */ - *bytesRead = 512 * read_sum; - *bytesWrite = 512 * write_sum; - *msTimeSpend = timeSpend_sum; + data->totalBytesRead = 512 * read_sum; + data->totalBytesWritten = 512 * write_sum; + data->totalMsTimeSpend = timeSpend_sum; return true; } diff --git a/linux/Platform.h b/linux/Platform.h index 3c3986e6..62402432 100644 --- a/linux/Platform.h +++ b/linux/Platform.h @@ -11,6 +11,7 @@ in the source distribution for its full text. #include #include "Action.h" +#include "DiskIOMeter.h" #include "Meter.h" #include "Process.h" #include "SignalsPanel.h" @@ -46,9 +47,7 @@ char* Platform_getProcessEnv(pid_t pid); void Platform_getPressureStall(const char *file, bool some, double* ten, double* sixty, double* threehundred); -bool Platform_getDiskIO(unsigned long int *bytesRead, - unsigned long int *bytesWrite, - unsigned long int *msTimeSpend); +bool Platform_getDiskIO(DiskIOData* data); bool Platform_getNetworkIO(unsigned long int *bytesReceived, unsigned long int *packetsReceived, diff --git a/openbsd/Platform.c b/openbsd/Platform.c index 9f7cd737..df6bc0cc 100644 --- a/openbsd/Platform.c +++ b/openbsd/Platform.c @@ -288,11 +288,9 @@ char* Platform_getProcessEnv(pid_t pid) { return env; } -bool Platform_getDiskIO(unsigned long int *bytesRead, - unsigned long int *bytesWrite, - unsigned long int *msTimeSpend) { +bool Platform_getDiskIO(DiskIOData* data) { // TODO - *bytesRead = *bytesWrite = *msTimeSpend = 0; + (void)data; return false; } diff --git a/openbsd/Platform.h b/openbsd/Platform.h index b75d87b2..8cb5bdf3 100644 --- a/openbsd/Platform.h +++ b/openbsd/Platform.h @@ -10,6 +10,7 @@ in the source distribution for its full text. #include "Action.h" #include "BatteryMeter.h" +#include "DiskIOMeter.h" #include "SignalsPanel.h" extern ProcessFieldData Process_fields[]; @@ -41,9 +42,7 @@ void Platform_setSwapValues(Meter* this); char* Platform_getProcessEnv(pid_t pid); -bool Platform_getDiskIO(unsigned long int *bytesRead, - unsigned long int *bytesWrite, - unsigned long int *msTimeSpend); +bool Platform_getDiskIO(DiskIOData* data); bool Platform_getNetworkIO(unsigned long int *bytesReceived, unsigned long int *packetsReceived, diff --git a/solaris/Platform.c b/solaris/Platform.c index 2fa2e1de..87247969 100644 --- a/solaris/Platform.c +++ b/solaris/Platform.c @@ -264,11 +264,9 @@ char* Platform_getProcessEnv(pid_t pid) { return envBuilder.env; } -bool Platform_getDiskIO(unsigned long int *bytesRead, - unsigned long int *bytesWrite, - unsigned long int *msTimeSpend) { +bool Platform_getDiskIO(DiskIOData* data) { // TODO - *bytesRead = *bytesWrite = *msTimeSpend = 0; + (void)data; return false; } diff --git a/solaris/Platform.h b/solaris/Platform.h index f95515c6..8718dbfe 100644 --- a/solaris/Platform.h +++ b/solaris/Platform.h @@ -11,6 +11,7 @@ in the source distribution for its full text. #include "Action.h" #include "BatteryMeter.h" +#include "DiskIOMeter.h" #include "SignalsPanel.h" #include #include @@ -63,9 +64,7 @@ void Platform_setZfsCompressedArcValues(Meter* this); char* Platform_getProcessEnv(pid_t pid); -bool Platform_getDiskIO(unsigned long int *bytesRead, - unsigned long int *bytesWrite, - unsigned long int *msTimeSpend); +bool Platform_getDiskIO(DiskIOData* data); bool Platform_getNetworkIO(unsigned long int *bytesReceived, unsigned long int *packetsReceived, diff --git a/unsupported/Platform.c b/unsupported/Platform.c index e2d7fa6b..3f8cefa6 100644 --- a/unsupported/Platform.c +++ b/unsupported/Platform.c @@ -141,10 +141,8 @@ char* Platform_getProcessEnv(pid_t pid) { return NULL; } -bool Platform_getDiskIO(unsigned long int *bytesRead, - unsigned long int *bytesWrite, - unsigned long int *msTimeSpend) { - *bytesRead = *bytesWrite = *msTimeSpend = 0; +bool Platform_getDiskIO(DiskIOData* data) { + (void)data; return false; } diff --git a/unsupported/Platform.h b/unsupported/Platform.h index 1558d66a..902b6a9b 100644 --- a/unsupported/Platform.h +++ b/unsupported/Platform.h @@ -10,6 +10,7 @@ in the source distribution for its full text. #include "Action.h" #include "BatteryMeter.h" +#include "DiskIOMeter.h" #include "SignalsPanel.h" #include "UnsupportedProcess.h" @@ -47,9 +48,7 @@ bool Process_isThread(const Process* this); char* Platform_getProcessEnv(pid_t pid); -bool Platform_getDiskIO(unsigned long int *bytesRead, - unsigned long int *bytesWrite, - unsigned long int *msTimeSpend); +bool Platform_getDiskIO(DiskIOData* data); bool Platform_getNetworkIO(unsigned long int *bytesReceived, unsigned long int *packetsReceived,