mirror of
https://github.com/mmueller41/genode.git
synced 2026-01-21 12:32:56 +01:00
allocator_avl: use Attempt for size_at
Fixes ambiguous interpretation of returned 0. genodelabs/genode#4393
This commit is contained in:
committed by
Norman Feske
parent
5aa0fea29b
commit
db3a647c6d
@@ -45,6 +45,15 @@ namespace Genode {
|
||||
|
||||
class Genode::Allocator_avl_base : public Range_allocator
|
||||
{
|
||||
public:
|
||||
|
||||
enum class Size_at_error {
|
||||
UNKNOWN_ADDR, /* no allocation at specified address */
|
||||
MISMATCHING_ADDR, /* specified address is not the start of a block */
|
||||
};
|
||||
|
||||
using Size_at_result = Attempt<size_t, Size_at_error>;
|
||||
|
||||
private:
|
||||
|
||||
static bool _sum_in_range(addr_t addr, addr_t offset) {
|
||||
@@ -287,7 +296,7 @@ class Genode::Allocator_avl_base : public Range_allocator
|
||||
/**
|
||||
* Return size of block at specified address
|
||||
*/
|
||||
size_t size_at(void const *addr) const;
|
||||
Size_at_result size_at(void const *addr) const;
|
||||
|
||||
/**
|
||||
* Return the memory overhead per Block
|
||||
|
||||
@@ -394,15 +394,18 @@ void Allocator_avl_base::free(void *addr)
|
||||
}
|
||||
|
||||
|
||||
size_t Allocator_avl_base::size_at(void const *addr) const
|
||||
Allocator_avl_base::Size_at_result Allocator_avl_base::size_at(void const *addr) const
|
||||
{
|
||||
/* lookup corresponding block */
|
||||
Block *b = _find_by_address(reinterpret_cast<addr_t>(addr));
|
||||
|
||||
if (b && (b->addr() != (addr_t)addr))
|
||||
return 0;
|
||||
return Size_at_error::MISMATCHING_ADDR;
|
||||
|
||||
return (b && b->used()) ? b->size() : 0;
|
||||
if (b && b->used())
|
||||
return b->size();
|
||||
|
||||
return Size_at_error::UNKNOWN_ADDR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -255,14 +255,27 @@ void Heap::free(void *addr, size_t)
|
||||
/* serialize access of heap functions */
|
||||
Mutex::Guard guard(_mutex);
|
||||
|
||||
/* try to find the size in our local allocator */
|
||||
size_t const size = _alloc->size_at(addr);
|
||||
using Size_at_error = Allocator_avl::Size_at_error;
|
||||
|
||||
if (size != 0) {
|
||||
Allocator_avl::Size_at_result size_at_result = _alloc->size_at(addr);
|
||||
|
||||
if (size_at_result.ok()) {
|
||||
/* forward request to our local allocator */
|
||||
_alloc->free(addr, size);
|
||||
_quota_used -= size;
|
||||
size_at_result.with_result(
|
||||
[&] (size_t size) {
|
||||
/* forward request to our local allocator */
|
||||
_alloc->free(addr, size);
|
||||
_quota_used -= size;
|
||||
},
|
||||
[&] (Size_at_error) { });
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (size_at_result == Size_at_error::MISMATCHING_ADDR) {
|
||||
/* address was found in local allocator but is not a block start address */
|
||||
error("heap could not free memory block: given address ", addr,
|
||||
" is not a block start adress");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -278,7 +291,7 @@ void Heap::free(void *addr, size_t)
|
||||
break;
|
||||
|
||||
if (!ds) {
|
||||
warning("heap could not free memory block");
|
||||
warning("heap could not free memory block: invalid address");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user