decommit returns whether re-commit is needed

This commit is contained in:
daanx 2023-04-04 12:57:18 -07:00
parent 449aad0635
commit 5c39fe7246
6 changed files with 94 additions and 98 deletions

View file

@ -341,46 +341,37 @@ static void unix_mprotect_hint(int err) {
}
int _mi_prim_commit(void* start, size_t size, bool commit) {
/*
#if 0 && defined(MAP_FIXED) && !defined(__APPLE__)
// Linux: disabled for now as mmap fixed seems much more expensive than MADV_DONTNEED (and splits VMA's?)
if (commit) {
// commit: just change the protection
err = mprotect(start, csize, (PROT_READ | PROT_WRITE));
if (err != 0) { err = errno; }
}
else {
// decommit: use mmap with MAP_FIXED to discard the existing memory (and reduce rss)
const int fd = mi_unix_mmap_fd();
void* p = mmap(start, csize, PROT_NONE, (MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE), fd, 0);
if (p != start) { err = errno; }
}
#else
*/
int err = 0;
if (commit) {
// commit: ensure we can access the area
err = mprotect(start, size, (PROT_READ | PROT_WRITE));
if (err != 0) { err = errno; }
}
else {
#if defined(MADV_DONTNEED) && MI_DEBUG == 0 && MI_SECURE == 0
// 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 = unix_madvise(start, size, MADV_DONTNEED);
#else
// decommit: just disable access (also used in debug and secure mode to trap on illegal access)
err = mprotect(start, size, PROT_NONE);
if (err != 0) { err = errno; }
#endif
}
int _mi_prim_commit(void* start, size_t size) {
// commit: ensure we can access the area
int err = mprotect(start, size, (PROT_READ | PROT_WRITE));
if (err != 0) { err = errno; }
unix_mprotect_hint(err);
return err;
}
int _mi_prim_decommit(void* start, size_t size, bool* decommitted) {
int err = 0;
#if defined(MADV_DONTNEED) && !MI_DEBUG && !MI_SECURE
// 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 :-( )
*decommitted = false;
err = unix_madvise(start, size, MADV_DONTNEED);
#else
// decommit: just disable access (also used in debug and secure mode to trap on illegal access)
*decommitted = true; // needs recommit to reuse the memory
err = mprotect(start, size, PROT_NONE);
if (err != 0) { err = errno; }
#endif
return err;
}
int _mi_prim_reset(void* start, size_t size) {
#if defined(MADV_FREE)
// We always use MADV_DONTNEED even if it may be a bit more expensive as this
// guarantees that we see the actual rss reflected in tools like `top`.
#if 0 && defined(MADV_FREE)
static _Atomic(size_t) advice = MI_ATOMIC_VAR_INIT(MADV_FREE);
int oadvice = (int)mi_atomic_load_relaxed(&advice);
int err;

View file

@ -126,8 +126,14 @@ int _mi_prim_alloc(size_t size, size_t try_alignment, bool commit, bool allow_la
// Commit/Reset/Protect
//---------------------------------------------
int _mi_prim_commit(void* addr, size_t size, bool commit) {
MI_UNUSED(addr); MI_UNUSED(size); MI_UNUSED(commit);
int _mi_prim_commit(void* addr, size_t size) {
MI_UNUSED(addr); MI_UNUSED(size);
return 0;
}
int _mi_prim_decommit(void* addr, size_t size, bool* decommitted) {
MI_UNUSED(addr); MI_UNUSED(size);
*decommitted = false;
return 0;
}

View file

@ -257,15 +257,15 @@ int _mi_prim_alloc(size_t size, size_t try_alignment, bool commit, bool allow_la
#pragma warning(disable:6250) // suppress warning calling VirtualFree without MEM_RELEASE (for decommit)
#endif
int _mi_prim_commit(void* addr, size_t size, bool commit) {
if (commit) {
void* p = VirtualAlloc(addr, size, MEM_COMMIT, PAGE_READWRITE);
return (p == addr ? 0 : (int)GetLastError());
}
else {
BOOL ok = VirtualFree(addr, size, MEM_DECOMMIT);
return (ok ? 0 : (int)GetLastError());
}
int _mi_prim_commit(void* addr, size_t size) {
void* p = VirtualAlloc(addr, size, MEM_COMMIT, PAGE_READWRITE);
return (p == addr ? 0 : (int)GetLastError());
}
int _mi_prim_decommit(void* addr, size_t size, bool* decommitted) {
BOOL ok = VirtualFree(addr, size, MEM_DECOMMIT);
*decommitted = true; // for safetly, assume always decommitted even in the case of an error.
return (ok ? 0 : (int)GetLastError());
}
int _mi_prim_reset(void* addr, size_t size) {