@@ -97,6 +97,11 @@ static size_t os_alloc_granularity = 4096;
9797// if non-zero, use large page allocation
9898static size_t large_os_page_size = 0 ;
9999
100+ #if defined(MADV_HUGEPAGE )
101+ // only linux supports the THP's notion.
102+ static bool os_transparent_huge_pages = false;
103+ #endif
104+
100105// is memory overcommit allowed?
101106// set dynamically in _mi_os_init (and if true we use MAP_NORESERVE)
102107static bool os_overcommit = true;
@@ -237,13 +242,37 @@ void _mi_os_init() {
237242
238243#else // generic unix
239244
245+ static void os_detect_transparent_huge_pages (void ) {
246+ #if defined(MADV_HUGEPAGE )
247+ int fd = -1 ;
248+ size_t i ;
249+ static const char * paths [] = {
250+ "/sys/kernel/mm/transparent_hugepage/enabled" ,
251+ "/sys/kernel/mm/redhat_transparent_hugepage/enabled" ,
252+ };
253+
254+ for (i = 0 ; i < sizeof (paths ) / sizeof (paths [0 ]); i ++ ) {
255+ fd = open (paths [i ], O_RDONLY );
256+ if (fd != -1 ) break ;
257+ }
258+
259+ if (fd < 0 ) return ;
260+ char buf [128 ];
261+ ssize_t nread = read (fd , & buf , sizeof (buf ));
262+ close (fd );
263+ if (nread >= 1 ) {
264+ if (strstr (buf , "[madvise]" )) os_transparent_huge_pages = true;
265+ }
266+ #endif
267+ }
268+
240269static void os_detect_overcommit (void ) {
241270#if defined(__linux__ )
242271 int fd = open ("/proc/sys/vm/overcommit_memory" , O_RDONLY );
243- if (fd < 0 ) return ;
272+ if (fd < 0 ) return ;
244273 char buf [128 ];
245274 ssize_t nread = read (fd , & buf , sizeof (buf ));
246- close (fd );
275+ close (fd );
247276 // <https://www.kernel.org/doc/Documentation/vm/overcommit-accounting>
248277 // 0: heuristic overcommit, 1: always overcommit, 2: never overcommit (ignore NORESERVE)
249278 if (nread >= 1 ) {
@@ -269,6 +298,7 @@ void _mi_os_init() {
269298 }
270299 large_os_page_size = 2 * MI_MiB ; // TODO: can we query the OS for this?
271300 os_detect_overcommit ();
301+ os_detect_transparent_huge_pages ();
272302}
273303#endif
274304
@@ -542,7 +572,7 @@ static void* mi_unix_mmap(void* addr, size_t size, size_t try_alignment, int pro
542572 // in that case -- in particular for our large regions (in `memory.c`).
543573 // However, some systems only allow THP if called with explicit `madvise`, so
544574 // when large OS pages are enabled for mimalloc, we call `madvise` anyways.
545- if (allow_large && use_large_os_page (size , try_alignment )) {
575+ if (os_transparent_huge_pages && allow_large && use_large_os_page (size , try_alignment )) {
546576 if (madvise (p , size , MADV_HUGEPAGE ) == 0 ) {
547577 * is_large = true; // possibly
548578 };
0 commit comments