base: support range restriction in allocator

Issue #696
This commit is contained in:
Alexander Boettcher 2015-02-07 23:27:56 +01:00 committed by Christian Helmuth
parent 57c4678aa1
commit 95ff5ba11d
9 changed files with 37 additions and 25 deletions

View File

@ -46,7 +46,7 @@ class Genode::Early_translations_allocator : public Genode::Core_mem_translator
Early_translations_allocator() { }
int add_range(addr_t base, size_t size) { return -1; }
int remove_range(addr_t base, size_t size) { return -1; }
Alloc_return alloc_aligned(size_t size, void **out_addr, int align) {
Alloc_return alloc_aligned(size_t, void **, int, addr_t, addr_t) {
return Alloc_return::RANGE_CONFLICT; }
Alloc_return alloc_addr(size_t size, addr_t addr) {
return Alloc_return::RANGE_CONFLICT; }

View File

@ -47,7 +47,8 @@ namespace Genode {
return true;
}
Alloc_return alloc_aligned(size_t, void **out_addr, int)
Alloc_return alloc_aligned(size_t, void **out_addr, int,
addr_t, addr_t)
{
*out_addr = 0;
return Alloc_return::OK;

View File

@ -157,7 +157,7 @@ namespace Genode {
* \param align alignment of new block specified
* as the power of two
*/
virtual Alloc_return alloc_aligned(size_t size, void **out_addr, int align = 0) = 0;
virtual Alloc_return alloc_aligned(size_t size, void **out_addr, int align = 0, addr_t from=0, addr_t to = ~0UL) = 0;
/**
* Allocate block at address

View File

@ -54,13 +54,19 @@ namespace Genode {
* Query if block can hold a specified subblock
*
* \param n number of bytes
* \param from minimum start address of subblock
* \param to maximum end address of subblock
* \param align alignment (power of two)
* \return true if block fits
*/
inline bool _fits(size_t n, unsigned align = 1) {
return ((align_addr(addr(), align) >= addr()) &&
_sum_in_range(align_addr(addr(), align), n) &&
(align_addr(addr(), align) - addr() + n <= avail())); }
inline bool _fits(size_t n, unsigned align,
addr_t from, addr_t to)
{
addr_t a = align_addr(addr() < from ? from : addr(),
align);
return (a >= addr()) && _sum_in_range(a, n) &&
(a - addr() + n <= avail()) && (a + n - 1 <= to);
}
public:
@ -110,7 +116,8 @@ namespace Genode {
/**
* Find best-fitting block
*/
Block *find_best_fit(size_t size, unsigned align = 1);
Block *find_best_fit(size_t size, unsigned align = 1,
addr_t from = 0UL, addr_t to = ~0UL);
/**
* Find block that contains the specified address range
@ -215,7 +222,7 @@ namespace Genode {
int add_range(addr_t base, size_t size);
int remove_range(addr_t base, size_t size);
Alloc_return alloc_aligned(size_t size, void **out_addr, int align = 0);
Alloc_return alloc_aligned(size_t size, void **out_addr, int align = 0, addr_t from = 0, addr_t to = ~0UL);
Alloc_return alloc_addr(size_t size, addr_t addr);
void free(void *addr);
size_t avail();

View File

@ -220,10 +220,10 @@ namespace Genode {
return _alloc.remove_range(base, size);
}
Alloc_return alloc_aligned(size_t size, void **out_addr, int align = 0)
Alloc_return alloc_aligned(size_t size, void **out_addr, int align = 0, addr_t from = 0, addr_t to = ~0UL)
{
Lock::Guard lock_guard(*_lock);
return _alloc.alloc_aligned(size, out_addr, align);
return _alloc.alloc_aligned(size, out_addr, align, from, to);
}
Alloc_return alloc_addr(size_t size, addr_t addr)

View File

@ -28,7 +28,8 @@ inline void *operator new(size_t, void *at) { return at; }
**************************/
Allocator_avl_base::Block *
Allocator_avl_base::Block::find_best_fit(size_t size, unsigned align)
Allocator_avl_base::Block::find_best_fit(size_t size, unsigned align,
addr_t from, addr_t to)
{
/* find child with lowest max_avail value */
bool side = _child_max_avail(1) < _child_max_avail(0);
@ -39,13 +40,13 @@ Allocator_avl_base::Block::find_best_fit(size_t size, unsigned align)
if (_child_max_avail(side) < size)
continue;
Block *res = child(side) ? child(side)->find_best_fit(size, align) : 0;
Block *res = child(side) ? child(side)->find_best_fit(size, align, from, to) : 0;
if (res)
return (_fits(size, align) && size < res->size()) ? this : res;
return (_fits(size, align, from, to) && size < res->size()) ? this : res;
}
return (_fits(size, align)) ? this : 0;
return (_fits(size, align, from, to)) ? this : 0;
}
@ -247,7 +248,7 @@ int Allocator_avl_base::remove_range(addr_t base, size_t size)
}
Range_allocator::Alloc_return Allocator_avl_base::alloc_aligned(size_t size, void **out_addr, int align)
Range_allocator::Alloc_return Allocator_avl_base::alloc_aligned(size_t size, void **out_addr, int align, addr_t from, addr_t to)
{
Block *dst1, *dst2;
if (!_alloc_two_blocks_metadata(&dst1, &dst2))
@ -255,7 +256,7 @@ Range_allocator::Alloc_return Allocator_avl_base::alloc_aligned(size_t size, voi
/* find best fitting block */
Block *b = _addr_tree.first();
b = b ? b->find_best_fit(size, align) : 0;
b = b ? b->find_best_fit(size, align, from, to) : 0;
if (!b) {
_md_alloc->free(dst1, sizeof(Block));
@ -264,7 +265,7 @@ Range_allocator::Alloc_return Allocator_avl_base::alloc_aligned(size_t size, voi
}
/* calculate address of new (aligned) block */
addr_t new_addr = align_addr(b->addr(), align);
addr_t new_addr = align_addr(b->addr() < from ? from : b->addr(), align);
/* remove new block from containing block */
_cut_from_block(b, new_addr, size, dst1, dst2);

View File

@ -36,7 +36,7 @@ void * Core_mem_allocator::Mapped_avl_allocator::map_addr(void * addr)
Range_allocator::Alloc_return
Core_mem_allocator::Mapped_mem_allocator::alloc_aligned(size_t size, void **out_addr, int align)
Core_mem_allocator::Mapped_mem_allocator::alloc_aligned(size_t size, void **out_addr, int align, addr_t from, addr_t to)
{
size_t page_rounded_size = (size + get_page_size() - 1) & get_page_mask();
void *phys_addr = 0;
@ -44,7 +44,7 @@ Core_mem_allocator::Mapped_mem_allocator::alloc_aligned(size_t size, void **out_
/* allocate physical pages */
Alloc_return ret1 = _phys_alloc->alloc_aligned(page_rounded_size,
&phys_addr, align);
&phys_addr, align, from, to);
if (!ret1.is_ok()) {
PERR("Could not allocate physical memory region of size %zu\n",
page_rounded_size);

View File

@ -162,7 +162,7 @@ class Genode::Core_mem_allocator : public Genode::Core_mem_translator
int add_range(addr_t base, size_t size) { return -1; }
int remove_range(addr_t base, size_t size) { return -1; }
Alloc_return alloc_aligned(size_t size, void **out_addr,
int align = 0);
int align = 0, addr_t from = 0, addr_t to = ~0UL);
Alloc_return alloc_addr(size_t size, addr_t addr) {
return Alloc_return::RANGE_CONFLICT; }
void free(void *addr) {}
@ -274,10 +274,10 @@ class Genode::Core_mem_allocator : public Genode::Core_mem_translator
Alloc_return alloc_addr(size_t size, addr_t addr) {
return Alloc_return::RANGE_CONFLICT; }
Alloc_return alloc_aligned(size_t size, void **out_addr, int align = 0)
Alloc_return alloc_aligned(size_t size, void **out_addr, int align = 0, addr_t from = 0, addr_t to = ~0UL)
{
Lock::Guard lock_guard(_lock);
return _mem_alloc.alloc_aligned(size, out_addr, align);
return _mem_alloc.alloc_aligned(size, out_addr, align, from, to);
}
void free(void *addr)

View File

@ -90,9 +90,12 @@ class Genode::Packet_allocator : public Genode::Range_allocator
return 0;
}
Alloc_return alloc_aligned(size_t size, void **out_addr, int) {
Alloc_return alloc_aligned(size_t size, void **out_addr, int, addr_t,
addr_t)
{
return alloc(size, out_addr) ? Alloc_return::OK
: Alloc_return::RANGE_CONFLICT; }
: Alloc_return::RANGE_CONFLICT;
}
bool alloc(size_t size, void **out_addr)
{