mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-05-05 15:09:31 +03:00
ensure large page privileges are acquired on windows when calling reserve_huge_os_pages
This commit is contained in:
parent
6896408ab1
commit
adf8e30eda
1 changed files with 39 additions and 31 deletions
56
src/os.c
56
src/os.c
|
@ -99,35 +99,17 @@ typedef NTSTATUS (__stdcall *PNtAllocateVirtualMemoryEx)(HANDLE, PVOID*, SIZE_T*
|
||||||
static PVirtualAlloc2 pVirtualAlloc2 = NULL;
|
static PVirtualAlloc2 pVirtualAlloc2 = NULL;
|
||||||
static PNtAllocateVirtualMemoryEx pNtAllocateVirtualMemoryEx = NULL;
|
static PNtAllocateVirtualMemoryEx pNtAllocateVirtualMemoryEx = NULL;
|
||||||
|
|
||||||
void _mi_os_init(void) {
|
static bool mi_win_enable_large_os_pages()
|
||||||
// get the page size
|
{
|
||||||
SYSTEM_INFO si;
|
if (large_os_page_size > 0) return true;
|
||||||
GetSystemInfo(&si);
|
|
||||||
if (si.dwPageSize > 0) os_page_size = si.dwPageSize;
|
|
||||||
if (si.dwAllocationGranularity > 0) os_alloc_granularity = si.dwAllocationGranularity;
|
|
||||||
// get the VirtualAlloc2 function
|
|
||||||
HINSTANCE hDll;
|
|
||||||
hDll = LoadLibrary(TEXT("kernelbase.dll"));
|
|
||||||
if (hDll != NULL) {
|
|
||||||
// use VirtualAlloc2FromApp if possible as it is available to Windows store apps
|
|
||||||
pVirtualAlloc2 = (PVirtualAlloc2)GetProcAddress(hDll, "VirtualAlloc2FromApp");
|
|
||||||
if (pVirtualAlloc2==NULL) pVirtualAlloc2 = (PVirtualAlloc2)GetProcAddress(hDll, "VirtualAlloc2");
|
|
||||||
FreeLibrary(hDll);
|
|
||||||
}
|
|
||||||
hDll = LoadLibrary(TEXT("ntdll.dll"));
|
|
||||||
if (hDll != NULL) {
|
|
||||||
pNtAllocateVirtualMemoryEx = (PNtAllocateVirtualMemoryEx)GetProcAddress(hDll, "NtAllocateVirtualMemoryEx");
|
|
||||||
FreeLibrary(hDll);
|
|
||||||
}
|
|
||||||
// Try to see if large OS pages are supported
|
// Try to see if large OS pages are supported
|
||||||
unsigned long err = 0;
|
|
||||||
bool ok = mi_option_is_enabled(mi_option_large_os_pages) || mi_option_is_enabled(mi_option_reserve_huge_os_pages);
|
|
||||||
if (ok) {
|
|
||||||
// To use large pages on Windows, we first need access permission
|
// To use large pages on Windows, we first need access permission
|
||||||
// Set "Lock pages in memory" permission in the group policy editor
|
// Set "Lock pages in memory" permission in the group policy editor
|
||||||
// <https://devblogs.microsoft.com/oldnewthing/20110128-00/?p=11643>
|
// <https://devblogs.microsoft.com/oldnewthing/20110128-00/?p=11643>
|
||||||
|
unsigned long err = 0;
|
||||||
HANDLE token = NULL;
|
HANDLE token = NULL;
|
||||||
ok = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token);
|
BOOL ok = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
TOKEN_PRIVILEGES tp;
|
TOKEN_PRIVILEGES tp;
|
||||||
ok = LookupPrivilegeValue(NULL, TEXT("SeLockMemoryPrivilege"), &tp.Privileges[0].Luid);
|
ok = LookupPrivilegeValue(NULL, TEXT("SeLockMemoryPrivilege"), &tp.Privileges[0].Luid);
|
||||||
|
@ -149,6 +131,31 @@ void _mi_os_init(void) {
|
||||||
if (err == 0) err = GetLastError();
|
if (err == 0) err = GetLastError();
|
||||||
_mi_warning_message("cannot enable large OS page support, error %lu\n", err);
|
_mi_warning_message("cannot enable large OS page support, error %lu\n", err);
|
||||||
}
|
}
|
||||||
|
return (ok!=0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _mi_os_init(void) {
|
||||||
|
// get the page size
|
||||||
|
SYSTEM_INFO si;
|
||||||
|
GetSystemInfo(&si);
|
||||||
|
if (si.dwPageSize > 0) os_page_size = si.dwPageSize;
|
||||||
|
if (si.dwAllocationGranularity > 0) os_alloc_granularity = si.dwAllocationGranularity;
|
||||||
|
// get the VirtualAlloc2 function
|
||||||
|
HINSTANCE hDll;
|
||||||
|
hDll = LoadLibrary(TEXT("kernelbase.dll"));
|
||||||
|
if (hDll != NULL) {
|
||||||
|
// use VirtualAlloc2FromApp if possible as it is available to Windows store apps
|
||||||
|
pVirtualAlloc2 = (PVirtualAlloc2)GetProcAddress(hDll, "VirtualAlloc2FromApp");
|
||||||
|
if (pVirtualAlloc2==NULL) pVirtualAlloc2 = (PVirtualAlloc2)GetProcAddress(hDll, "VirtualAlloc2");
|
||||||
|
FreeLibrary(hDll);
|
||||||
|
}
|
||||||
|
hDll = LoadLibrary(TEXT("ntdll.dll"));
|
||||||
|
if (hDll != NULL) {
|
||||||
|
pNtAllocateVirtualMemoryEx = (PNtAllocateVirtualMemoryEx)GetProcAddress(hDll, "NtAllocateVirtualMemoryEx");
|
||||||
|
FreeLibrary(hDll);
|
||||||
|
}
|
||||||
|
if (mi_option_is_enabled(mi_option_large_os_pages) || mi_option_is_enabled(mi_option_reserve_huge_os_pages)) {
|
||||||
|
mi_win_enable_large_os_pages();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#elif defined(__wasi__)
|
#elif defined(__wasi__)
|
||||||
|
@ -887,6 +894,7 @@ int mi_reserve_huge_os_pages( size_t pages, double max_secs, size_t* pages_reser
|
||||||
void* p = NULL;
|
void* p = NULL;
|
||||||
bool is_large = true;
|
bool is_large = true;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
if (page==0) { mi_win_enable_large_os_pages(); }
|
||||||
p = mi_win_virtual_alloc(addr, MI_HUGE_OS_PAGE_SIZE, 0, MEM_LARGE_PAGES | MEM_COMMIT | MEM_RESERVE, true, true, &is_large);
|
p = mi_win_virtual_alloc(addr, MI_HUGE_OS_PAGE_SIZE, 0, MEM_LARGE_PAGES | MEM_COMMIT | MEM_RESERVE, true, true, &is_large);
|
||||||
#elif defined(MI_OS_USE_MMAP)
|
#elif defined(MI_OS_USE_MMAP)
|
||||||
p = mi_unix_mmap(addr, MI_HUGE_OS_PAGE_SIZE, 0, PROT_READ | PROT_WRITE, true, true, &is_large);
|
p = mi_unix_mmap(addr, MI_HUGE_OS_PAGE_SIZE, 0, PROT_READ | PROT_WRITE, true, true, &is_large);
|
||||||
|
|
Loading…
Add table
Reference in a new issue