diff options
author | jasone <jasone@FreeBSD.org> | 2006-01-23 03:19:01 +0000 |
---|---|---|
committer | jasone <jasone@FreeBSD.org> | 2006-01-23 03:19:01 +0000 |
commit | cd2c530a43de8ceaaad08af5fa53f691ba5c170b (patch) | |
tree | 6f51241f5730a96d3bdaf067d70817f1cd5d6f20 /lib | |
parent | 47e7cba205f901d7b314cc0874a669e5760a0216 (diff) | |
download | FreeBSD-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.c | 31 |
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)); |