Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions windows/syscall_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -1782,12 +1782,12 @@ func LoadResourceData(module, resInfo Handle) (data []byte, err error) {
}

// PSAPI_WORKING_SET_EX_BLOCK contains extended working set information for a page.
type PSAPI_WORKING_SET_EX_BLOCK uint64
type PSAPI_WORKING_SET_EX_BLOCK uintptr

// Valid returns the validity of this page.
// If this bit is 1, the subsequent members are valid; otherwise they should be ignored.
func (b PSAPI_WORKING_SET_EX_BLOCK) Valid() bool {
return (b & 1) == 1
return (b & 1) != 0
}

// ShareCount is the number of processes that share this page. The maximum value of this member is 7.
Expand All @@ -1804,7 +1804,7 @@ func (b PSAPI_WORKING_SET_EX_BLOCK) Win32Protection() uint64 {
// Shared returns the shared status of this page.
// If this bit is 1, the page can be shared.
func (b PSAPI_WORKING_SET_EX_BLOCK) Shared() bool {
return (b & (1 << 15)) == 1
return (b & (1 << 15)) != 0
}

// Node is the NUMA node. The maximum value of this member is 63.
Expand All @@ -1815,19 +1815,19 @@ func (b PSAPI_WORKING_SET_EX_BLOCK) Node() uint64 {
// Locked returns the locked status of this page.
// If this bit is 1, the virtual page is locked in physical memory.
func (b PSAPI_WORKING_SET_EX_BLOCK) Locked() bool {
return (b & (1 << 22)) == 1
return (b & (1 << 22)) != 0
}

// LargePage returns the large page status of this page.
// If this bit is 1, the page is a large page.
func (b PSAPI_WORKING_SET_EX_BLOCK) LargePage() bool {
return (b & (1 << 23)) == 1
return (b & (1 << 23)) != 0
}

// Bad returns the bad status of this page.
// If this bit is 1, the page is has been reported as bad.
func (b PSAPI_WORKING_SET_EX_BLOCK) Bad() bool {
return (b & (1 << 31)) == 1
return (b & (1 << 31)) != 0
}

// intField extracts an integer field in the PSAPI_WORKING_SET_EX_BLOCK union.
Expand All @@ -1844,7 +1844,7 @@ func (b PSAPI_WORKING_SET_EX_BLOCK) intField(start, length int) uint64 {
// PSAPI_WORKING_SET_EX_INFORMATION contains extended working set information for a process.
type PSAPI_WORKING_SET_EX_INFORMATION struct {
// The virtual address.
VirtualAddress Pointer
VirtualAddress uintptr
// A PSAPI_WORKING_SET_EX_BLOCK union that indicates the attributes of the page at VirtualAddress.
VirtualAttributes PSAPI_WORKING_SET_EX_BLOCK
}
Expand Down
43 changes: 37 additions & 6 deletions windows/syscall_windows_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1022,21 +1022,52 @@ func TestProcessModules(t *testing.T) {
}

func TestQueryWorkingSetEx(t *testing.T) {
var a int
// alloc some shared pages
pageNum := 100
sharedMemSize := os.Getpagesize() * pageNum
handle, err := windows.CreateFileMapping(
windows.InvalidHandle,
nil,
windows.PAGE_READWRITE,
0,
uint32(sharedMemSize),
nil,
)
if err != nil {
t.Fatalf("%+v", err)
}
defer windows.CloseHandle(handle)

addr, err := windows.MapViewOfFile(handle, windows.FILE_MAP_WRITE, 0, 0, uintptr(sharedMemSize))
if err != nil {
t.Fatalf("%+v", err)
}
defer windows.UnmapViewOfFile(addr)

// accessing it to paging it in
memSlice := unsafe.Slice((*byte)(unsafe.Pointer(addr)), sharedMemSize)
for i := range memSlice {
memSlice[i] = 1
}

process := windows.CurrentProcess()
information := windows.PSAPI_WORKING_SET_EX_INFORMATION{
VirtualAddress: windows.Pointer(unsafe.Pointer(&a)),
infos := make([]windows.PSAPI_WORKING_SET_EX_INFORMATION, pageNum)
for i := 0; i < pageNum; i++ {
infos[i].VirtualAddress = addr + uintptr(i*os.Getpagesize())
}
infos := []windows.PSAPI_WORKING_SET_EX_INFORMATION{information}

cb := uint32(uintptr(len(infos)) * unsafe.Sizeof(infos[0]))
if err := windows.QueryWorkingSetEx(process, uintptr(unsafe.Pointer(&infos[0])), cb); err != nil {
t.Fatalf("%+v", err)
}

if !infos[0].VirtualAttributes.Valid() {
t.Errorf("memory location not valid")
for i := 0; i < pageNum; i++ {
if !infos[i].VirtualAttributes.Valid() {
t.Errorf("memory location not valid")
}
if !infos[i].VirtualAttributes.Shared() {
t.Errorf("memory location not shared")
}
}
}

Expand Down