diff --git a/repos/base-hw/src/core/include/page_slab.h b/repos/base-hw/src/core/include/page_slab.h index 0e0948e67..05d93ea75 100644 --- a/repos/base-hw/src/core/include/page_slab.h +++ b/repos/base-hw/src/core/include/page_slab.h @@ -188,13 +188,14 @@ class Genode::Page_slab : public Genode::Allocator */ void free(void *addr) { - for (List_element *le = _b_list.first(); - le; le = le->next()) { - if (!le->object()->free(addr)) continue; + for (List_element *le = _b_list.first(); le;) { + List_element *cur = le; + le = le->next(); + if (!cur->object()->free(addr)) continue; if (_free_slab_entries++ > (MIN_SLABS+SLABS_PER_BLOCK) - && !le->object()->ref_counter) - _free_slab_block(le->object()); + && !cur->object()->ref_counter) + _free_slab_block(cur->object()); } } diff --git a/repos/base/src/core/core_mem_alloc.cc b/repos/base/src/core/core_mem_alloc.cc index 9088fde92..70b2d6476 100644 --- a/repos/base/src/core/core_mem_alloc.cc +++ b/repos/base/src/core/core_mem_alloc.cc @@ -75,3 +75,21 @@ Core_mem_allocator::Mapped_mem_allocator::alloc_aligned(size_t size, void **out_ return Alloc_return::OK; } + + +void Core_mem_allocator::Mapped_mem_allocator::free(void *addr, size_t size) +{ + using Block = Mapped_avl_allocator::Block; + Block *b = static_cast(_virt_alloc->_find_by_address((addr_t)addr)); + if (!b) return; + + _unmap_local((addr_t)addr, b->size()); + _phys_alloc->free(b->map_addr, b->size()); + _virt_alloc->free(addr, b->size()); +} + + +void Core_mem_allocator::Mapped_mem_allocator::free(void *addr) +{ + PWRN("Not implemented!"); +} diff --git a/repos/base/src/core/include/core_mem_alloc.h b/repos/base/src/core/include/core_mem_alloc.h index 7b2b5148b..e13a138e4 100644 --- a/repos/base/src/core/include/core_mem_alloc.h +++ b/repos/base/src/core/include/core_mem_alloc.h @@ -68,12 +68,16 @@ class Genode::Core_mem_allocator : public Genode::Core_mem_translator */ struct Metadata { void * map_addr; }; + class Mapped_mem_allocator; + /** * Page-size granular allocator that links ranges to related ones. */ class Mapped_avl_allocator : public Allocator_avl_tpl { + friend class Mapped_mem_allocator; + public: /** @@ -166,7 +170,7 @@ class Genode::Core_mem_allocator : public Genode::Core_mem_translator addr_t to = ~0UL) override; Alloc_return alloc_addr(size_t size, addr_t addr) override { return Alloc_return::RANGE_CONFLICT; } - void free(void *addr) override { } + void free(void *addr) override; size_t avail() const override { return _phys_alloc->avail(); } bool valid_addr(addr_t addr) const override { return _virt_alloc->valid_addr(addr); } @@ -178,7 +182,7 @@ class Genode::Core_mem_allocator : public Genode::Core_mem_translator bool alloc(size_t size, void **out_addr) override { return alloc_aligned(size, out_addr).is_ok(); } - void free(void *addr, size_t) override { free(addr); } + void free(void *addr, size_t) override; size_t consumed() const override { return _phys_alloc->consumed(); } size_t overhead(size_t size) const override { return _phys_alloc->overhead(size); } @@ -300,7 +304,11 @@ class Genode::Core_mem_allocator : public Genode::Core_mem_translator bool alloc(size_t size, void **out_addr) override { return alloc_aligned(size, out_addr).is_ok(); } - void free(void *addr, size_t) override { free(addr); } + void free(void *addr, size_t size) override + { + Lock::Guard lock_guard(_lock); + return _mem_alloc.free(addr, size); + } size_t consumed() const override { return _phys_alloc.consumed(); } size_t overhead(size_t size) const override { return _phys_alloc.overhead(size); }