mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-18 23:28:29 +00:00
base: don't use the 'size' argument in 'Heap::free()'
The Heap reports that 'free()' does not rely on a valid 'size' argument, so it should not use it. Fixes #2113
This commit is contained in:
committed by
Christian Helmuth
parent
ce2139a533
commit
3a1f852318
@ -64,6 +64,8 @@ class Genode::Heap : public Allocator
|
|||||||
|
|
||||||
~Dataspace_pool();
|
~Dataspace_pool();
|
||||||
|
|
||||||
|
void remove_and_free(Dataspace &);
|
||||||
|
|
||||||
void reassign_resources(Ram_session *ram, Region_map *rm) {
|
void reassign_resources(Ram_session *ram, Region_map *rm) {
|
||||||
ram_session = ram, region_map = rm; }
|
ram_session = ram, region_map = rm; }
|
||||||
};
|
};
|
||||||
|
@ -36,33 +36,37 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Heap::Dataspace_pool::remove_and_free(Dataspace &ds)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* read dataspace capability and modify _ds_list before detaching
|
||||||
|
* possible backing store for Dataspace - we rely on LIFO list
|
||||||
|
* manipulation here!
|
||||||
|
*/
|
||||||
|
|
||||||
|
Ram_dataspace_capability ds_cap = ds.cap;
|
||||||
|
void *ds_local_addr = ds.local_addr;
|
||||||
|
|
||||||
|
remove(&ds);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call 'Dataspace' destructor to properly release the RAM dataspace
|
||||||
|
* capabilities. Note that we don't free the 'Dataspace' object at the
|
||||||
|
* local allocator because this is already done by the 'Heap'
|
||||||
|
* destructor prior executing the 'Dataspace_pool' destructor.
|
||||||
|
*/
|
||||||
|
ds.~Dataspace();
|
||||||
|
|
||||||
|
region_map->detach(ds_local_addr);
|
||||||
|
ram_session->free(ds_cap);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Heap::Dataspace_pool::~Dataspace_pool()
|
Heap::Dataspace_pool::~Dataspace_pool()
|
||||||
{
|
{
|
||||||
/* free all ram_dataspaces */
|
/* free all ram_dataspaces */
|
||||||
for (Dataspace *ds; (ds = first()); ) {
|
for (Dataspace *ds; (ds = first()); )
|
||||||
|
remove_and_free(*ds);
|
||||||
/*
|
|
||||||
* read dataspace capability and modify _ds_list before detaching
|
|
||||||
* possible backing store for Dataspace - we rely on LIFO list
|
|
||||||
* manipulation here!
|
|
||||||
*/
|
|
||||||
|
|
||||||
Ram_dataspace_capability ds_cap = ds->cap;
|
|
||||||
void *ds_local_addr = ds->local_addr;
|
|
||||||
|
|
||||||
remove(ds);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Call 'Dataspace' destructor to properly release the RAM dataspace
|
|
||||||
* capabilities. Note that we don't free the 'Dataspace' object at the
|
|
||||||
* local allocator because this is already done by the 'Heap'
|
|
||||||
* destructor prior executing the 'Dataspace_pool' destructor.
|
|
||||||
*/
|
|
||||||
ds->~Dataspace();
|
|
||||||
|
|
||||||
region_map->detach(ds_local_addr);
|
|
||||||
ram_session->free(ds_cap);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -216,37 +220,42 @@ bool Heap::alloc(size_t size, void **out_addr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Heap::free(void *addr, size_t size)
|
void Heap::free(void *addr, size_t)
|
||||||
{
|
{
|
||||||
/* serialize access of heap functions */
|
/* serialize access of heap functions */
|
||||||
Lock::Guard lock_guard(_lock);
|
Lock::Guard lock_guard(_lock);
|
||||||
|
|
||||||
if (size >= BIG_ALLOCATION_THRESHOLD) {
|
/* try to find the size in our local allocator */
|
||||||
|
size_t const size = _alloc->size_at(addr);
|
||||||
|
|
||||||
Heap::Dataspace *ds;
|
if (size != 0) {
|
||||||
|
|
||||||
for (ds = _ds_pool.first(); ds; ds = ds->next())
|
/* forward request to our local allocator */
|
||||||
if (((addr_t)addr >= (addr_t)ds->local_addr) &&
|
|
||||||
((addr_t)addr <= (addr_t)ds->local_addr + ds->size - 1))
|
|
||||||
break;
|
|
||||||
|
|
||||||
_ds_pool.remove(ds);
|
|
||||||
_ds_pool.region_map->detach(ds->local_addr);
|
|
||||||
_ds_pool.ram_session->free(ds->cap);
|
|
||||||
|
|
||||||
_quota_used -= ds->size;
|
|
||||||
|
|
||||||
destroy(*_alloc, ds);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* forward request to our local allocator
|
|
||||||
*/
|
|
||||||
_alloc->free(addr, size);
|
_alloc->free(addr, size);
|
||||||
|
|
||||||
_quota_used -= size;
|
_quota_used -= size;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Block could not be found in local allocator. So it is either a big
|
||||||
|
* allocation or invalid address.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Heap::Dataspace *ds = nullptr;
|
||||||
|
for (ds = _ds_pool.first(); ds; ds = ds->next())
|
||||||
|
if (((addr_t)addr >= (addr_t)ds->local_addr) &&
|
||||||
|
((addr_t)addr <= (addr_t)ds->local_addr + ds->size - 1))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!ds) {
|
||||||
|
warning("heap could not free memory block");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_ds_pool.remove_and_free(*ds);
|
||||||
|
_alloc->free(ds);
|
||||||
|
|
||||||
|
_quota_used -= ds->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user