Fix chunk_recycle()'s new_addr functionality.

Fix chunk_recycle()'s new_addr functionality to search by address rather
than just size if new_addr is specified.  The functionality added by
a95018ee81 (Attempt to expand huge
allocations in-place.) only worked if the two search orders happened to
return the same results (e.g. in simple test cases).
This commit is contained in:
Jason Evans 2015-01-30 21:22:54 -08:00
parent f8723572d8
commit 8ddc93293c

View File

@ -48,6 +48,8 @@ chunk_recycle(extent_tree_t *chunks_szad, extent_tree_t *chunks_ad,
size_t alloc_size, leadsize, trailsize; size_t alloc_size, leadsize, trailsize;
bool zeroed; bool zeroed;
assert(new_addr == NULL || alignment == chunksize);
if (base) { if (base) {
/* /*
* This function may need to call base_node_{,de}alloc(), but * This function may need to call base_node_{,de}alloc(), but
@ -65,13 +67,15 @@ chunk_recycle(extent_tree_t *chunks_szad, extent_tree_t *chunks_ad,
key.addr = new_addr; key.addr = new_addr;
key.size = alloc_size; key.size = alloc_size;
malloc_mutex_lock(&chunks_mtx); malloc_mutex_lock(&chunks_mtx);
node = extent_tree_szad_nsearch(chunks_szad, &key); node = (new_addr != NULL) ? extent_tree_ad_search(chunks_ad, &key) :
if (node == NULL || (new_addr && node->addr != new_addr)) { extent_tree_szad_nsearch(chunks_szad, &key);
if (node == NULL) {
malloc_mutex_unlock(&chunks_mtx); malloc_mutex_unlock(&chunks_mtx);
return (NULL); return (NULL);
} }
leadsize = ALIGNMENT_CEILING((uintptr_t)node->addr, alignment) - leadsize = ALIGNMENT_CEILING((uintptr_t)node->addr, alignment) -
(uintptr_t)node->addr; (uintptr_t)node->addr;
assert(new_addr == NULL || leadsize == 0);
assert(node->size >= leadsize + size); assert(node->size >= leadsize + size);
trailsize = node->size - leadsize - size; trailsize = node->size - leadsize - size;
ret = (void *)((uintptr_t)node->addr + leadsize); ret = (void *)((uintptr_t)node->addr + leadsize);