summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQi Wang <interwq@gwu.edu>2017-09-26 20:45:21 (GMT)
committerQi Wang <interwq@gmail.com>2017-09-27 00:26:22 (GMT)
commit0720192a323f5dd2dd27828c6ab3061f8f039416 (patch)
treee62b0861107ecc5eb6c040fffcc11d7524ffa8b1
parent3959a9fe1973a7d7ddbbd99056c22e9b684a3275 (diff)
downloadjemalloc-0720192a323f5dd2dd27828c6ab3061f8f039416.zip
jemalloc-0720192a323f5dd2dd27828c6ab3061f8f039416.tar.gz
jemalloc-0720192a323f5dd2dd27828c6ab3061f8f039416.tar.bz2
Add runtime detection of lazy purging support.
It's possible to build with lazy purge enabled but depoly to systems without such support. In this case, rely on the boot time detection instead of keep making unnecessary madvise calls (which all returns EINVAL).
-rw-r--r--src/pages.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/src/pages.c b/src/pages.c
index 4ca3107..8469188 100644
--- a/src/pages.c
+++ b/src/pages.c
@@ -27,6 +27,9 @@ static bool os_overcommits;
bool thp_state_madvise;
+/* Runtime support for lazy purge. Irrelevant when !pages_can_purge_lazy. */
+static bool pages_can_purge_lazy_runtime = true;
+
/******************************************************************************/
/*
* Function prototypes for static functions that are referenced prior to
@@ -254,6 +257,13 @@ pages_purge_lazy(void *addr, size_t size) {
if (!pages_can_purge_lazy) {
return true;
}
+ if (!pages_can_purge_lazy_runtime) {
+ /*
+ * Built with lazy purge enabled, but detected it was not
+ * supported on the current system.
+ */
+ return true;
+ }
#ifdef _WIN32
VirtualAlloc(addr, size, MEM_RESET, PAGE_READWRITE);
@@ -491,5 +501,19 @@ pages_boot(void) {
init_thp_state();
+ /* Detect lazy purge runtime support. */
+ if (pages_can_purge_lazy) {
+ bool committed = false;
+ void *madv_free_page = os_pages_map(NULL, PAGE, PAGE, &committed);
+ if (madv_free_page == NULL) {
+ return true;
+ }
+ assert(pages_can_purge_lazy_runtime);
+ if (pages_purge_lazy(madv_free_page, PAGE)) {
+ pages_can_purge_lazy_runtime = false;
+ }
+ os_pages_unmap(madv_free_page, PAGE);
+ }
+
return false;
}