//go:build windows package loadaverage import ( "fmt" "rpi5-health/internal/windows_system" "sync" "syscall" "time" "unsafe" ) const ( // Formatting flag for PdhGetFormattedCounterValue to return a float64 PDH_FMT_DOUBLE = 0x00000200 ERROR_SUCCESS = 0 ) // PDH_FMT_COUNTERVALUE_DOUBLE maps the C struct _PDH_FMT_COUNTERVALUE for double values. // * Note the explicit padding: C++ unions align to 8 bytes on 64-bit systems. type PDH_FMT_COUNTERVALUE_DOUBLE struct { CStatus uint32 Pad uint32 // ! Crucial padding for 64-bit alignment before the float64 DoubleValue float64 // Represents the union where the double is stored } var ( GlobalLoadAverage LoadAverageInformation // 1. A RWMutex protects the struct from concurrent reads/writes loadMu sync.RWMutex startWorker = sync.OnceFunc(func() { go loadAverageWorker() }) ) func loadAverageWorker() { var hQuery syscall.Handle // PDH_HQUERY var hCounter syscall.Handle // PDH_HCOUNTER wintools := windows_system.GetWindowsTools() // initialize query ret, _, _ := wintools.ProcPdhOpenQuery.Call(0, 0, uintptr(unsafe.Pointer(&hQuery))) if ret != ERROR_SUCCESS { fmt.Printf("PdhOpenQueryW failed: %x\n", ret) return } defer wintools.ProcPdhCloseQuery.Call(uintptr(hQuery)) counterPath, _ := syscall.UTF16PtrFromString(`\Processor(_Total)\% Processor Time`) ret, _, _ = wintools.ProcPdhAddCounter.Call( uintptr(hQuery), uintptr(unsafe.Pointer(counterPath)), 0, uintptr(unsafe.Pointer(&hCounter)), ) if ret != ERROR_SUCCESS { fmt.Printf("PdhAddCounterW failed: %x\n", ret) return } // Collect initial data, "priming the counter" wintools.ProcPdhCollectQueryData.Call(uintptr(hQuery)) // Infinite collection loop for { time.Sleep(SAMPLE_DELAY) wintools.ProcPdhCollectQueryData.Call(uintptr(hQuery)) var counterType uint32 var value PDH_FMT_COUNTERVALUE_DOUBLE ret, _, _ = wintools.ProcPdhGetFormattedCounterValue.Call( uintptr(hCounter), uintptr(PDH_FMT_DOUBLE), uintptr(unsafe.Pointer(&counterType)), uintptr(unsafe.Pointer(&value)), ) if ret == ERROR_SUCCESS { loadMu.Lock() GlobalLoadAverage.Update(value.DoubleValue) loadMu.Unlock() } else { fmt.Printf("PdhGetFormattedCounterValue failed: %x\n", ret) } } } func GetLoadAverage() (LoadAverageInformation, error) { startWorker() loadMu.RLock() defer loadMu.RUnlock() return GlobalLoadAverage, nil }