memory_windows.go raw
1 // +build windows
2
3 package memory
4
5 import (
6 "syscall"
7 "unsafe"
8 )
9
10 // omitting a few fields for brevity...
11 // https://msdn.microsoft.com/en-us/library/windows/desktop/aa366589(v=vs.85).aspx
12 type memStatusEx struct {
13 dwLength uint32
14 dwMemoryLoad uint32
15 ullTotalPhys uint64
16 ullAvailPhys uint64
17 unused [5]uint64
18 }
19
20 func sysTotalMemory() uint64 {
21 kernel32, err := syscall.LoadDLL("kernel32.dll")
22 if err != nil {
23 return 0
24 }
25 // GetPhysicallyInstalledSystemMemory is simpler, but broken on
26 // older versions of windows (and uses this under the hood anyway).
27 globalMemoryStatusEx, err := kernel32.FindProc("GlobalMemoryStatusEx")
28 if err != nil {
29 return 0
30 }
31 msx := &memStatusEx{
32 dwLength: 64,
33 }
34 r, _, _ := globalMemoryStatusEx.Call(uintptr(unsafe.Pointer(msx)))
35 if r == 0 {
36 return 0
37 }
38 return msx.ullTotalPhys
39 }
40
41 func sysFreeMemory() uint64 {
42 kernel32, err := syscall.LoadDLL("kernel32.dll")
43 if err != nil {
44 return 0
45 }
46 // GetPhysicallyInstalledSystemMemory is simpler, but broken on
47 // older versions of windows (and uses this under the hood anyway).
48 globalMemoryStatusEx, err := kernel32.FindProc("GlobalMemoryStatusEx")
49 if err != nil {
50 return 0
51 }
52 msx := &memStatusEx{
53 dwLength: 64,
54 }
55 r, _, _ := globalMemoryStatusEx.Call(uintptr(unsafe.Pointer(msx)))
56 if r == 0 {
57 return 0
58 }
59 return msx.ullAvailPhys
60 }
61