Merge pull request #3204 from BrzVlad/fix-lock-free-alloc2
authormonojenkins <jo.shields+jenkins@xamarin.com>
Mon, 27 Jun 2016 23:08:47 +0000 (00:08 +0100)
committerGitHub <noreply@github.com>
Mon, 27 Jun 2016 23:08:47 +0000 (00:08 +0100)
[utils] Fix retiring of live block for the lock free allocator

Freeing a block descriptor (along with the block) can happen either when freeing a pointer in the block (we do this in order to prevent situations where we need to wait for the next alloc in order to free a block), either when we acquire an empty block while allocating. Either way, in order to free a block descriptor, we need to acquire it first.

When freeing a slot in a block, we are checking if the block is now empty in which case we acquire the block descriptor in order to free it (along with the block). While doing so, we were failing to account for the case where, by the time we make the block descriptor empty and the time we acquire it, another thread would try to allocate from the same descriptor, see that it's empty, free it, allocate a new descriptor (which would happen to have the same address as the retired one) to fulfill the allocation and then set it as the active descriptor for the allocator. When the first thread finally acquires the descriptor, we need to double check that it is still empty since it might be logically a different descriptor than the one we actually freed from. In the unlikely case it's not empty, we need to put it back in the allocator's data structures.


Trivial merge