//go:build windows package api import ( "syscall" "unsafe" ) var ( kernel32 = syscall.NewLazyDLL("kernel32.dll") globalMemoryStatusEx = kernel32.NewProc("GlobalMemoryStatusEx") getSystemTimes = kernel32.NewProc("GetSystemTimes") ) // MEMORYSTATUSEX structure type memoryStatusEx struct { dwLength uint32 dwMemoryLoad uint32 ullTotalPhys uint64 ullAvailPhys uint64 ullTotalPageFile uint64 ullAvailPageFile uint64 ullTotalVirtual uint64 ullAvailVirtual uint64 ullAvailExtendedVirtual uint64 } func getMemoryInfo() (total, used uint64) { var ms memoryStatusEx ms.dwLength = uint32(unsafe.Sizeof(ms)) ret, _, _ := globalMemoryStatusEx.Call(uintptr(unsafe.Pointer(&ms))) if ret == 0 { return 0, 0 } return ms.ullTotalPhys, ms.ullTotalPhys - ms.ullAvailPhys } type filetime struct { dwLowDateTime uint32 dwHighDateTime uint32 } func (ft filetime) ticks() uint64 { return uint64(ft.dwHighDateTime)<<32 | uint64(ft.dwLowDateTime) } var prevIdleWin, prevTotalWin uint64 func getCPUUsage() float64 { var idleTime, kernelTime, userTime filetime ret, _, _ := getSystemTimes.Call( uintptr(unsafe.Pointer(&idleTime)), uintptr(unsafe.Pointer(&kernelTime)), uintptr(unsafe.Pointer(&userTime)), ) if ret == 0 { return 0 } idle := idleTime.ticks() total := kernelTime.ticks() + userTime.ticks() // kernel includes idle deltaTotal := total - prevTotalWin deltaIdle := idle - prevIdleWin prevIdleWin = idle prevTotalWin = total if deltaTotal == 0 { return 0 } return float64(deltaTotal-deltaIdle) / float64(deltaTotal) * 100 }