github.com/gofiber/fiber/v2@v2.47.0/internal/gopsutil/mem/mem_openbsd.go (about)

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