summaryrefslogtreecommitdiffstats
path: root/src/chunk.c
diff options
context:
space:
mode:
authorJason Evans <je@fb.com>2012-10-09 00:56:11 (GMT)
committerJason Evans <je@fb.com>2012-10-09 01:04:49 (GMT)
commit7de92767c20cb72c94609b9c78985526fb84a679 (patch)
tree6e6aab107b7d77d575b130b7074824da5f2df234 /src/chunk.c
parentf4c3f8545beed9f7e606cef7b1d06fae3f630269 (diff)
downloadjemalloc-7de92767c20cb72c94609b9c78985526fb84a679.zip
jemalloc-7de92767c20cb72c94609b9c78985526fb84a679.tar.gz
jemalloc-7de92767c20cb72c94609b9c78985526fb84a679.tar.bz2
Fix mlockall()/madvise() interaction.
mlockall(2) can cause purging via madvise(2) to fail. Fix purging code to check whether madvise() succeeded, and base zeroed page metadata on the result. Reported by Olivier Lecomte.
Diffstat (limited to 'src/chunk.c')
-rw-r--r--src/chunk.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/src/chunk.c b/src/chunk.c
index 6bc2454..b43f950 100644
--- a/src/chunk.c
+++ b/src/chunk.c
@@ -43,6 +43,7 @@ chunk_recycle(size_t size, size_t alignment, bool base, bool *zero)
extent_node_t *node;
extent_node_t key;
size_t alloc_size, leadsize, trailsize;
+ bool zeroed;
if (base) {
/*
@@ -107,17 +108,18 @@ chunk_recycle(size_t size, size_t alignment, bool base, bool *zero)
}
malloc_mutex_unlock(&chunks_mtx);
- if (node != NULL)
+ zeroed = false;
+ if (node != NULL) {
+ if (node->zeroed) {
+ zeroed = true;
+ *zero = true;
+ }
base_node_dealloc(node);
-#ifdef JEMALLOC_PURGE_MADVISE_DONTNEED
- /* Pages are zeroed as a side effect of pages_purge(). */
- *zero = true;
-#else
- if (*zero) {
+ }
+ if (zeroed == false && *zero) {
VALGRIND_MAKE_MEM_UNDEFINED(ret, size);
memset(ret, 0, size);
}
-#endif
return (ret);
}
@@ -191,9 +193,10 @@ label_return:
static void
chunk_record(void *chunk, size_t size)
{
+ bool unzeroed;
extent_node_t *xnode, *node, *prev, key;
- pages_purge(chunk, size);
+ unzeroed = pages_purge(chunk, size);
/*
* Allocate a node before acquiring chunks_mtx even though it might not
@@ -216,6 +219,7 @@ chunk_record(void *chunk, size_t size)
extent_tree_szad_remove(&chunks_szad, node);
node->addr = chunk;
node->size += size;
+ node->zeroed = (node->zeroed && (unzeroed == false));
extent_tree_szad_insert(&chunks_szad, node);
if (xnode != NULL)
base_node_dealloc(xnode);
@@ -234,6 +238,7 @@ chunk_record(void *chunk, size_t size)
node = xnode;
node->addr = chunk;
node->size = size;
+ node->zeroed = (unzeroed == false);
extent_tree_ad_insert(&chunks_ad, node);
extent_tree_szad_insert(&chunks_szad, node);
}
@@ -253,6 +258,7 @@ chunk_record(void *chunk, size_t size)
extent_tree_szad_remove(&chunks_szad, node);
node->addr = prev->addr;
node->size += prev->size;
+ node->zeroed = (node->zeroed && prev->zeroed);
extent_tree_szad_insert(&chunks_szad, node);
base_node_dealloc(prev);