mirror of
https://github.com/shirou/gopsutil.git
synced 2025-05-12 19:29:30 +08:00

In order to improve performance and help prevent crashes due to the outstanding fork crash bug: https://github.com/golang/go/issues/15658 Replace string parsed values from the sysctl command with native reads of sysctl values using unix.SysctlRaw and unix.SysctlUint32. This also merges OpenBSD and FreeBSD load implementations which are identical.
113 lines
2.4 KiB
Go
113 lines
2.4 KiB
Go
// +build freebsd
|
|
|
|
package mem
|
|
|
|
import (
|
|
"errors"
|
|
"os/exec"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"golang.org/x/sys/unix"
|
|
)
|
|
|
|
func VirtualMemory() (*VirtualMemoryStat, error) {
|
|
pageSize, err := unix.SysctlUint32("vm.stats.vm.v_page_size")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
pageCount, err := unix.SysctlUint32("vm.stats.vm.v_page_count")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
free, err := unix.SysctlUint32("vm.stats.vm.v_free_count")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
active, err := unix.SysctlUint32("vm.stats.vm.v_active_count")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
inactive, err := unix.SysctlUint32("vm.stats.vm.v_inactive_count")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
cached, err := unix.SysctlUint32("vm.stats.vm.v_cache_count")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
buffers, err := unix.SysctlUint32("vfs.bufspace")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
wired, err := unix.SysctlUint32("vm.stats.vm.v_wire_count")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
p := uint64(pageSize)
|
|
ret := &VirtualMemoryStat{
|
|
Total: uint64(pageCount) * p,
|
|
Free: uint64(free) * p,
|
|
Active: uint64(active) * p,
|
|
Inactive: uint64(inactive) * p,
|
|
Cached: uint64(cached) * p,
|
|
Buffers: uint64(buffers),
|
|
Wired: uint64(wired) * p,
|
|
}
|
|
|
|
ret.Available = ret.Inactive + ret.Cached + ret.Free
|
|
ret.Used = ret.Total - ret.Available
|
|
ret.UsedPercent = float64(ret.Used) / float64(ret.Total) * 100.0
|
|
|
|
return ret, nil
|
|
}
|
|
|
|
// Return swapinfo
|
|
// FreeBSD can have multiple swap devices. but use only first device
|
|
func SwapMemory() (*SwapMemoryStat, error) {
|
|
swapinfo, err := exec.LookPath("swapinfo")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
out, err := invoke.Command(swapinfo)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for _, line := range strings.Split(string(out), "\n") {
|
|
values := strings.Fields(line)
|
|
// skip title line
|
|
if len(values) == 0 || values[0] == "Device" {
|
|
continue
|
|
}
|
|
|
|
u := strings.Replace(values[4], "%", "", 1)
|
|
total_v, err := strconv.ParseUint(values[1], 10, 64)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
used_v, err := strconv.ParseUint(values[2], 10, 64)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
free_v, err := strconv.ParseUint(values[3], 10, 64)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
up_v, err := strconv.ParseFloat(u, 64)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &SwapMemoryStat{
|
|
Total: total_v,
|
|
Used: used_v,
|
|
Free: free_v,
|
|
UsedPercent: up_v,
|
|
}, nil
|
|
}
|
|
|
|
return nil, errors.New("no swap devices found")
|
|
}
|