@@ -97,6 +97,11 @@ static size_t os_alloc_granularity = 4096;
97
97
// if non-zero, use large page allocation
98
98
static size_t large_os_page_size = 0 ;
99
99
100
+ #if defined(MADV_HUGEPAGE )
101
+ // only linux supports the THP's notion.
102
+ static bool os_transparent_huge_pages = false;
103
+ #endif
104
+
100
105
// is memory overcommit allowed?
101
106
// set dynamically in _mi_os_init (and if true we use MAP_NORESERVE)
102
107
static bool os_overcommit = true;
@@ -237,13 +242,37 @@ void _mi_os_init() {
237
242
238
243
#else // generic unix
239
244
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 > 0 ) 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
+
240
269
static void os_detect_overcommit (void ) {
241
270
#if defined(__linux__ )
242
271
int fd = open ("/proc/sys/vm/overcommit_memory" , O_RDONLY );
243
- if (fd < 0 ) return ;
272
+ if (fd < 0 ) return ;
244
273
char buf [128 ];
245
274
ssize_t nread = read (fd , & buf , sizeof (buf ));
246
- close (fd );
275
+ close (fd );
247
276
// <https://www.kernel.org/doc/Documentation/vm/overcommit-accounting>
248
277
// 0: heuristic overcommit, 1: always overcommit, 2: never overcommit (ignore NORESERVE)
249
278
if (nread >= 1 ) {
@@ -269,6 +298,7 @@ void _mi_os_init() {
269
298
}
270
299
large_os_page_size = 2 * MI_MiB ; // TODO: can we query the OS for this?
271
300
os_detect_overcommit ();
301
+ os_detect_transparent_huge_pages ();
272
302
}
273
303
#endif
274
304
@@ -542,7 +572,7 @@ static void* mi_unix_mmap(void* addr, size_t size, size_t try_alignment, int pro
542
572
// in that case -- in particular for our large regions (in `memory.c`).
543
573
// However, some systems only allow THP if called with explicit `madvise`, so
544
574
// 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 )) {
546
576
if (madvise (p , size , MADV_HUGEPAGE ) == 0 ) {
547
577
* is_large = true; // possibly
548
578
};
0 commit comments