mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-18 10:46:25 +00:00
parent
57c4678aa1
commit
95ff5ba11d
@ -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; }
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user