diff options
author | Volodymyr Nikolaichuk <nikolaychuk.volodymyr@gmail.com> | 2021-09-15 01:17:51 +0300 |
---|---|---|
committer | Aliaksey Kandratsenka <alkondratenko@gmail.com> | 2021-12-12 22:29:36 -0800 |
commit | 003775aa816cb3fe01215455825245089d423a7c (patch) | |
tree | 8c88d870be1a392538ba0f44394cc67f653c3fad | |
parent | 852fb6df031560c5e353b497222b76394190e27d (diff) | |
download | gperftools-003775aa816cb3fe01215455825245089d423a7c.tar.gz |
free memory with mmap(PROT_NONE, MAP_FIXED)
-rw-r--r-- | src/system-alloc.cc | 32 |
1 files changed, 26 insertions, 6 deletions
diff --git a/src/system-alloc.cc b/src/system-alloc.cc index e84a5f1..439ec69 100644 --- a/src/system-alloc.cc +++ b/src/system-alloc.cc @@ -511,7 +511,7 @@ void* TCMalloc_SystemAlloc(size_t size, size_t *actual_size, } bool TCMalloc_SystemRelease(void* start, size_t length) { -#ifdef MADV_FREE +#if defined(FREE_MMAP_PROT_NONE) && defined(HAVE_MMAP) || defined(MADV_FREE) if (FLAGS_malloc_devmem_start) { // It's not safe to use MADV_FREE/MADV_DONTNEED if we've been // mapping /dev/mem for heap memory. @@ -536,20 +536,40 @@ bool TCMalloc_SystemRelease(void* start, size_t length) { ASSERT(new_end <= end); if (new_end > new_start) { - int result; + bool result, retry; do { - result = madvise(reinterpret_cast<char*>(new_start), +#if defined(FREE_MMAP_PROT_NONE) && defined(HAVE_MMAP) + // mmap PROT_NONE is similar to munmap by freeing backing pages by + // physical memory except using MAP_FIXED keeps virtual memory range + // reserved to be remapped back later + void* ret = mmap(reinterpret_cast<char*>(new_start), new_end - new_start, + PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0); + + result = ret != MAP_FAILED; +#else + int ret = madvise(reinterpret_cast<char*>(new_start), new_end - new_start, MADV_FREE); - } while (result == -1 && errno == EAGAIN); - return result != -1; - } + result = ret != -1; #endif + retry = errno == EAGAIN; + } while (!result && retry); + + return result; + } +#endif return false; } void TCMalloc_SystemCommit(void* start, size_t length) { +#if defined(FREE_MMAP_PROT_NONE) && defined(HAVE_MMAP) + // remaping as MAP_FIXED to same address assuming span size did not change + // since last TCMalloc_SystemRelease + mmap(start, length, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, + -1, 0); +#else // Nothing to do here. TCMalloc_SystemRelease does not alter pages // such that they need to be re-committed before they can be used by the // application. +#endif } |