3x-ui/util/sys/sys_darwin.go

92 lines
1.7 KiB
Go
Raw Normal View History

2023-03-17 16:07:49 +00:00
//go:build darwin
2023-02-09 19:18:06 +00:00
package sys
import (
2025-09-16 12:15:18 +00:00
"encoding/binary"
"fmt"
"sync"
2026-02-20 01:07:46 +00:00
"syscall"
2025-09-16 12:15:18 +00:00
2024-06-17 19:48:49 +00:00
"github.com/shirou/gopsutil/v4/net"
2025-09-16 12:15:18 +00:00
"golang.org/x/sys/unix"
2023-02-09 19:18:06 +00:00
)
2026-02-20 01:07:46 +00:00
var SIGUSR1 = syscall.SIGUSR1
2023-02-09 19:18:06 +00:00
func GetTCPCount() (int, error) {
stats, err := net.Connections("tcp")
if err != nil {
return 0, err
}
return len(stats), nil
}
func GetUDPCount() (int, error) {
stats, err := net.Connections("udp")
if err != nil {
return 0, err
}
return len(stats), nil
}
2025-09-16 12:15:18 +00:00
// --- CPU Utilization (macOS native) ---
// sysctl kern.cp_time returns 5 longs in the BSD CPUSTATES order:
// user, nice, sys, intr, idle (CP_INTR=3, CP_IDLE=4). gopsutil reads the
// same layout in cpu_darwin_nocgo.go.
2025-09-16 12:15:18 +00:00
var (
cpuMu sync.Mutex
lastTotals [5]uint64
hasLastCPUT bool
)
func CPUPercentRaw() (float64, error) {
raw, err := unix.SysctlRaw("kern.cp_time")
if err != nil {
return 0, err
}
// Expect either 5*8 bytes (uint64) or 5*4 bytes (uint32)
var out [5]uint64
switch len(raw) {
case 5 * 8:
for i := range 5 {
2025-09-16 12:15:18 +00:00
out[i] = binary.LittleEndian.Uint64(raw[i*8 : (i+1)*8])
}
case 5 * 4:
for i := range 5 {
2025-09-16 12:15:18 +00:00
out[i] = uint64(binary.LittleEndian.Uint32(raw[i*4 : (i+1)*4]))
}
default:
return 0, fmt.Errorf("unexpected kern.cp_time size: %d", len(raw))
}
cpuMu.Lock()
defer cpuMu.Unlock()
if !hasLastCPUT {
lastTotals = out
hasLastCPUT = true
return 0, nil
}
var deltas [5]uint64
var totald uint64
for i := range 5 {
deltas[i] = out[i] - lastTotals[i]
totald += deltas[i]
}
2025-09-16 12:15:18 +00:00
lastTotals = out
if totald == 0 {
return 0, nil
}
idleDelta := deltas[4]
busy := totald - idleDelta
2025-09-16 12:15:18 +00:00
pct := float64(busy) / float64(totald) * 100.0
if pct > 100 {
pct = 100
}
return pct, nil
}