mem_openbsd.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. // +build openbsd
  2. package mem
  3. import (
  4. "bytes"
  5. "context"
  6. "encoding/binary"
  7. "errors"
  8. "fmt"
  9. "os/exec"
  10. "github.com/shirou/gopsutil/internal/common"
  11. "golang.org/x/sys/unix"
  12. )
  13. func GetPageSize() (uint64, error) {
  14. return GetPageSizeWithContext(context.Background())
  15. }
  16. func GetPageSizeWithContext(ctx context.Context) (uint64, error) {
  17. uvmexp, err := unix.SysctlUvmexp("vm.uvmexp")
  18. if err != nil {
  19. return 0, err
  20. }
  21. return uint64(uvmexp.Pagesize), nil
  22. }
  23. func VirtualMemory() (*VirtualMemoryStat, error) {
  24. return VirtualMemoryWithContext(context.Background())
  25. }
  26. func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) {
  27. uvmexp, err := unix.SysctlUvmexp("vm.uvmexp")
  28. if err != nil {
  29. return nil, err
  30. }
  31. p := uint64(uvmexp.Pagesize)
  32. ret := &VirtualMemoryStat{
  33. Total: uint64(uvmexp.Npages) * p,
  34. Free: uint64(uvmexp.Free) * p,
  35. Active: uint64(uvmexp.Active) * p,
  36. Inactive: uint64(uvmexp.Inactive) * p,
  37. Cached: 0, // not available
  38. Wired: uint64(uvmexp.Wired) * p,
  39. }
  40. ret.Available = ret.Inactive + ret.Cached + ret.Free
  41. ret.Used = ret.Total - ret.Available
  42. ret.UsedPercent = float64(ret.Used) / float64(ret.Total) * 100.0
  43. mib := []int32{CTLVfs, VfsGeneric, VfsBcacheStat}
  44. buf, length, err := common.CallSyscall(mib)
  45. if err != nil {
  46. return nil, err
  47. }
  48. if length < sizeOfBcachestats {
  49. return nil, fmt.Errorf("short syscall ret %d bytes", length)
  50. }
  51. var bcs Bcachestats
  52. br := bytes.NewReader(buf)
  53. err = common.Read(br, binary.LittleEndian, &bcs)
  54. if err != nil {
  55. return nil, err
  56. }
  57. ret.Buffers = uint64(bcs.Numbufpages) * p
  58. return ret, nil
  59. }
  60. // Return swapctl summary info
  61. func SwapMemory() (*SwapMemoryStat, error) {
  62. return SwapMemoryWithContext(context.Background())
  63. }
  64. func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) {
  65. swapctl, err := exec.LookPath("swapctl")
  66. if err != nil {
  67. return nil, err
  68. }
  69. out, err := invoke.CommandWithContext(ctx, swapctl, "-sk")
  70. if err != nil {
  71. return &SwapMemoryStat{}, nil
  72. }
  73. line := string(out)
  74. var total, used, free uint64
  75. _, err = fmt.Sscanf(line,
  76. "total: %d 1K-blocks allocated, %d used, %d available",
  77. &total, &used, &free)
  78. if err != nil {
  79. return nil, errors.New("failed to parse swapctl output")
  80. }
  81. percent := float64(used) / float64(total) * 100
  82. return &SwapMemoryStat{
  83. Total: total * 1024,
  84. Used: used * 1024,
  85. Free: free * 1024,
  86. UsedPercent: percent,
  87. }, nil
  88. }