version 1.39, 2016/01/24 21:56:43 |
version 1.40, 2016/04/12 18:07:08 |
Line 1661 arena_chunk_comp(arena_chunk_t *a, arena |
|
Line 1661 arena_chunk_comp(arena_chunk_t *a, arena |
|
assert(a != NULL); |
assert(a != NULL); |
assert(b != NULL); |
assert(b != NULL); |
|
|
|
if (a->max_frun_npages < b->max_frun_npages) |
|
return -1; |
|
if (a->max_frun_npages > b->max_frun_npages) |
|
return 1; |
|
|
if ((uintptr_t)a < (uintptr_t)b) |
if ((uintptr_t)a < (uintptr_t)b) |
return (-1); |
return (-1); |
else if (a == b) |
else if (a == b) |
Line 1912 arena_chunk_alloc(arena_t *arena) |
|
Line 1917 arena_chunk_alloc(arena_t *arena) |
|
|
|
chunk->arena = arena; |
chunk->arena = arena; |
|
|
/* LINTED */ |
|
RB_INSERT(arena_chunk_tree_s, &arena->chunks, chunk); |
|
|
|
/* |
/* |
* Claim that no pages are in use, since the header is merely |
* Claim that no pages are in use, since the header is merely |
* overhead. |
* overhead. |
Line 1934 arena_chunk_alloc(arena_t *arena) |
|
Line 1936 arena_chunk_alloc(arena_t *arena) |
|
chunk->map[chunk_npages - 1].npages = chunk_npages - |
chunk->map[chunk_npages - 1].npages = chunk_npages - |
arena_chunk_header_npages; |
arena_chunk_header_npages; |
chunk->map[chunk_npages - 1].pos = POS_FREE; |
chunk->map[chunk_npages - 1].pos = POS_FREE; |
|
|
|
RB_INSERT(arena_chunk_tree_s, &arena->chunks, chunk); |
} |
} |
|
|
return (chunk); |
return (chunk); |
Line 1970 arena_chunk_dealloc(arena_t *arena, aren |
|
Line 1974 arena_chunk_dealloc(arena_t *arena, aren |
|
static arena_run_t * |
static arena_run_t * |
arena_run_alloc(arena_t *arena, size_t size) |
arena_run_alloc(arena_t *arena, size_t size) |
{ |
{ |
arena_chunk_t *chunk; |
arena_chunk_t *chunk, *chunk_tmp; |
arena_run_t *run; |
arena_run_t *run; |
unsigned need_npages, limit_pages, compl_need_npages; |
unsigned need_npages; |
|
|
assert(size <= (chunksize - (arena_chunk_header_npages << |
assert(size <= (chunksize - (arena_chunk_header_npages << |
pagesize_2pow))); |
pagesize_2pow))); |
assert((size & pagesize_mask) == 0); |
assert((size & pagesize_mask) == 0); |
|
|
/* |
/* |
* Search through arena's chunks in address order for a free run that is |
* Search through the arena chunk tree for a large enough free run. |
* large enough. Look for the first fit. |
* Tree order ensures that any exact fit is picked immediately or |
|
* otherwise the lowest address of the next size. |
*/ |
*/ |
need_npages = (unsigned)(size >> pagesize_2pow); |
need_npages = (unsigned)(size >> pagesize_2pow); |
limit_pages = chunk_npages - arena_chunk_header_npages; |
|
compl_need_npages = limit_pages - need_npages; |
|
/* LINTED */ |
/* LINTED */ |
RB_FOREACH(chunk, arena_chunk_tree_s, &arena->chunks) { |
for (;;) { |
|
chunk_tmp = RB_ROOT(&arena->chunks); |
|
chunk = NULL; |
|
while (chunk_tmp) { |
|
if (chunk_tmp->max_frun_npages == need_npages) { |
|
chunk = chunk_tmp; |
|
break; |
|
} |
|
if (chunk_tmp->max_frun_npages < need_npages) { |
|
chunk_tmp = RB_RIGHT(chunk_tmp, link); |
|
continue; |
|
} |
|
chunk = chunk_tmp; |
|
chunk_tmp = RB_LEFT(chunk, link); |
|
} |
|
if (chunk == NULL) |
|
break; |
/* |
/* |
* Avoid searching this chunk if there are not enough |
* At this point, the chunk must have a cached run size large |
* contiguous free pages for there to possibly be a large |
* enough to fit the allocation. |
* enough free run. |
|
*/ |
*/ |
if (chunk->pages_used <= compl_need_npages && |
assert(need_npages <= chunk->max_frun_npages); |
need_npages <= chunk->max_frun_npages) { |
{ |
arena_chunk_map_t *mapelm; |
arena_chunk_map_t *mapelm; |
unsigned i; |
unsigned i; |
unsigned max_frun_npages = 0; |
unsigned max_frun_npages = 0; |
Line 2031 arena_run_alloc(arena_t *arena, size_t s |
|
Line 2049 arena_run_alloc(arena_t *arena, size_t s |
|
* chunk->min_frun_ind was already reset above (if |
* chunk->min_frun_ind was already reset above (if |
* necessary). |
* necessary). |
*/ |
*/ |
|
RB_REMOVE(arena_chunk_tree_s, &arena->chunks, chunk); |
chunk->max_frun_npages = max_frun_npages; |
chunk->max_frun_npages = max_frun_npages; |
|
RB_INSERT(arena_chunk_tree_s, &arena->chunks, chunk); |
} |
} |
} |
} |
|
|
Line 2114 arena_run_dalloc(arena_t *arena, arena_r |
|
Line 2134 arena_run_dalloc(arena_t *arena, arena_r |
|
assert(chunk->map[run_ind + run_pages - 1].pos == POS_FREE); |
assert(chunk->map[run_ind + run_pages - 1].pos == POS_FREE); |
} |
} |
|
|
if (chunk->map[run_ind].npages > chunk->max_frun_npages) |
if (chunk->map[run_ind].npages > chunk->max_frun_npages) { |
|
RB_REMOVE(arena_chunk_tree_s, &arena->chunks, chunk); |
chunk->max_frun_npages = chunk->map[run_ind].npages; |
chunk->max_frun_npages = chunk->map[run_ind].npages; |
|
RB_INSERT(arena_chunk_tree_s, &arena->chunks, chunk); |
|
} |
if (run_ind < chunk->min_frun_ind) |
if (run_ind < chunk->min_frun_ind) |
chunk->min_frun_ind = run_ind; |
chunk->min_frun_ind = run_ind; |
|
|