package stats import ( "unsafe" ) var ( procGetSystemTimes = kernel32.NewProc("GetSystemTimes") ) type filetime struct { LowDateTime uint32 HighDateTime uint32 } func filetimeToUint64(ft filetime) uint64 { return (uint64(ft.HighDateTime) << 32) | uint64(ft.LowDateTime) } func (r *Reporter) SystemCPUPercent() float64 { r.mu.Lock() defer r.mu.Unlock() var idle, kernel, user filetime ret, _, _ := procGetSystemTimes.Call( uintptr(unsafe.Pointer(&idle)), uintptr(unsafe.Pointer(&kernel)), uintptr(unsafe.Pointer(&user)), ) if ret == 0 { return 0 } idleTicks := filetimeToUint64(idle) kernelTicks := filetimeToUint64(kernel) userTicks := filetimeToUint64(user) if !r.hasSample { r.lastIdle = idleTicks r.lastKernel = kernelTicks r.lastUser = userTicks r.hasSample = true return 0 } idleDelta := float64(idleTicks - r.lastIdle) totalDelta := float64((kernelTicks - r.lastKernel) + (userTicks - r.lastUser)) r.lastIdle = idleTicks r.lastKernel = kernelTicks r.lastUser = userTicks if totalDelta <= 0 { return 0 } busyPct := (1.0 - idleDelta/totalDelta) * 100 if busyPct < 0 { return 0 } if busyPct > 100 { return 100 } return busyPct }