github.com/isyscore/isc-gobase@v1.5.3-0.20231218061332-cbc7451899e9/system/mem/mem_darwin_nocgo.go (about) 1 //go:build darwin && !cgo 2 3 package mem 4 5 import ( 6 "context" 7 "os/exec" 8 "strconv" 9 "strings" 10 11 "golang.org/x/sys/unix" 12 ) 13 14 // Runs vm_stat and returns Free and inactive pages 15 func getVMStat(vms *VirtualMemoryStat) error { 16 vm_stat, err := exec.LookPath("vm_stat") 17 if err != nil { 18 return err 19 } 20 out, err := invoke.Command(vm_stat) 21 if err != nil { 22 return err 23 } 24 return parseVMStat(string(out), vms) 25 } 26 27 func parseVMStat(out string, vms *VirtualMemoryStat) error { 28 var err error 29 30 lines := strings.Split(out, "\n") 31 pagesize := uint64(unix.Getpagesize()) 32 for _, line := range lines { 33 fields := strings.Split(line, ":") 34 if len(fields) < 2 { 35 continue 36 } 37 key := strings.TrimSpace(fields[0]) 38 value := strings.Trim(fields[1], " .") 39 switch key { 40 case "Pages free": 41 free, e := strconv.ParseUint(value, 10, 64) 42 if e != nil { 43 err = e 44 } 45 vms.Free = free * pagesize 46 case "Pages inactive": 47 inactive, e := strconv.ParseUint(value, 10, 64) 48 if e != nil { 49 err = e 50 } 51 vms.Inactive = inactive * pagesize 52 case "Pages active": 53 active, e := strconv.ParseUint(value, 10, 64) 54 if e != nil { 55 err = e 56 } 57 vms.Active = active * pagesize 58 case "Pages wired down": 59 wired, e := strconv.ParseUint(value, 10, 64) 60 if e != nil { 61 err = e 62 } 63 vms.Wired = wired * pagesize 64 } 65 } 66 return err 67 } 68 69 // VirtualMemory returns VirtualmemoryStat. 70 func VirtualMemory() (*VirtualMemoryStat, error) { 71 return VirtualMemoryWithContext(context.Background()) 72 } 73 74 func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) { 75 ret := &VirtualMemoryStat{} 76 77 total, err := getHwMemsize() 78 if err != nil { 79 return nil, err 80 } 81 err = getVMStat(ret) 82 if err != nil { 83 return nil, err 84 } 85 86 ret.Available = ret.Free + ret.Inactive 87 ret.Total = total 88 89 ret.Used = ret.Total - ret.Available 90 ret.UsedPercent = 100 * float64(ret.Used) / float64(ret.Total) 91 92 return ret, nil 93 }