123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- //go:build windows
- // +build windows
- package sys
- import (
- "errors"
- "sync"
- "syscall"
- "unsafe"
- "github.com/shirou/gopsutil/v4/net"
- )
- func GetConnectionCount(proto string) (int, error) {
- if proto != "tcp" && proto != "udp" {
- return 0, errors.New("invalid protocol")
- }
- stats, err := net.Connections(proto)
- if err != nil {
- return 0, err
- }
- return len(stats), nil
- }
- func GetTCPCount() (int, error) {
- return GetConnectionCount("tcp")
- }
- 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
- }
|