sys_darwin.go 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. //go:build darwin
  2. package sys
  3. import (
  4. "encoding/binary"
  5. "fmt"
  6. "sync"
  7. "syscall"
  8. "github.com/shirou/gopsutil/v4/net"
  9. "golang.org/x/sys/unix"
  10. )
  11. var SIGUSR1 = syscall.SIGUSR1
  12. func GetTCPCount() (int, error) {
  13. stats, err := net.Connections("tcp")
  14. if err != nil {
  15. return 0, err
  16. }
  17. return len(stats), nil
  18. }
  19. func GetUDPCount() (int, error) {
  20. stats, err := net.Connections("udp")
  21. if err != nil {
  22. return 0, err
  23. }
  24. return len(stats), nil
  25. }
  26. // --- CPU Utilization (macOS native) ---
  27. // sysctl kern.cp_time returns 5 longs in the BSD CPUSTATES order:
  28. // user, nice, sys, intr, idle (CP_INTR=3, CP_IDLE=4). gopsutil reads the
  29. // same layout in cpu_darwin_nocgo.go.
  30. var (
  31. cpuMu sync.Mutex
  32. lastTotals [5]uint64
  33. hasLastCPUT bool
  34. )
  35. func CPUPercentRaw() (float64, error) {
  36. raw, err := unix.SysctlRaw("kern.cp_time")
  37. if err != nil {
  38. return 0, err
  39. }
  40. // Expect either 5*8 bytes (uint64) or 5*4 bytes (uint32)
  41. var out [5]uint64
  42. switch len(raw) {
  43. case 5 * 8:
  44. for i := range 5 {
  45. out[i] = binary.LittleEndian.Uint64(raw[i*8 : (i+1)*8])
  46. }
  47. case 5 * 4:
  48. for i := range 5 {
  49. out[i] = uint64(binary.LittleEndian.Uint32(raw[i*4 : (i+1)*4]))
  50. }
  51. default:
  52. return 0, fmt.Errorf("unexpected kern.cp_time size: %d", len(raw))
  53. }
  54. cpuMu.Lock()
  55. defer cpuMu.Unlock()
  56. if !hasLastCPUT {
  57. lastTotals = out
  58. hasLastCPUT = true
  59. return 0, nil
  60. }
  61. var deltas [5]uint64
  62. var totald uint64
  63. for i := range 5 {
  64. deltas[i] = out[i] - lastTotals[i]
  65. totald += deltas[i]
  66. }
  67. lastTotals = out
  68. if totald == 0 {
  69. return 0, nil
  70. }
  71. idleDelta := deltas[4]
  72. busy := totald - idleDelta
  73. pct := float64(busy) / float64(totald) * 100.0
  74. if pct > 100 {
  75. pct = 100
  76. }
  77. return pct, nil
  78. }