base: avoid deadlock in sliced_heap

It happens that ram_session and rm_session itself are invoking alloc
respectively free on the very same sliced heap inside core.

Lock only the sliced_heap list implementation and let the session locking to
the session implementation of rm_session and ram_session.

The ram_session and rm_session must take care to proper lock since inside
both implementations already the session handling thread and the service thread
are running parallel.
This commit is contained in:
Alexander Boettcher 2012-12-10 11:20:15 +01:00 committed by Norman Feske
parent 68156918ee
commit 2283536b27

View File

@ -70,9 +70,6 @@ Sliced_heap::~Sliced_heap()
bool Sliced_heap::alloc(size_t size, void **out_addr)
{
/* serialize access to block list */
Lock::Guard lock_guard(_lock);
/* allocation includes space for block meta data and is page-aligned */
size = align_addr(size + sizeof(Block), 12);
@ -91,6 +88,9 @@ bool Sliced_heap::alloc(size_t size, void **out_addr)
return false;
}
/* serialize access to block list */
Lock::Guard lock_guard(_lock);
Block *b = new(local_addr) Block(ds_cap, size);
_consumed += size;
_block_list.insert(b);
@ -101,15 +101,21 @@ bool Sliced_heap::alloc(size_t size, void **out_addr)
void Sliced_heap::free(void *addr, size_t size)
{
/* serialize access to block list */
Lock::Guard lock_guard(_lock);
Ram_dataspace_capability ds_cap;
void * local_addr;
{
/* serialize access to block list */
Lock::Guard lock_guard(_lock);
Block *b = Block::block(addr);
_block_list.remove(b);
_consumed -= b->size();
Ram_dataspace_capability ds_cap = b->ds_cap();
delete b;
_rm_session->detach(b);
Block *b = Block::block(addr);
_block_list.remove(b);
_consumed -= b->size();
ds_cap = b->ds_cap();
local_addr = b;
delete b;
}
_rm_session->detach(local_addr);
_ram_session->free(ds_cap);
}