-
Notifications
You must be signed in to change notification settings - Fork 1
/
Windows.jl
78 lines (63 loc) · 2.54 KB
/
Windows.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
"""
NumaAllocators.Windows
NUMA support for Windows.
See also https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualallocexnuma
"""
module Windows
using ..NumaAllocators: AbstractNumaAllocator
import ArrayAllocators: allocate, iszeroinit
using ArrayAllocators.ByteCalculators: nbytes
using ArrayAllocators.Windows: wrap_virtual, hCurrentProcess, MEM_COMMIT_RESERVE, PAGE_READWRITE, kernel32
function GetNumaProcessorNode(processor = GetCurrentProcessorNumber())
node_number = Ref{Cuchar}(0)
status = ccall((:GetNumaProcessorNode, kernel32), Cint, (Cuchar, Ptr{Cuchar}), processor, node_number)
if status == 0
error("Could not retrieve NUMA node for processor $processor.")
end
return node_number[]
end
# https://docs.microsoft.com/en-us/windows/win32/api/systemtopologyapi/nf-systemtopologyapi-getnumahighestnodenumber
function GetNumaHighestNodeNumber()
node_number = Ref{Culong}(0)
status = ccall((:GetNumaHighestNodeNumber, kernel32), Cint, (Ptr{Culong},), node_number)
if status == 0
error("Could not retrieve highest NUMA node.")
end
return node_number[]
end
function GetCurrentProcessorNumber()
return ccall((:GetCurrentProcessorNumber, "kernel32"), Cint, ())
end
#=
LPVOID VirtualAllocExNuma(
[in] HANDLE hProcess,
[in, optional] LPVOID lpAddress,
[in] SIZE_T dwSize,
[in] DWORD flAllocationType,
[in] DWORD flProtect,
[in] DWORD nndPreferred
);
=#
function VirtualAllocExNuma(hProcess, lpAddress, dwSize, flAllocationType, flProtect, nndPreferred)
ccall((:VirtualAllocExNuma, kernel32),
Ptr{Nothing}, (Ptr{Nothing}, Ptr{Nothing}, Csize_t, Culong, Culong, Culong),
hProcess, lpAddress, dwSize, flAllocationType, flProtect, nndPreferred)
end
function VirtualAllocExNuma(dest_size, numa_node)
VirtualAllocExNuma(hCurrentProcess, C_NULL, dest_size, MEM_COMMIT_RESERVE, PAGE_READWRITE, numa_node)
end
abstract type AbstractWinNumaAllocator{B} <: AbstractNumaAllocator{B} end
"""
WinNumaAllocator
Allocate memory on a specific NUMA node with `VirtualAllocExNuma`.
See also https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualallocexnuma
"""
struct WinNumaAllocator{B} <: AbstractWinNumaAllocator{B}
node::Int
end
function allocate(n::WinNumaAllocator, num_bytes)
return VirtualAllocExNuma(num_bytes, n.node)
end
Base.unsafe_wrap(::WinNumaAllocator, args...) = wrap_virtual(args...)
iszeroinit(::Type{A}) where A <: WinNumaAllocator = true
end # module Windows