mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-07-07 11:58:41 +03:00
check for remap support
This commit is contained in:
parent
10fbe6cf0f
commit
48ff5c178e
5 changed files with 77 additions and 44 deletions
|
@ -139,6 +139,9 @@ void _mi_prim_mem_init( mi_os_mem_config_t* config ) {
|
|||
config->has_overcommit = unix_detect_overcommit();
|
||||
config->must_free_whole = false; // mmap can free in parts
|
||||
config->has_virtual_reserve = true; // todo: check if this true for NetBSD? (for anonymous mmap with PROT_NONE)
|
||||
#if defined(MREMAP_MAYMOVE) && defined(MREMAP_FIXED)
|
||||
config->has_remap = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -850,7 +853,7 @@ void _mi_prim_thread_associate_default_heap(mi_heap_t* heap) {
|
|||
}
|
||||
}
|
||||
|
||||
#else
|
||||
#else // no pthreads
|
||||
|
||||
void _mi_prim_thread_init_auto_done(void) {
|
||||
// nothing
|
||||
|
@ -867,12 +870,11 @@ void _mi_prim_thread_associate_default_heap(mi_heap_t* heap) {
|
|||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Remappable memory
|
||||
//----------------------------------------------------------------
|
||||
|
||||
#if defined(MREMAP_MAYMOVE) && defined(MREMAP_FIXED)
|
||||
int _mi_prim_remap_reserve(size_t size, bool* is_pinned, void** base, void** remap_info) {
|
||||
mi_assert_internal((size%_mi_os_page_size()) == 0);
|
||||
*remap_info = NULL;
|
||||
|
@ -909,3 +911,21 @@ int _mi_prim_remap_free(void* base, size_t size, void* remap_info) {
|
|||
mi_assert_internal((size % _mi_os_page_size()) == 0);
|
||||
return _mi_prim_free(base,size);
|
||||
}
|
||||
|
||||
#else // no mremap
|
||||
int _mi_prim_remap_reserve(size_t size, bool* is_pinned, void** base, void** remap_info) {
|
||||
MI_UNUSED(size); MI_UNUSED(is_pinned); MI_UNUSED(base); MI_UNUSED(remap_info);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
int _mi_prim_remap_to(void* base, void* addr, size_t size, void* newaddr, size_t newsize, bool* extend_is_zero, void** remap_info, void** new_remap_info) {
|
||||
MI_UNUSED(base); MI_UNUSED(addr); MI_UNUSED(size); MI_UNUSED(newaddr); MI_UNUSED(newsize); MI_UNUSED(extend_is_zero); MI_UNUSED(remap_info); MI_UNUSED(new_remap_info);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
int _mi_prim_remap_free(void* base, size_t size, void* remap_info) {
|
||||
MI_UNUSED(base); MI_UNUSED(size); MI_UNUSED(remap_info);
|
||||
return EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ void _mi_prim_mem_init( mi_os_mem_config_t* config ) {
|
|||
config->has_overcommit = false;
|
||||
config->must_free_whole = true;
|
||||
config->has_virtual_reserve = false;
|
||||
config->has_remap = false;
|
||||
}
|
||||
|
||||
//---------------------------------------------
|
||||
|
|
|
@ -64,19 +64,20 @@ static PGetNumaNodeProcessorMaskEx pGetNumaNodeProcessorMaskEx = NULL;
|
|||
static PGetNumaProcessorNode pGetNumaProcessorNode = NULL;
|
||||
|
||||
//---------------------------------------------
|
||||
// Enable large page support dynamically (if possible)
|
||||
// Get lock memory permission dynamically (if possible)
|
||||
// To use large pages on Windows, or remappable memory, we first need access permission
|
||||
// Set "Lock pages in memory" permission in the group policy editor
|
||||
// <https://devblogs.microsoft.com/oldnewthing/20110128-00/?p=11643>
|
||||
//---------------------------------------------
|
||||
|
||||
static bool mi_win_enable_large_os_pages(size_t* large_page_size)
|
||||
static bool mi_win_get_lock_memory_privilege(void)
|
||||
{
|
||||
static bool large_initialized = false;
|
||||
if (large_initialized) return (_mi_os_large_page_size() > 0);
|
||||
large_initialized = true;
|
||||
static bool lock_memory_initialized = false;
|
||||
static int lock_memory_err = 0;
|
||||
if (lock_memory_initialized) return (lock_memory_err == 0);
|
||||
lock_memory_initialized = true;
|
||||
|
||||
// Try to see if large OS pages are supported
|
||||
// To use large pages on Windows, we first need access permission
|
||||
// Set "Lock pages in memory" permission in the group policy editor
|
||||
// <https://devblogs.microsoft.com/oldnewthing/20110128-00/?p=11643>
|
||||
// Try to see if we have permission can lock memory
|
||||
unsigned long err = 0;
|
||||
HANDLE token = NULL;
|
||||
BOOL ok = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token);
|
||||
|
@ -89,17 +90,15 @@ static bool mi_win_enable_large_os_pages(size_t* large_page_size)
|
|||
ok = AdjustTokenPrivileges(token, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
|
||||
if (ok) {
|
||||
err = GetLastError();
|
||||
ok = (err == ERROR_SUCCESS);
|
||||
if (ok && large_page_size != NULL) {
|
||||
*large_page_size = GetLargePageMinimum();
|
||||
}
|
||||
ok = (err == ERROR_SUCCESS);
|
||||
}
|
||||
}
|
||||
CloseHandle(token);
|
||||
}
|
||||
if (!ok) {
|
||||
if (err == 0) err = GetLastError();
|
||||
_mi_warning_message("cannot acquire the lock memory privilege (needed for large OS page or remap support), error %lu\n", err);
|
||||
if (err == 0) { err = GetLastError(); }
|
||||
lock_memory_err = (int)err;
|
||||
_mi_warning_message("cannot acquire the lock memory privilege (needed for large OS page or remap support), error %lu (0x%04lx)\n", err);
|
||||
}
|
||||
return (ok!=0);
|
||||
}
|
||||
|
@ -143,9 +142,12 @@ void _mi_prim_mem_init( mi_os_mem_config_t* config )
|
|||
pGetNumaProcessorNode = (PGetNumaProcessorNode)(void (*)(void))GetProcAddress(hDll, "GetNumaProcessorNode");
|
||||
FreeLibrary(hDll);
|
||||
}
|
||||
if (mi_option_is_enabled(mi_option_allow_large_os_pages) || mi_option_is_enabled(mi_option_reserve_huge_os_pages)) {
|
||||
mi_win_enable_large_os_pages(&config->large_page_size);
|
||||
}
|
||||
// if (mi_option_is_enabled(mi_option_allow_large_os_pages) || mi_option_is_enabled(mi_option_reserve_huge_os_pages)) {
|
||||
if (mi_win_get_lock_memory_privilege()) {
|
||||
config->large_page_size = GetLargePageMinimum();
|
||||
config->has_remap = true;
|
||||
};
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
@ -308,7 +310,7 @@ static void* _mi_prim_alloc_huge_os_pagesx(void* hint_addr, size_t size, int num
|
|||
{
|
||||
const DWORD flags = MEM_LARGE_PAGES | MEM_COMMIT | MEM_RESERVE;
|
||||
|
||||
if (!mi_win_enable_large_os_pages(NULL)) return NULL;
|
||||
if (!mi_win_get_lock_memory_privilege()) return NULL;
|
||||
|
||||
MI_MEM_EXTENDED_PARAMETER params[3] = { {{0,0},{0}},{{0,0},{0}},{{0,0},{0}} };
|
||||
// on modern Windows try use NtAllocateVirtualMemoryEx for 1GiB huge pages
|
||||
|
@ -733,7 +735,7 @@ static int mi_win_remap_virtual_pages(mi_win_remap_info_t* rinfo, void* oldaddr,
|
|||
|
||||
// Reserve a virtual address range to be mapped to physical memory later
|
||||
int _mi_prim_remap_reserve(size_t size, bool* is_pinned, void** base, void** remap_info) {
|
||||
if (!mi_win_enable_large_os_pages(NULL)) return EINVAL;
|
||||
if (!mi_win_get_lock_memory_privilege()) return EINVAL;
|
||||
mi_assert_internal((size % _mi_os_page_size()) == 0);
|
||||
size = _mi_align_up(size, _mi_os_page_size());
|
||||
mi_win_remap_info_t** prinfo = (mi_win_remap_info_t**)remap_info;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue