diff --git a/GPUMeter.c b/GPUMeter.c index 908fb9204..57857d641 100644 --- a/GPUMeter.c +++ b/GPUMeter.c @@ -16,7 +16,7 @@ in the source distribution for its full text. static size_t activeMeters; -const int GPUMeter_attributes[] = { +static const int GPUMeter_attributes[] = { GPU_ENGINE_1, GPU_ENGINE_2, GPU_ENGINE_3, @@ -73,21 +73,20 @@ static int humanTimeUnit(char* buffer, size_t size, unsigned long long int value } static void GPUMeter_updateValues(Meter* this) { + const Machine* host = this->host; char* buffer = this->txtBuffer; size_t size = sizeof(this->txtBuffer); - double totalUsage = Machine_updateGpuUsage(this->host); - - if (!isNonnegative(totalUsage)) { + if (!isNonnegative(host->totalGPUUsage)) { this->values[0] = 0; int written = xSnprintf(buffer, size, "N/A"); METER_BUFFER_CHECK(buffer, size, written); - return; + return; } - int written = xSnprintf(buffer, size, "%.1f", totalUsage); - METER_BUFFER_CHECK(buffer, size, written); - METER_BUFFER_APPEND_CHR(buffer, size, '%'); + int written = xSnprintf(buffer, size, "%.1f", host->totalGPUUsage); + METER_BUFFER_CHECK(buffer, size, written); + METER_BUFFER_APPEND_CHR(buffer, size, '%'); } static void GPUMeter_display(const Object* cast, RichString* out) { diff --git a/Machine.h b/Machine.h index c9976840c..4c35ef746 100644 --- a/Machine.h +++ b/Machine.h @@ -97,6 +97,6 @@ void Machine_scan(Machine* this); void Machine_scanTables(Machine* this); -double Machine_updateGpuUsage(Machine* this); +void Machine_scanGPUUsage(Machine* super); #endif diff --git a/darwin/DarwinMachine.c b/darwin/DarwinMachine.c index b386fdf97..5aa52a47e 100644 --- a/darwin/DarwinMachine.c +++ b/darwin/DarwinMachine.c @@ -16,6 +16,8 @@ in the source distribution for its full text. #include #include #include +#include +#include #include "CRT.h" #include "Machine.h" @@ -84,6 +86,7 @@ void Machine_scan(Machine* super) { DarwinMachine_allocateCPULoadInfo(&host->curr_load); DarwinMachine_getVMStats(host); openzfs_sysctl_updateArcStats(&host->zfs); + Machine_scanGPUUsage(super); } Machine* Machine_new(UsersTable* usersTable, uid_t userId) { @@ -105,12 +108,23 @@ Machine* Machine_new(UsersTable* usersTable, uid_t userId) { openzfs_sysctl_init(&this->zfs); openzfs_sysctl_updateArcStats(&this->zfs); + this->GPUService = IOServiceGetMatchingService(kIOMainPortDefault, IOServiceMatching("IOGPU")); + if(!this->GPUService) { + CRT_debug("Cannot create macOS GPUService"); + } + + /* Initialize GPU metric read-out */ + super->totalGPUUsage = NAN; + super->totalGPUTimeDiff = (unsigned long long)-1; + return super; } void Machine_delete(Machine* super) { DarwinMachine* this = (DarwinMachine*) super; + IOObjectRelease(this->GPUService); + DarwinMachine_freeCPULoadInfo(&this->prev_load); Machine_done(super); @@ -126,8 +140,36 @@ bool Machine_isCPUonline(const Machine* host, unsigned int id) { return true; } -double Machine_updateGpuUsage(Machine* super) { - /* Not supported yet */ - (void)super; - return -1; +void Machine_scanGPUUsage(Machine* super) { + DarwinMachine* dhost = (DarwinMachine *)super; + + if (!dhost->GPUService) { + return; + } + + CFMutableDictionaryRef properties = NULL; + kern_return_t ret = IORegistryEntryCreateCFProperties(dhost->GPUService, &properties, kCFAllocatorDefault, kNilOptions); + if (ret != KERN_SUCCESS) { + return; + } + + CFDictionaryRef perfStats = CFDictionaryGetValue(properties, CFSTR("PerformanceStatistics")); + + if (!perfStats) { + goto cleanup; + } + + assert(CFGetTypeID(perfStats) == CFDictionaryGetTypeID()); + + CFNumberRef deviceUtil = CFDictionaryGetValue(perfStats, CFSTR("Device Utilization %")); + if (!deviceUtil) { + goto cleanup; + } + + int device = NAN; + CFNumberGetValue(deviceUtil, kCFNumberIntType, &device); + super->totalGPUUsage = (double)device; + +cleanup: + CFRelease(properties); } diff --git a/darwin/DarwinMachine.h b/darwin/DarwinMachine.h index a4ca1a02e..13a385983 100644 --- a/darwin/DarwinMachine.h +++ b/darwin/DarwinMachine.h @@ -7,6 +7,7 @@ Released under the GNU GPLv2+, see the COPYING file in the source distribution for its full text. */ +#include #include #include @@ -26,6 +27,8 @@ typedef struct DarwinMachine_ { processor_cpu_load_info_t prev_load; processor_cpu_load_info_t curr_load; + io_service_t GPUService; + ZfsArcStats zfs; } DarwinMachine; diff --git a/darwin/Platform.c b/darwin/Platform.c index ec8acb2ff..681a691f3 100644 --- a/darwin/Platform.c +++ b/darwin/Platform.c @@ -38,6 +38,7 @@ in the source distribution for its full text. #include "DateMeter.h" #include "DateTimeMeter.h" #include "FileDescriptorMeter.h" +#include "GPUMeter.h" #include "HostnameMeter.h" #include "LoadAverageMeter.h" #include "Macros.h" @@ -144,6 +145,7 @@ const MeterClass* const Platform_meterTypes[] = { &DiskIOMeter_class, &NetworkIOMeter_class, &FileDescriptorMeter_class, + &GPUMeter_class, &BlankMeter_class, NULL }; diff --git a/dragonflybsd/DragonFlyBSDMachine.c b/dragonflybsd/DragonFlyBSDMachine.c index f38d14fc4..19b6527cd 100644 --- a/dragonflybsd/DragonFlyBSDMachine.c +++ b/dragonflybsd/DragonFlyBSDMachine.c @@ -340,6 +340,7 @@ void Machine_scan(Machine* super) { DragonFlyBSDMachine_scanMemoryInfo(super); DragonFlyBSDMachine_scanCPUTime(super); DragonFlyBSDMachine_scanJails(this); + Machine_scanGPUUsage(super); } bool Machine_isCPUonline(const Machine* host, unsigned int id) { @@ -350,8 +351,7 @@ bool Machine_isCPUonline(const Machine* host, unsigned int id) { return true; } -double Machine_updateGpuUsage(Machine* super) { +void Machine_scanGPUUsage(Machine* super) { /* Not supported yet */ - (void)super; - return -1; + super->totalGPUUsage = -1.0; } diff --git a/freebsd/FreeBSDMachine.c b/freebsd/FreeBSDMachine.c index 2b89898f7..3fc0947ac 100644 --- a/freebsd/FreeBSDMachine.c +++ b/freebsd/FreeBSDMachine.c @@ -387,6 +387,7 @@ void Machine_scan(Machine* super) { openzfs_sysctl_updateArcStats(&this->zfs); FreeBSDMachine_scanMemoryInfo(super); FreeBSDMachine_scanCPU(super); + Machine_scanGPUUsage(super); } bool Machine_isCPUonline(const Machine* host, unsigned int id) { @@ -398,8 +399,7 @@ bool Machine_isCPUonline(const Machine* host, unsigned int id) { return true; } -double Machine_updateGpuUsage(Machine* super) { +void Machine_scanGPUUsage(Machine* super) { /* Not supported yet */ - (void)super; - return -1; + super->totalGPUUsage = -1.0; } diff --git a/linux/LinuxMachine.c b/linux/LinuxMachine.c index 8f97b7d0a..e455e9c87 100644 --- a/linux/LinuxMachine.c +++ b/linux/LinuxMachine.c @@ -733,6 +733,7 @@ void Machine_scan(Machine* super) { LinuxMachine_scanZfsArcstats(this); LinuxMachine_scanZramInfo(this); LinuxMachine_scanCPUTime(this); + Machine_scanGPUUsage(super); const Settings* settings = super->settings; if (settings->showCPUFrequency @@ -822,7 +823,7 @@ bool Machine_isCPUonline(const Machine* super, unsigned int id) { return this->cpuData[id + 1].online; } -double Machine_updateGpuUsage(Machine* super) { +void Machine_scanGPUUsage(Machine* super) { LinuxMachine* this = (LinuxMachine*) super; const uint64_t monotonictimeDelta = super->monotonicMs - super->prevMonotonicMs; @@ -836,11 +837,8 @@ double Machine_updateGpuUsage(Machine* super) { this->curResidueTime = this->curGpuTime; for (gpuEngineData = this->gpuEngineData, i = 0; gpuEngineData; gpuEngineData = gpuEngineData->next, i++) { - // unsigned long long int timeDiff = saturatingSub(gpuEngineData->curTime, gpuEngineData->prevTime); - this->curResidueTime = saturatingSub(this->curResidueTime, gpuEngineData->curTime); } super->totalGPUUsage = 100.0 * super->totalGPUTimeDiff / (1000 * 1000) / monotonictimeDelta; - return super->totalGPUUsage; } diff --git a/netbsd/NetBSDMachine.c b/netbsd/NetBSDMachine.c index e1ad6884a..ffe17a255 100644 --- a/netbsd/NetBSDMachine.c +++ b/netbsd/NetBSDMachine.c @@ -270,6 +270,7 @@ void Machine_scan(Machine* super) { NetBSDMachine_scanMemoryInfo(this); NetBSDMachine_scanCPUTime(this); + Machine_scanGPUUsage(super); if (super->settings->showCPUFrequency) { NetBSDMachine_scanCPUFrequency(this); @@ -284,8 +285,7 @@ bool Machine_isCPUonline(const Machine* host, unsigned int id) { return true; } -double Machine_updateGpuUsage(Machine* super) { +void Machine_scanGPUUsage(Machine* super) { /* Not supported yet */ - (void)super; - return -1; + super->totalGPUUsage = -1.0; } diff --git a/openbsd/OpenBSDMachine.c b/openbsd/OpenBSDMachine.c index fe168c828..3ecd02930 100644 --- a/openbsd/OpenBSDMachine.c +++ b/openbsd/OpenBSDMachine.c @@ -280,6 +280,7 @@ void Machine_scan(Machine* super) { OpenBSDMachine_updateCPUcount(this); OpenBSDMachine_scanMemoryInfo(this); OpenBSDMachine_scanCPUTime(this); + Machine_scanGPUUsage(super); } bool Machine_isCPUonline(const Machine* super, unsigned int id) { @@ -289,8 +290,7 @@ bool Machine_isCPUonline(const Machine* super, unsigned int id) { return this->cpuData[id + 1].online; } -double Machine_updateGpuUsage(Machine* super) { +void Machine_scanGPUUsage(Machine* super) { /* Not supported yet */ - (void)super; - return -1; + super->totalGPUUsage = -1.0; } diff --git a/pcp/PCPMachine.c b/pcp/PCPMachine.c index 2afa333b5..e181a58ab 100644 --- a/pcp/PCPMachine.c +++ b/pcp/PCPMachine.c @@ -303,6 +303,7 @@ void Machine_scan(Machine* super) { host->period = (host->timestamp - sample) * 100; PCPMachine_scan(host); + Machine_scanGPUUsage(super); } Machine* Machine_new(UsersTable* usersTable, uid_t userId) { @@ -344,8 +345,7 @@ bool Machine_isCPUonline(const Machine* host, unsigned int id) { return false; } -double Machine_updateGpuUsage(Machine* super) { +void Machine_scanGPUUsage(Machine* super) { /* Not supported yet */ - (void)super; - return -1; + super->totalGPUUsage = -1.0; } diff --git a/solaris/SolarisMachine.c b/solaris/SolarisMachine.c index 231e2668d..427fe3b48 100644 --- a/solaris/SolarisMachine.c +++ b/solaris/SolarisMachine.c @@ -297,6 +297,7 @@ void Machine_scan(Machine* super) { SolarisMachine_scanCPUTime(this); SolarisMachine_scanMemoryInfo(this); SolarisMachine_scanZfsArcstats(this); + Machine_scanGPUUsage(super); } Machine* Machine_new(UsersTable* usersTable, uid_t userId) { @@ -339,8 +340,7 @@ bool Machine_isCPUonline(const Machine* super, unsigned int id) { return (super->existingCPUs == 1) ? true : this->cpus[id + 1].online; } -double Machine_updateGpuUsage(Machine* super) { +void Machine_scanGPUUsage(Machine* super) { /* Not supported yet */ - (void)super; - return -1; + super->totalGPUUsage = -1.0; } diff --git a/unsupported/UnsupportedMachine.c b/unsupported/UnsupportedMachine.c index df134d923..888e6e1a7 100644 --- a/unsupported/UnsupportedMachine.c +++ b/unsupported/UnsupportedMachine.c @@ -22,6 +22,9 @@ Machine* Machine_new(UsersTable* usersTable, uid_t userId) { super->existingCPUs = 1; super->activeCPUs = 1; + super->totalGPUUsage = NAN; + super->totalGPUTimeDiff = (unsigned long long)-1; + return super; } @@ -54,7 +57,3 @@ void Machine_scan(Machine* super) { super->usedSwap = 0; super->cachedSwap = 0; } - -double Machine_updateGpuUsage(Machine* super ATTR_UNUSED) { - return -1; - }