use MADV_DONTNEED instead of mmap fixedfor simplification and possibly better performance on Linux

This commit is contained in:
Daan 2021-10-19 13:18:54 -07:00
commit 35b928b08f

View file

@ -782,8 +782,8 @@ static bool mi_os_commitx(void* addr, size_t size, bool commit, bool conservativ
} }
#elif defined(__wasi__) #elif defined(__wasi__)
// WebAssembly guests can't control memory protection // WebAssembly guests can't control memory protection
#elif defined(MAP_FIXED) && !defined(__APPLE__) #elif 0 && defined(MAP_FIXED) && !defined(__APPLE__)
// Linux // Linux: disabled for now as mmap fixed seems much more expensive than MADV_DONTNEED (and splits VMA's?)
if (commit) { if (commit) {
// commit: just change the protection // commit: just change the protection
err = mprotect(start, csize, (PROT_READ | PROT_WRITE)); err = mprotect(start, csize, (PROT_READ | PROT_WRITE));
@ -796,7 +796,7 @@ static bool mi_os_commitx(void* addr, size_t size, bool commit, bool conservativ
if (p != start) { err = errno; } if (p != start) { err = errno; }
} }
#else #else
// macOSX and others. // Linux, macOSX and others.
if (commit) { if (commit) {
// commit: ensure we can access the area // commit: ensure we can access the area
err = mprotect(start, csize, (PROT_READ | PROT_WRITE)); err = mprotect(start, csize, (PROT_READ | PROT_WRITE));
@ -805,14 +805,12 @@ static bool mi_os_commitx(void* addr, size_t size, bool commit, bool conservativ
else { else {
#if defined(MADV_DONTNEED) #if defined(MADV_DONTNEED)
// decommit: use MADV_DONTNEED as it decreases rss immediately (unlike MADV_FREE) // decommit: use MADV_DONTNEED as it decreases rss immediately (unlike MADV_FREE)
// (on the other hand, MADV_FREE would be good enough.. it is just not reflected in the stats :-( )
err = madvise(start, csize, MADV_DONTNEED); err = madvise(start, csize, MADV_DONTNEED);
#else #else
// decommit: just disable access // decommit: just disable access
err = mprotect(start, csize, PROT_NONE); err = mprotect(start, csize, PROT_NONE);
if (err != 0) { err = errno; } if (err != 0) { err = errno; }
#if defined(MADV_FREE_REUSE)
while ((err = madvise(start, csize, MADV_FREE_REUSE)) != 0 && errno == EAGAIN) { errno = 0; }
#endif
#endif #endif
} }
#endif #endif
@ -872,17 +870,12 @@ static bool mi_os_resetx(void* addr, size_t size, bool reset, mi_stats_t* stats)
if (p != start) return false; if (p != start) return false;
#else #else
#if defined(MADV_FREE) #if defined(MADV_FREE)
#if defined(MADV_FREE_REUSABLE) static _Atomic(uintptr_t) advice = ATOMIC_VAR_INIT(MADV_FREE);
#define KK_MADV_FREE_INITIAL MADV_FREE_REUSABLE
#else
#define KK_MADV_FREE_INITIAL MADV_FREE
#endif
static _Atomic(uintptr_t) advice = ATOMIC_VAR_INIT(KK_MADV_FREE_INITIAL);
int oadvice = (int)mi_atomic_load_relaxed(&advice); int oadvice = (int)mi_atomic_load_relaxed(&advice);
int err; int err;
while ((err = madvise(start, csize, oadvice)) != 0 && errno == EAGAIN) { errno = 0; }; while ((err = madvise(start, csize, oadvice)) != 0 && errno == EAGAIN) { errno = 0; };
if (err != 0 && errno == EINVAL && oadvice == KK_MADV_FREE_INITIAL) { if (err != 0 && errno == EINVAL && oadvice == MADV_FREE) {
// if MADV_FREE/MADV_FREE_REUSABLE is not supported, fall back to MADV_DONTNEED from now on // if MADV_FREE is not supported, fall back to MADV_DONTNEED from now on
mi_atomic_store_release(&advice, (uintptr_t)MADV_DONTNEED); mi_atomic_store_release(&advice, (uintptr_t)MADV_DONTNEED);
err = madvise(start, csize, MADV_DONTNEED); err = madvise(start, csize, MADV_DONTNEED);
} }