github.com/NVIDIA/aistore@v1.3.23-0.20240517131212-7df6609be51d/sys/mem_darwin.go (about) 1 // Package sys provides methods to read system information 2 /* 3 * Copyright (c) 2018-2021, NVIDIA CORPORATION. All rights reserved. 4 */ 5 package sys 6 7 /* 8 #include <mach/mach_host.h> 9 */ 10 import "C" //nolint:gci,gocritic // super weird case 11 12 import ( 13 "bytes" 14 "encoding/binary" 15 "errors" 16 "fmt" 17 "syscall" 18 "unsafe" //nolint:gocritic // super weird case 19 ) 20 21 type ( 22 swapStats struct { 23 Total uint64 24 Free uint64 25 Used uint64 26 } 27 ) 28 29 func readSysctl(name string, data any) (err error) { 30 value, err := syscall.Sysctl(name) 31 if err != nil { 32 return err 33 } 34 35 buf := []byte(value) 36 37 switch v := data.(type) { 38 case *uint64: 39 *v = *(*uint64)(unsafe.Pointer(&buf[0])) 40 return 41 default: 42 b := bytes.NewBuffer(buf) 43 return binary.Read(b, binary.LittleEndian, data) 44 } 45 } 46 47 func readTotalMemory() (uint64, error) { 48 var totalMem uint64 49 if err := readSysctl("hw.memsize", &totalMem); err != nil { 50 return 0, err 51 } 52 return totalMem, nil 53 } 54 55 func readVMStat(vmstat *C.vm_statistics_data_t) error { 56 var count C.mach_msg_type_number_t = C.HOST_VM_INFO_COUNT 57 status := C.host_statistics( 58 C.mach_host_self(), 59 C.HOST_VM_INFO, 60 C.host_info_t(unsafe.Pointer(vmstat)), 61 &count, 62 ) 63 if status != C.KERN_SUCCESS { 64 return fmt.Errorf("host_statistics=%v", status) 65 } 66 return nil 67 } 68 69 func (mem *MemStat) host() error { 70 totalMem, err := readTotalMemory() 71 if err != nil { 72 return err 73 } 74 75 var vmstat C.vm_statistics_data_t 76 if err := readVMStat(&vmstat); err != nil { 77 return err 78 } 79 80 var ( 81 sstats = swapStats{} 82 pageSize = uint64(1 << 12) 83 freeMem = uint64(vmstat.free_count) * pageSize 84 kern = uint64(vmstat.inactive_count) * pageSize 85 ) 86 if err := readSysctl("vm.swapusage", &sstats); err != nil { 87 return err 88 } 89 { 90 mem.Total = totalMem 91 mem.Free = freeMem 92 mem.Used = totalMem - freeMem 93 mem.ActualFree = freeMem + kern 94 mem.ActualUsed = totalMem - freeMem - kern 95 mem.SwapTotal = sstats.Total 96 mem.SwapFree = sstats.Free 97 mem.SwapUsed = sstats.Used 98 } 99 return nil 100 } 101 102 func (*MemStat) container() error { return errors.New("Darwin: cannot get container memory stats") }