| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- //go:build darwin
- package sys
- import (
- "encoding/binary"
- "fmt"
- "sync"
- "syscall"
- "github.com/shirou/gopsutil/v4/net"
- "golang.org/x/sys/unix"
- )
- var SIGUSR1 = syscall.SIGUSR1
- 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
- }
- // --- 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.
- 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 {
- out[i] = binary.LittleEndian.Uint64(raw[i*8 : (i+1)*8])
- }
- case 5 * 4:
- for i := range 5 {
- 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]
- }
- lastTotals = out
- if totald == 0 {
- return 0, nil
- }
- idleDelta := deltas[4]
- busy := totald - idleDelta
- pct := float64(busy) / float64(totald) * 100.0
- if pct > 100 {
- pct = 100
- }
- return pct, nil
- }
|