diff --git a/CMakeLists.txt b/CMakeLists.txt index 1387e0db..0fe0b9e0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,6 +28,7 @@ option(MI_DEBUG_UBSAN "Build with undefined-behavior sanitizer (needs clan option(MI_SKIP_COLLECT_ON_EXIT "Skip collecting memory on program exit" OFF) option(MI_NO_PADDING "Force no use of padding even in DEBUG mode etc." OFF) option(MI_INSTALL_TOPLEVEL "Install directly into $CMAKE_INSTALL_PREFIX instead of PREFIX/lib/mimalloc-version" OFF) +option(MI_NO_THP "Force disable transparent huge pages support on Linux/Android process wise only" OFF) # deprecated options option(MI_CHECK_FULL "Use full internal invariant checking in DEBUG mode (deprecated, use MI_DEBUG_FULL instead)" OFF) @@ -263,6 +264,14 @@ if(MI_USE_CXX) endif() endif() +if(CMAKE_SYSTEM_NAME MATCHES "Linux|Android") + if(MI_NO_THP) + message(STATUS "Disable transparent huge pages support (MI_NO_THP=ON)") + list(APPEND mi_defines MI_NO_THP=1) + endif() +endif() + + if(CMAKE_SYSTEM_NAME MATCHES "Haiku") SET(CMAKE_INSTALL_LIBDIR ~/config/non-packaged/lib) SET(CMAKE_INSTALL_INCLUDEDIR ~/config/non-packaged/headers) diff --git a/src/prim/unix/prim.c b/src/prim/unix/prim.c index 54bf57b2..14a0dcdb 100644 --- a/src/prim/unix/prim.c +++ b/src/prim/unix/prim.c @@ -31,6 +31,7 @@ terms of the MIT license. A copy of the license can be found in the file #if defined(__linux__) #include #include + #include #if defined(__GLIBC__) #include // linux mmap flags #else @@ -125,6 +126,20 @@ static bool unix_detect_overcommit(void) { return os_overcommit; } +void unix_set_thp(void) { +#if defined(__linux__) || defined(__ANDROID__) +#if MI_NO_THP + int val; + if (prctl(PR_GET_THP_DISABLE, &val, 0, 0, 0) != 0) { + // Most likely since distros often come with always/madvise settings. + val = 1; + // Disabling only for mimalloc process rather than touching system wide settings + (void)prctl(PR_SET_THP_DISABLE, &val, 0, 0, 0); + } +#endif +#endif +} + void _mi_prim_mem_init( mi_os_mem_config_t* config ) { long psize = sysconf(_SC_PAGESIZE); if (psize > 0) { @@ -135,6 +150,7 @@ 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) + unix_set_thp(); }