blob: 7194057674805eb6fe9afdc56b40f8cbceca4840 [file] [log] [blame]
// +build freebsd
package mem
import (
"errors"
"os/exec"
"strconv"
"strings"
"github.com/shirou/gopsutil/internal/common"
)
func VirtualMemory() (*VirtualMemoryStat, error) {
pageSize, err := common.DoSysctrl("vm.stats.vm.v_page_size")
if err != nil {
return nil, err
}
p, err := strconv.ParseUint(pageSize[0], 10, 64)
if err != nil {
return nil, err
}
pageCount, err := common.DoSysctrl("vm.stats.vm.v_page_count")
if err != nil {
return nil, err
}
free, err := common.DoSysctrl("vm.stats.vm.v_free_count")
if err != nil {
return nil, err
}
active, err := common.DoSysctrl("vm.stats.vm.v_active_count")
if err != nil {
return nil, err
}
inactive, err := common.DoSysctrl("vm.stats.vm.v_inactive_count")
if err != nil {
return nil, err
}
cache, err := common.DoSysctrl("vm.stats.vm.v_cache_count")
if err != nil {
return nil, err
}
buffer, err := common.DoSysctrl("vfs.bufspace")
if err != nil {
return nil, err
}
wired, err := common.DoSysctrl("vm.stats.vm.v_wire_count")
if err != nil {
return nil, err
}
parsed := make([]uint64, 0, 7)
vv := []string{
pageCount[0],
free[0],
active[0],
inactive[0],
cache[0],
buffer[0],
wired[0],
}
for _, target := range vv {
t, err := strconv.ParseUint(target, 10, 64)
if err != nil {
return nil, err
}
parsed = append(parsed, t)
}
ret := &VirtualMemoryStat{
Total: parsed[0] * p,
Free: parsed[1] * p,
Active: parsed[2] * p,
Inactive: parsed[3] * p,
Cached: parsed[4] * p,
Buffers: parsed[5],
Wired: parsed[6] * 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 := exec.Command(swapinfo).Output()
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")
}