|
55 | 55 | // the calls at compile time), try to load them at runtime. To do this we need |
56 | 56 | // first to define the corresponding function pointers. |
57 | 57 |
|
58 | | -extern "C" { |
59 | | -using OpenProcessToken_t = bool (*)(HANDLE, DWORD, PHANDLE); |
60 | | -using LookupPrivilegeValueA_t = bool (*)(LPCSTR, LPCSTR, PLUID); |
61 | | -using AdjustTokenPrivileges_t = |
62 | | - bool (*)(HANDLE, BOOL, PTOKEN_PRIVILEGES, DWORD, PTOKEN_PRIVILEGES, PDWORD); |
63 | | -} |
64 | 58 | #endif |
65 | 59 |
|
66 | 60 |
|
@@ -106,77 +100,14 @@ void std_aligned_free(void* ptr) { |
106 | 100 |
|
107 | 101 | static void* aligned_large_pages_alloc_windows([[maybe_unused]] size_t allocSize) { |
108 | 102 |
|
109 | | - #if !defined(_WIN64) |
110 | | - return nullptr; |
111 | | - #else |
112 | | - |
113 | | - HANDLE hProcessToken{}; |
114 | | - LUID luid{}; |
115 | | - void* mem = nullptr; |
116 | | - |
117 | | - const size_t largePageSize = GetLargePageMinimum(); |
118 | | - if (!largePageSize) |
119 | | - return nullptr; |
120 | | - |
121 | | - // Dynamically link OpenProcessToken, LookupPrivilegeValue and AdjustTokenPrivileges |
122 | | - |
123 | | - HMODULE hAdvapi32 = GetModuleHandle(TEXT("advapi32.dll")); |
124 | | - |
125 | | - if (!hAdvapi32) |
126 | | - hAdvapi32 = LoadLibrary(TEXT("advapi32.dll")); |
127 | | - |
128 | | - auto OpenProcessToken_f = |
129 | | - OpenProcessToken_t((void (*)()) GetProcAddress(hAdvapi32, "OpenProcessToken")); |
130 | | - if (!OpenProcessToken_f) |
131 | | - return nullptr; |
132 | | - auto LookupPrivilegeValueA_f = |
133 | | - LookupPrivilegeValueA_t((void (*)()) GetProcAddress(hAdvapi32, "LookupPrivilegeValueA")); |
134 | | - if (!LookupPrivilegeValueA_f) |
135 | | - return nullptr; |
136 | | - auto AdjustTokenPrivileges_f = |
137 | | - AdjustTokenPrivileges_t((void (*)()) GetProcAddress(hAdvapi32, "AdjustTokenPrivileges")); |
138 | | - if (!AdjustTokenPrivileges_f) |
139 | | - return nullptr; |
140 | | - |
141 | | - // We need SeLockMemoryPrivilege, so try to enable it for the process |
142 | | - |
143 | | - if (!OpenProcessToken_f( // OpenProcessToken() |
144 | | - GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hProcessToken)) |
145 | | - return nullptr; |
146 | | - |
147 | | - if (LookupPrivilegeValueA_f(nullptr, "SeLockMemoryPrivilege", &luid)) |
148 | | - { |
149 | | - TOKEN_PRIVILEGES tp{}; |
150 | | - TOKEN_PRIVILEGES prevTp{}; |
151 | | - DWORD prevTpLen = 0; |
152 | | - |
153 | | - tp.PrivilegeCount = 1; |
154 | | - tp.Privileges[0].Luid = luid; |
155 | | - tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; |
156 | | - |
157 | | - // Try to enable SeLockMemoryPrivilege. Note that even if AdjustTokenPrivileges() |
158 | | - // succeeds, we still need to query GetLastError() to ensure that the privileges |
159 | | - // were actually obtained. |
160 | | - |
161 | | - if (AdjustTokenPrivileges_f(hProcessToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), &prevTp, |
162 | | - &prevTpLen) |
163 | | - && GetLastError() == ERROR_SUCCESS) |
164 | | - { |
165 | | - // Round up size to full pages and allocate |
166 | | - allocSize = (allocSize + largePageSize - 1) & ~size_t(largePageSize - 1); |
167 | | - mem = VirtualAlloc(nullptr, allocSize, MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES, |
168 | | - PAGE_READWRITE); |
169 | | - |
170 | | - // Privilege no longer needed, restore previous state |
171 | | - AdjustTokenPrivileges_f(hProcessToken, FALSE, &prevTp, 0, nullptr, nullptr); |
172 | | - } |
173 | | - } |
174 | | - |
175 | | - CloseHandle(hProcessToken); |
176 | | - |
177 | | - return mem; |
178 | | - |
179 | | - #endif |
| 103 | + return windows_try_with_large_page_priviliges( |
| 104 | + [&](size_t largePageSize) { |
| 105 | + // Round up size to full pages and allocate |
| 106 | + allocSize = (allocSize + largePageSize - 1) & ~size_t(largePageSize - 1); |
| 107 | + return VirtualAlloc(nullptr, allocSize, MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES, |
| 108 | + PAGE_READWRITE); |
| 109 | + }, |
| 110 | + []() { return (void*) nullptr; }); |
180 | 111 | } |
181 | 112 |
|
182 | 113 | void* aligned_large_pages_alloc(size_t allocSize) { |
|
0 commit comments