github.com/boomhut/fiber/v2@v2.0.0-20230603160335-b65c856e57d3/internal/gopsutil/mem/mem_windows.go (about)

     1  //go:build windows
     2  // +build windows
     3  
     4  package mem
     5  
     6  import (
     7  	"context"
     8  	"unsafe"
     9  
    10  	"github.com/boomhut/fiber/v2/internal/gopsutil/common"
    11  	"golang.org/x/sys/windows"
    12  )
    13  
    14  var (
    15  	procGlobalMemoryStatusEx = common.Modkernel32.NewProc("GlobalMemoryStatusEx")
    16  	procGetPerformanceInfo   = common.ModPsapi.NewProc("GetPerformanceInfo")
    17  )
    18  
    19  type memoryStatusEx struct {
    20  	cbSize                  uint32
    21  	dwMemoryLoad            uint32
    22  	ullTotalPhys            uint64 // in bytes
    23  	ullAvailPhys            uint64
    24  	ullTotalPageFile        uint64
    25  	ullAvailPageFile        uint64
    26  	ullTotalVirtual         uint64
    27  	ullAvailVirtual         uint64
    28  	ullAvailExtendedVirtual uint64
    29  }
    30  
    31  func VirtualMemory() (*VirtualMemoryStat, error) {
    32  	return VirtualMemoryWithContext(context.Background())
    33  }
    34  
    35  func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) {
    36  	var memInfo memoryStatusEx
    37  	memInfo.cbSize = uint32(unsafe.Sizeof(memInfo))
    38  	mem, _, _ := procGlobalMemoryStatusEx.Call(uintptr(unsafe.Pointer(&memInfo)))
    39  	if mem == 0 {
    40  		return nil, windows.GetLastError()
    41  	}
    42  
    43  	ret := &VirtualMemoryStat{
    44  		Total:       memInfo.ullTotalPhys,
    45  		Available:   memInfo.ullAvailPhys,
    46  		Free:        memInfo.ullAvailPhys,
    47  		UsedPercent: float64(memInfo.dwMemoryLoad),
    48  	}
    49  
    50  	ret.Used = ret.Total - ret.Available
    51  	return ret, nil
    52  }
    53  
    54  type performanceInformation struct {
    55  	cb                uint32
    56  	commitTotal       uint64
    57  	commitLimit       uint64
    58  	commitPeak        uint64
    59  	physicalTotal     uint64
    60  	physicalAvailable uint64
    61  	systemCache       uint64
    62  	kernelTotal       uint64
    63  	kernelPaged       uint64
    64  	kernelNonpaged    uint64
    65  	pageSize          uint64
    66  	handleCount       uint32
    67  	processCount      uint32
    68  	threadCount       uint32
    69  }
    70  
    71  func SwapMemory() (*SwapMemoryStat, error) {
    72  	return SwapMemoryWithContext(context.Background())
    73  }
    74  
    75  func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) {
    76  	var perfInfo performanceInformation
    77  	perfInfo.cb = uint32(unsafe.Sizeof(perfInfo))
    78  	mem, _, _ := procGetPerformanceInfo.Call(uintptr(unsafe.Pointer(&perfInfo)), uintptr(perfInfo.cb))
    79  	if mem == 0 {
    80  		return nil, windows.GetLastError()
    81  	}
    82  	tot := perfInfo.commitLimit * perfInfo.pageSize
    83  	used := perfInfo.commitTotal * perfInfo.pageSize
    84  	free := tot - used
    85  	var usedPercent float64
    86  	if tot == 0 {
    87  		usedPercent = 0
    88  	} else {
    89  		usedPercent = float64(used) / float64(tot) * 100
    90  	}
    91  	ret := &SwapMemoryStat{
    92  		Total:       tot,
    93  		Used:        used,
    94  		Free:        free,
    95  		UsedPercent: usedPercent,
    96  	}
    97  
    98  	return ret, nil
    99  }