mirror of
https://github.com/shirou/gopsutil.git
synced 2025-04-26 13:48:59 +08:00

Executing the command does the lookup if needed and returns the same error when not found, no need to do it separately.
90 lines
1.8 KiB
Go
90 lines
1.8 KiB
Go
//go:build darwin && !cgo
|
|
// +build darwin,!cgo
|
|
|
|
package mem
|
|
|
|
import (
|
|
"context"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"golang.org/x/sys/unix"
|
|
)
|
|
|
|
// Runs vm_stat and returns Free and inactive pages
|
|
func getVMStat(vms *VirtualMemoryStat) error {
|
|
out, err := invoke.Command("vm_stat")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return parseVMStat(string(out), vms)
|
|
}
|
|
|
|
func parseVMStat(out string, vms *VirtualMemoryStat) error {
|
|
var err error
|
|
|
|
lines := strings.Split(out, "\n")
|
|
pagesize := uint64(unix.Getpagesize())
|
|
for _, line := range lines {
|
|
fields := strings.Split(line, ":")
|
|
if len(fields) < 2 {
|
|
continue
|
|
}
|
|
key := strings.TrimSpace(fields[0])
|
|
value := strings.Trim(fields[1], " .")
|
|
switch key {
|
|
case "Pages free":
|
|
free, e := strconv.ParseUint(value, 10, 64)
|
|
if e != nil {
|
|
err = e
|
|
}
|
|
vms.Free = free * pagesize
|
|
case "Pages inactive":
|
|
inactive, e := strconv.ParseUint(value, 10, 64)
|
|
if e != nil {
|
|
err = e
|
|
}
|
|
vms.Inactive = inactive * pagesize
|
|
case "Pages active":
|
|
active, e := strconv.ParseUint(value, 10, 64)
|
|
if e != nil {
|
|
err = e
|
|
}
|
|
vms.Active = active * pagesize
|
|
case "Pages wired down":
|
|
wired, e := strconv.ParseUint(value, 10, 64)
|
|
if e != nil {
|
|
err = e
|
|
}
|
|
vms.Wired = wired * pagesize
|
|
}
|
|
}
|
|
return err
|
|
}
|
|
|
|
// VirtualMemory returns VirtualmemoryStat.
|
|
func VirtualMemory() (*VirtualMemoryStat, error) {
|
|
return VirtualMemoryWithContext(context.Background())
|
|
}
|
|
|
|
func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) {
|
|
ret := &VirtualMemoryStat{}
|
|
|
|
total, err := getHwMemsize()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
err = getVMStat(ret)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
ret.Available = ret.Free + ret.Inactive
|
|
ret.Total = total
|
|
|
|
ret.Used = ret.Total - ret.Available
|
|
ret.UsedPercent = 100 * float64(ret.Used) / float64(ret.Total)
|
|
|
|
return ret, nil
|
|
}
|