summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorjasone <jasone@FreeBSD.org>2006-01-23 03:19:01 +0000
committerjasone <jasone@FreeBSD.org>2006-01-23 03:19:01 +0000
commitcd2c530a43de8ceaaad08af5fa53f691ba5c170b (patch)
tree6f51241f5730a96d3bdaf067d70817f1cd5d6f20 /lib
parent47e7cba205f901d7b314cc0874a669e5760a0216 (diff)
downloadFreeBSD-src-cd2c530a43de8ceaaad08af5fa53f691ba5c170b.zip
FreeBSD-src-cd2c530a43de8ceaaad08af5fa53f691ba5c170b.tar.gz
In arena_chunk_reg_alloc(), try to avoid touching the last page in the
chunk during initialization, in order to avoid physically backing the page unless data are allocated there.
Diffstat (limited to 'lib')
-rw-r--r--lib/libc/stdlib/malloc.c31
1 files changed, 24 insertions, 7 deletions
diff --git a/lib/libc/stdlib/malloc.c b/lib/libc/stdlib/malloc.c
index 730f3bf..9ad7285 100644
--- a/lib/libc/stdlib/malloc.c
+++ b/lib/libc/stdlib/malloc.c
@@ -2980,7 +2980,7 @@ RETURN:
static region_t *
arena_chunk_reg_alloc(arena_t *arena, size_t size, bool fit)
{
- region_t *ret, *next;
+ region_t *ret;
chunk_node_t *chunk;
chunk = chunk_alloc(chunk_size);
@@ -3014,12 +3014,29 @@ arena_chunk_reg_alloc(arena_t *arena, size_t size, bool fit)
region_prev_free_unset(&ret->sep);
region_next_free_unset(&ret->sep);
- /* Create a separator at the end of this new region. */
- next = (region_t *)&((char *)ret)[region_next_size_get(&ret->sep)];
- region_next_size_set(&next->sep, 0);
- region_prev_free_unset(&next->sep);
- region_next_free_unset(&next->sep);
- region_next_contig_unset(&next->sep);
+ /*
+ * Avoiding the following when possible is worthwhile, because it
+ * avoids touching a page that for many applications would never be
+ * touched otherwise.
+ */
+#ifdef USE_BRK
+ if ((uintptr_t)ret >= (uintptr_t)brk_base
+ && (uintptr_t)ret < (uintptr_t)brk_max) {
+ region_t *next;
+
+ /*
+ * This may be a re-used brk chunk, so we have no guarantee
+ * that the memory is zero-filled. Therefore manually create a
+ * separator at the end of this new region (all zero bits).
+ */
+ next = (region_t *)&((char *)ret)[region_next_size_get(
+ &ret->sep)];
+ region_next_size_set(&next->sep, 0);
+ region_prev_free_unset(&next->sep);
+ region_next_free_unset(&next->sep);
+ region_next_contig_unset(&next->sep);
+ }
+#endif
if (fit)
arena_reg_fit(arena, size, ret, (arena->split == NULL));
OpenPOWER on IntegriCloud