Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/MHSanaei/3x-ui.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'util/sys/sys_windows.go')
-rw-r--r--util/sys/sys_windows.go81
1 files changed, 81 insertions, 0 deletions
diff --git a/util/sys/sys_windows.go b/util/sys/sys_windows.go
index fd51d470..f3eae076 100644
--- a/util/sys/sys_windows.go
+++ b/util/sys/sys_windows.go
@@ -5,6 +5,9 @@ package sys
import (
"errors"
+ "sync"
+ "syscall"
+ "unsafe"
"github.com/shirou/gopsutil/v4/net"
)
@@ -28,3 +31,81 @@ func GetTCPCount() (int, error) {
func GetUDPCount() (int, error) {
return GetConnectionCount("udp")
}
+
+// --- CPU Utilization (Windows native) ---
+
+var (
+ modKernel32 = syscall.NewLazyDLL("kernel32.dll")
+ procGetSystemTimes = modKernel32.NewProc("GetSystemTimes")
+
+ cpuMu sync.Mutex
+ lastIdle uint64
+ lastKernel uint64
+ lastUser uint64
+ hasLast bool
+)
+
+type filetime struct {
+ LowDateTime uint32
+ HighDateTime uint32
+}
+
+func ftToUint64(ft filetime) uint64 {
+ return (uint64(ft.HighDateTime) << 32) | uint64(ft.LowDateTime)
+}
+
+// CPUPercentRaw returns the instantaneous total CPU utilization percentage using
+// Windows GetSystemTimes across all logical processors. The first call returns 0
+// as it initializes the baseline. Subsequent calls compute deltas.
+func CPUPercentRaw() (float64, error) {
+ var idleFT, kernelFT, userFT filetime
+ r1, _, e1 := procGetSystemTimes.Call(
+ uintptr(unsafe.Pointer(&idleFT)),
+ uintptr(unsafe.Pointer(&kernelFT)),
+ uintptr(unsafe.Pointer(&userFT)),
+ )
+ if r1 == 0 { // failure
+ if e1 != nil {
+ return 0, e1
+ }
+ return 0, syscall.GetLastError()
+ }
+
+ idle := ftToUint64(idleFT)
+ kernel := ftToUint64(kernelFT)
+ user := ftToUint64(userFT)
+
+ cpuMu.Lock()
+ defer cpuMu.Unlock()
+
+ if !hasLast {
+ lastIdle = idle
+ lastKernel = kernel
+ lastUser = user
+ hasLast = true
+ return 0, nil
+ }
+
+ idleDelta := idle - lastIdle
+ kernelDelta := kernel - lastKernel
+ userDelta := user - lastUser
+
+ // Update for next call
+ lastIdle = idle
+ lastKernel = kernel
+ lastUser = user
+
+ total := kernelDelta + userDelta
+ if total == 0 {
+ return 0, nil
+ }
+ // On Windows, kernel time includes idle time; busy = total - idle
+ busy := total - idleDelta
+
+ pct := float64(busy) / float64(total) * 100.0
+ // lower bound not needed; ratios of uint64 are non-negative
+ if pct > 100 {
+ pct = 100
+ }
+ return pct, nil
+}