[mem][freebsd]: add SysctlUint which can adapt both 32 and 64 bit

pull/649/head
WAKAYAMA shirou 6 years ago
parent ebc97eefea
commit bb15c85289

@ -3,6 +3,7 @@
package common package common
import ( import (
"fmt"
"os" "os"
"os/exec" "os/exec"
"strings" "strings"
@ -11,6 +12,21 @@ import (
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
) )
func SysctlUint(mib string) (uint64, error) {
buf, err := unix.SysctlRaw(mib)
if err != nil {
return 0, err
}
if len(buf) == 8 { // 64 bit
return *(*uint64)(unsafe.Pointer(&buf[0])), nil
}
if len(buf) == 4 { // 32bit
t := *(*uint32)(unsafe.Pointer(&buf[0]))
return uint64(t), nil
}
return 0, fmt.Errorf("unexpected size: %s, %d", mib, len(buf))
}
func DoSysctrl(mib string) ([]string, error) { func DoSysctrl(mib string) ([]string, error) {
sysctl, err := exec.LookPath("/sbin/sysctl") sysctl, err := exec.LookPath("/sbin/sysctl")
if err != nil { if err != nil {

@ -8,6 +8,8 @@ import (
"unsafe" "unsafe"
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
"github.com/shirou/gopsutil/internal/common"
) )
func VirtualMemory() (*VirtualMemoryStat, error) { func VirtualMemory() (*VirtualMemoryStat, error) {
@ -15,58 +17,59 @@ func VirtualMemory() (*VirtualMemoryStat, error) {
} }
func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) { func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) {
pageSize, err := unix.SysctlUint32("vm.stats.vm.v_page_size") pageSize, err := common.SysctlUint("vm.stats.vm.v_page_size")
if err != nil { if err != nil {
return nil, err return nil, err
} }
physmem, err := unix.SysctlUint64("hw.physmem") physmem, err := common.SysctlUint("hw.physmem")
if err != nil { if err != nil {
return nil, err return nil, err
} }
free, err := unix.SysctlUint32("vm.stats.vm.v_free_count")
free, err := common.SysctlUint("vm.stats.vm.v_free_count")
if err != nil { if err != nil {
return nil, err return nil, err
} }
active, err := unix.SysctlUint32("vm.stats.vm.v_active_count") active, err := common.SysctlUint("vm.stats.vm.v_active_count")
if err != nil { if err != nil {
return nil, err return nil, err
} }
inactive, err := unix.SysctlUint32("vm.stats.vm.v_inactive_count") inactive, err := common.SysctlUint("vm.stats.vm.v_inactive_count")
if err != nil { if err != nil {
return nil, err return nil, err
} }
buffers, err := unix.SysctlUint64("vfs.bufspace") buffers, err := common.SysctlUint("vfs.bufspace")
if err != nil { if err != nil {
return nil, err return nil, err
} }
wired, err := unix.SysctlUint32("vm.stats.vm.v_wire_count") wired, err := common.SysctlUint("vm.stats.vm.v_wire_count")
if err != nil { if err != nil {
return nil, err return nil, err
} }
var cached, laundry uint32 var cached, laundry uint64
osreldate, _ := unix.SysctlUint32("kern.osreldate") osreldate, _ := common.SysctlUint("kern.osreldate")
if osreldate < 1102000 { if osreldate < 1102000 {
cached, err = unix.SysctlUint32("vm.stats.vm.v_cache_count") cached, err = common.SysctlUint("vm.stats.vm.v_cache_count")
if err != nil { if err != nil {
return nil, err return nil, err
} }
} else { } else {
laundry, err = unix.SysctlUint32("vm.stats.vm.v_laundry_count") laundry, err = common.SysctlUint("vm.stats.vm.v_laundry_count")
if err != nil { if err != nil {
return nil, err return nil, err
} }
} }
p := uint64(pageSize) p := pageSize
ret := &VirtualMemoryStat{ ret := &VirtualMemoryStat{
Total: uint64(physmem), Total: physmem,
Free: uint64(free) * p, Free: free * p,
Active: uint64(active) * p, Active: active * p,
Inactive: uint64(inactive) * p, Inactive: inactive * p,
Cached: uint64(cached) * p, Cached: cached * p,
Buffers: uint64(buffers), Buffers: buffers,
Wired: uint64(wired) * p, Wired: wired * p,
Laundry: uint64(laundry) * p, Laundry: laundry * p,
} }
ret.Available = ret.Inactive + ret.Cached + ret.Free + ret.Laundry ret.Available = ret.Inactive + ret.Cached + ret.Free + ret.Laundry
@ -109,7 +112,7 @@ type xswdev11 struct {
func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) { func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) {
// FreeBSD can have multiple swap devices so we total them up // FreeBSD can have multiple swap devices so we total them up
i, err := unix.SysctlUint32("vm.nswapdev") i, err := common.SysctlUint("vm.nswapdev")
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -120,11 +123,11 @@ func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) {
c := int(i) c := int(i)
i, err = unix.SysctlUint32("vm.stats.vm.v_page_size") i, err = common.SysctlUint("vm.stats.vm.v_page_size")
if err != nil { if err != nil {
return nil, err return nil, err
} }
pageSize := uint64(i) pageSize := i
var buf []byte var buf []byte
s := &SwapMemoryStat{} s := &SwapMemoryStat{}

@ -21,6 +21,7 @@ func TestVirtual_memory(t *testing.T) {
if v == empty { if v == empty {
t.Errorf("error %v", v) t.Errorf("error %v", v)
} }
t.Log(v)
assert.True(t, v.Total > 0) assert.True(t, v.Total > 0)
assert.True(t, v.Available > 0) assert.True(t, v.Available > 0)
@ -64,6 +65,8 @@ func TestSwap_memory(t *testing.T) {
if v == empty { if v == empty {
t.Errorf("error %v", v) t.Errorf("error %v", v)
} }
t.Log(v)
} }
func TestVirtualMemoryStat_String(t *testing.T) { func TestVirtualMemoryStat_String(t *testing.T) {

Loading…
Cancel
Save