summaryrefslogtreecommitdiffstats
path: root/src/arena.c
diff options
context:
space:
mode:
authorJason Evans <jasone@canonware.com>2012-04-12 01:13:45 (GMT)
committerJason Evans <jasone@canonware.com>2012-04-12 01:13:45 (GMT)
commit5ff709c264e52651de25b788692c62ff1f6f389c (patch)
tree5e969c80453327e14d8491a11914a1252b666e5b /src/arena.c
parent122449b073bcbaa504c4f592ea2d733503c272d2 (diff)
downloadjemalloc-5ff709c264e52651de25b788692c62ff1f6f389c.zip
jemalloc-5ff709c264e52651de25b788692c62ff1f6f389c.tar.gz
jemalloc-5ff709c264e52651de25b788692c62ff1f6f389c.tar.bz2
Normalize aligned allocation algorithms.
Normalize arena_palloc(), chunk_alloc_mmap_slow(), and chunk_recycle_dss() to use the same algorithm for trimming over-allocation. Add the ALIGNMENT_ADDR2BASE(), ALIGNMENT_ADDR2OFFSET(), and ALIGNMENT_CEILING() macros, and use them where appropriate. Remove the run_size_p parameter from sa2u(). Fix a potential deadlock in chunk_recycle_dss() that was introduced by eae269036c9f702d9fa9be497a1a2aa1be13a29e (Add alignment support to chunk_alloc()).
Diffstat (limited to 'src/arena.c')
-rw-r--r--src/arena.c52
1 files changed, 21 insertions, 31 deletions
diff --git a/src/arena.c b/src/arena.c
index 1d4f61e..1a108db 100644
--- a/src/arena.c
+++ b/src/arena.c
@@ -1418,48 +1418,38 @@ arena_malloc_large(arena_t *arena, size_t size, bool zero)
/* Only handles large allocations that require more than page alignment. */
void *
-arena_palloc(arena_t *arena, size_t size, size_t alloc_size, size_t alignment,
- bool zero)
+arena_palloc(arena_t *arena, size_t size, size_t alignment, bool zero)
{
void *ret;
- size_t offset;
+ size_t alloc_size, leadsize, trailsize;
+ arena_run_t *run;
arena_chunk_t *chunk;
assert((size & PAGE_MASK) == 0);
alignment = PAGE_CEILING(alignment);
+ alloc_size = size + alignment - PAGE;
malloc_mutex_lock(&arena->lock);
- ret = (void *)arena_run_alloc(arena, alloc_size, true, zero);
- if (ret == NULL) {
+ run = arena_run_alloc(arena, alloc_size, true, zero);
+ if (run == NULL) {
malloc_mutex_unlock(&arena->lock);
return (NULL);
}
+ chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(run);
- chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ret);
-
- offset = (uintptr_t)ret & (alignment - 1);
- assert((offset & PAGE_MASK) == 0);
- assert(offset < alloc_size);
- if (offset == 0)
- arena_run_trim_tail(arena, chunk, ret, alloc_size, size, false);
- else {
- size_t leadsize, trailsize;
-
- leadsize = alignment - offset;
- if (leadsize > 0) {
- arena_run_trim_head(arena, chunk, ret, alloc_size,
- alloc_size - leadsize);
- ret = (void *)((uintptr_t)ret + leadsize);
- }
-
- trailsize = alloc_size - leadsize - size;
- if (trailsize != 0) {
- /* Trim trailing space. */
- assert(trailsize < alloc_size);
- arena_run_trim_tail(arena, chunk, ret, size + trailsize,
- size, false);
- }
+ leadsize = ALIGNMENT_CEILING((uintptr_t)run, alignment) -
+ (uintptr_t)run;
+ assert(alloc_size >= leadsize + size);
+ trailsize = alloc_size - leadsize - size;
+ ret = (void *)((uintptr_t)run + leadsize);
+ if (leadsize != 0) {
+ arena_run_trim_head(arena, chunk, run, alloc_size, alloc_size -
+ leadsize);
+ }
+ if (trailsize != 0) {
+ arena_run_trim_tail(arena, chunk, ret, size + trailsize, size,
+ false);
}
if (config_stats) {
@@ -1950,7 +1940,7 @@ arena_ralloc(void *ptr, size_t oldsize, size_t size, size_t extra,
* copying.
*/
if (alignment != 0) {
- size_t usize = sa2u(size + extra, alignment, NULL);
+ size_t usize = sa2u(size + extra, alignment);
if (usize == 0)
return (NULL);
ret = ipalloc(usize, alignment, zero);
@@ -1962,7 +1952,7 @@ arena_ralloc(void *ptr, size_t oldsize, size_t size, size_t extra,
return (NULL);
/* Try again, this time without extra. */
if (alignment != 0) {
- size_t usize = sa2u(size, alignment, NULL);
+ size_t usize = sa2u(size, alignment);
if (usize == 0)
return (NULL);
ret = ipalloc(usize, alignment, zero);