Fix a base allocator deadlock.
Fix a base allocator deadlock due to chunk_recycle() calling back into the base allocator.
This commit is contained in:
parent
c584fc75bb
commit
34a8cf6c40
17
src/chunk.c
17
src/chunk.c
@ -30,19 +30,30 @@ size_t arena_maxclass; /* Max size class for arenas. */
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* Function prototypes for non-inline static functions. */
|
/* Function prototypes for non-inline static functions. */
|
||||||
|
|
||||||
static void *chunk_recycle(size_t size, size_t alignment, bool *zero);
|
static void *chunk_recycle(size_t size, size_t alignment, bool base,
|
||||||
|
bool *zero);
|
||||||
static void chunk_record(void *chunk, size_t size);
|
static void chunk_record(void *chunk, size_t size);
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
chunk_recycle(size_t size, size_t alignment, bool *zero)
|
chunk_recycle(size_t size, size_t alignment, bool base, bool *zero)
|
||||||
{
|
{
|
||||||
void *ret;
|
void *ret;
|
||||||
extent_node_t *node;
|
extent_node_t *node;
|
||||||
extent_node_t key;
|
extent_node_t key;
|
||||||
size_t alloc_size, leadsize, trailsize;
|
size_t alloc_size, leadsize, trailsize;
|
||||||
|
|
||||||
|
if (base) {
|
||||||
|
/*
|
||||||
|
* This function may need to call base_node_{,de}alloc(), but
|
||||||
|
* the current chunk allocation request is on behalf of the
|
||||||
|
* base allocator. Avoid deadlock (and if that weren't an
|
||||||
|
* issue, potential for infinite recursion) by returning NULL.
|
||||||
|
*/
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
alloc_size = size + alignment - chunksize;
|
alloc_size = size + alignment - chunksize;
|
||||||
/* Beware size_t wrap-around. */
|
/* Beware size_t wrap-around. */
|
||||||
if (alloc_size < size)
|
if (alloc_size < size)
|
||||||
@ -125,7 +136,7 @@ chunk_alloc(size_t size, size_t alignment, bool base, bool *zero)
|
|||||||
assert((size & chunksize_mask) == 0);
|
assert((size & chunksize_mask) == 0);
|
||||||
assert((alignment & chunksize_mask) == 0);
|
assert((alignment & chunksize_mask) == 0);
|
||||||
|
|
||||||
ret = chunk_recycle(size, alignment, zero);
|
ret = chunk_recycle(size, alignment, base, zero);
|
||||||
if (ret != NULL)
|
if (ret != NULL)
|
||||||
goto label_return;
|
goto label_return;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user