summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVolodymyr Nikolaichuk <nikolaychuk.volodymyr@gmail.com>2021-09-15 01:17:51 +0300
committerAliaksey Kandratsenka <alkondratenko@gmail.com>2021-12-12 22:29:36 -0800
commit003775aa816cb3fe01215455825245089d423a7c (patch)
tree8c88d870be1a392538ba0f44394cc67f653c3fad
parent852fb6df031560c5e353b497222b76394190e27d (diff)
downloadgperftools-003775aa816cb3fe01215455825245089d423a7c.tar.gz
free memory with mmap(PROT_NONE, MAP_FIXED)
-rw-r--r--src/system-alloc.cc32
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
}