mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-07 11:27:29 +00:00
allocator_avl: avoid false dangling warnings
By first removing unused ranges, implicitly meta data allocations are freed up. This leads to more unused slab blocks and freed up meta data allocations in the avl tree. Issue #4014
This commit is contained in:
parent
1e84b46c3f
commit
18e282ab8a
@ -188,6 +188,7 @@ class Genode::Allocator_avl_base : public Range_allocator
|
||||
addr_t base, size_t size, bool used);
|
||||
|
||||
Block *_find_any_used_block(Block *sub_tree);
|
||||
Block *_find_any_unused_block(Block *sub_tree);
|
||||
|
||||
/**
|
||||
* Destroy block
|
||||
@ -215,6 +216,7 @@ class Genode::Allocator_avl_base : public Range_allocator
|
||||
* from the meta-data allocator.
|
||||
*/
|
||||
void _revert_allocations_and_ranges();
|
||||
void _revert_unused_ranges();
|
||||
|
||||
/**
|
||||
* Find block by specified address
|
||||
@ -342,6 +344,7 @@ class Genode::Allocator_avl_tpl : public Allocator_avl_base
|
||||
|
||||
~Allocator_avl_tpl()
|
||||
{
|
||||
_revert_unused_ranges();
|
||||
_metadata.free_empty_blocks();
|
||||
_revert_allocations_and_ranges();
|
||||
}
|
||||
|
@ -173,6 +173,8 @@ _ZN6Genode18Allocator_avl_base14any_block_addrEPm T
|
||||
_ZN6Genode18Allocator_avl_base15_cut_from_blockEPNS0_5BlockEmmS2_S2_ T
|
||||
_ZN6Genode18Allocator_avl_base20_find_any_used_blockEPNS0_5BlockE T
|
||||
_ZN6Genode18Allocator_avl_base21_alloc_block_metadataEv T
|
||||
_ZN6Genode18Allocator_avl_base21_revert_unused_rangesEv T
|
||||
_ZN6Genode18Allocator_avl_base22_find_any_unused_blockEPNS0_5BlockE T
|
||||
_ZN6Genode18Allocator_avl_base26_alloc_two_blocks_metadataEPPNS0_5BlockES3_ T
|
||||
_ZN6Genode18Allocator_avl_base30_revert_allocations_and_rangesEv T
|
||||
_ZN6Genode18Allocator_avl_base4freeEPv T
|
||||
|
@ -187,6 +187,21 @@ void Allocator_avl_base::_cut_from_block(Block *b, addr_t addr, size_t size,
|
||||
}
|
||||
|
||||
|
||||
void Allocator_avl_base::_revert_unused_ranges()
|
||||
{
|
||||
do {
|
||||
Block * const block = _find_any_unused_block(_addr_tree.first());
|
||||
if (!block)
|
||||
break;
|
||||
|
||||
int const error = remove_range(block->addr(), block->size());
|
||||
if (error && block == _find_any_unused_block(_addr_tree.first()))
|
||||
/* if the invocation fails, release the block to break endless loop */
|
||||
_destroy_block(block);
|
||||
} while (true);
|
||||
}
|
||||
|
||||
|
||||
void Allocator_avl_base::_revert_allocations_and_ranges()
|
||||
{
|
||||
/* revert all allocations */
|
||||
@ -390,6 +405,22 @@ size_t Allocator_avl_base::size_at(void const *addr) const
|
||||
}
|
||||
|
||||
|
||||
Allocator_avl_base::Block *Allocator_avl_base::_find_any_unused_block(Block *sub_tree)
|
||||
{
|
||||
if (!sub_tree)
|
||||
return nullptr;
|
||||
|
||||
if (!sub_tree->used())
|
||||
return sub_tree;
|
||||
|
||||
for (unsigned i = 0; i < 2; i++)
|
||||
if (Block *block = _find_any_unused_block(sub_tree->child(i)))
|
||||
return block;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
Allocator_avl_base::Block *Allocator_avl_base::_find_any_used_block(Block *sub_tree)
|
||||
{
|
||||
if (!sub_tree)
|
||||
|
Loading…
x
Reference in New Issue
Block a user