A second alloc() call is initiated with higher priority before the first alloc() call completes line 40
Failing behaviour:
prev_free will be reloaded with the new contents of _free_block, which will be 0.
line 39 will cause new_free to be loaded with *(uint32_t *)(0) (this is __stack so it is a pointer to valid memory)
atomic_cas((uintptr_t*)&_free_block, &prev_free, (uintptr_t)new_free) will install __stack in _free_block
alloc() will return NULL (this is expected behaviour)
A subsequent call to either alloc() or free() will have unintended consequences:
* A call to alloc() will return __stack
* A call to free() will hide __stack for a later alloc()
To solve this problem, alloc() should check for prev_free == NULL on each loop, rather than just on entry.
There is a race condition in PoolAllocator. The conditions for failure are:
alloc()
call is initiatedalloc()
call is initiated with higher priority before the firstalloc()
call completes line 40Failing behaviour:
prev_free
will be reloaded with the new contents of_free_block
, which will be 0.*(uint32_t *)(0)
(this is__stack
so it is a pointer to valid memory)atomic_cas((uintptr_t*)&_free_block, &prev_free, (uintptr_t)new_free)
will install__stack
in_free_block
alloc()
will returnNULL
(this is expected behaviour)alloc()
orfree()
will have unintended consequences: * A call toalloc()
will return__stack
* A call tofree()
will hide__stack
for a lateralloc()
To solve this problem,
alloc()
should check forprev_free == NULL
on each loop, rather than just on entry.