diff --git a/repos/base-linux/src/core/include/platform.h b/repos/base-linux/src/core/include/platform.h index 7368b88700..8b4bf58897 100644 --- a/repos/base-linux/src/core/include/platform.h +++ b/repos/base-linux/src/core/include/platform.h @@ -75,7 +75,7 @@ class Genode::Platform : public Platform_generic bool valid_addr(addr_t ) const override { ASSERT_NEVER_CALLED; } bool alloc(size_t, void **) override { ASSERT_NEVER_CALLED; } - Alloc_return alloc_aligned(size_t, void **, int, addr_t, addr_t) override + Alloc_return alloc_aligned(size_t, void **, unsigned, Range) override { ASSERT_NEVER_CALLED; } Alloc_return alloc_addr(size_t, addr_t) override @@ -94,10 +94,9 @@ class Genode::Platform : public Platform_generic return true; } - Alloc_return alloc_aligned(size_t, void **out_addr, int, - addr_t, addr_t) override + Alloc_return alloc_aligned(size_t, void **out, unsigned, Range) override { - *out_addr = 0; + *out = 0; return Alloc_return::OK; } diff --git a/repos/base/include/base/allocator.h b/repos/base/include/base/allocator.h index b20b48f4eb..ab3e4249d7 100644 --- a/repos/base/include/base/allocator.h +++ b/repos/base/include/base/allocator.h @@ -166,6 +166,8 @@ struct Genode::Range_allocator : Allocator bool error() const { return !ok(); } }; + struct Range { addr_t start, end; }; + /** * Allocate block * @@ -174,8 +176,18 @@ struct Genode::Range_allocator : Allocator * undefined in the error case * \param align alignment of new block specified * as the power of two + * \param range address-range constraint for the allocation */ - virtual Alloc_return alloc_aligned(size_t size, void **out_addr, int align, addr_t from=0, addr_t to = ~0UL) = 0; + virtual Alloc_return alloc_aligned(size_t size, void **out_addr, + unsigned align, Range range) = 0; + + /** + * Allocate block without constraining the address range + */ + Alloc_return alloc_aligned(size_t size, void **out_addr, unsigned align) + { + return alloc_aligned(size, out_addr, align, Range { .start = 0, .end = ~0UL }); + } /** * Allocate block at address diff --git a/repos/base/include/base/allocator_avl.h b/repos/base/include/base/allocator_avl.h index a2e0c94c90..6185c9da6b 100644 --- a/repos/base/include/base/allocator_avl.h +++ b/repos/base/include/base/allocator_avl.h @@ -79,18 +79,15 @@ class Genode::Allocator_avl_base : public Range_allocator * 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 range address constraint of subblock * \param align alignment (power of two) * \return true if block fits */ - inline bool _fits(size_t n, unsigned align, - addr_t from, addr_t to) + inline bool _fits(size_t n, unsigned align, Range range) { - addr_t a = align_addr(addr() < from ? from : addr(), - align); + addr_t a = align_addr(max(addr(), range.start), align); return (a >= addr()) && _sum_in_range(a, n) && - (a - addr() + n <= avail()) && (a + n - 1 <= to); + (a - addr() + n <= avail()) && (a + n - 1 <= range.end); } /* @@ -150,8 +147,7 @@ class Genode::Allocator_avl_base : public Range_allocator /** * Find best-fitting block */ - Block *find_best_fit(size_t size, unsigned align, - addr_t from = 0UL, addr_t to = ~0UL); + Block *find_best_fit(size_t size, unsigned align, Range); /** * Find block that contains the specified address range @@ -264,13 +260,14 @@ class Genode::Allocator_avl_base : public Range_allocator int add_range(addr_t base, size_t size) override; int remove_range(addr_t base, size_t size) override; - Alloc_return alloc_aligned(size_t size, void **out_addr, int align, - addr_t from = 0, addr_t to = ~0UL) override; + Alloc_return alloc_aligned(size_t, void **, unsigned, Range) override; Alloc_return alloc_addr(size_t size, addr_t addr) override; void free(void *addr) override; size_t avail() const override; bool valid_addr(addr_t addr) const override; + using Range_allocator::alloc_aligned; /* import overloads */ + /************************* ** Allocator interface ** diff --git a/repos/base/lib/symbols/ld b/repos/base/lib/symbols/ld index 241714c659..1b85cf5650 100644 --- a/repos/base/lib/symbols/ld +++ b/repos/base/lib/symbols/ld @@ -168,7 +168,7 @@ _ZN6Genode17Timeout_schedulerD2Ev T _ZN6Genode18Allocator_avl_base10_add_blockEPNS0_5BlockEmmb T _ZN6Genode18Allocator_avl_base10alloc_addrEmm T _ZN6Genode18Allocator_avl_base12remove_rangeEmm T -_ZN6Genode18Allocator_avl_base13alloc_alignedEmPPvimm T +_ZN6Genode18Allocator_avl_base13alloc_alignedEmPPvjNS_15Range_allocator5RangeE T _ZN6Genode18Allocator_avl_base14_destroy_blockEPNS0_5BlockE T _ZN6Genode18Allocator_avl_base14any_block_addrEPm T _ZN6Genode18Allocator_avl_base15_cut_from_blockEPNS0_5BlockEmmS2_S2_ T diff --git a/repos/base/src/core/core_mem_alloc.cc b/repos/base/src/core/core_mem_alloc.cc index ec96a87f7f..95ffef1faa 100644 --- a/repos/base/src/core/core_mem_alloc.cc +++ b/repos/base/src/core/core_mem_alloc.cc @@ -34,7 +34,8 @@ void * Mapped_avl_allocator::map_addr(void * addr) Range_allocator::Alloc_return -Mapped_mem_allocator::alloc_aligned(size_t size, void **out_addr, int align, addr_t from, addr_t to) +Mapped_mem_allocator::alloc_aligned(size_t size, void **out_addr, + unsigned align, Range range) { size_t page_rounded_size = align_addr(size, get_page_size_log2()); void *phys_addr = 0; @@ -42,7 +43,7 @@ Mapped_mem_allocator::alloc_aligned(size_t size, void **out_addr, int align, add /* allocate physical pages */ Alloc_return ret1 = _phys_alloc->alloc_aligned(page_rounded_size, - &phys_addr, align, from, to); + &phys_addr, align, range); if (!ret1.ok()) { error("Could not allocate physical memory region of size ", page_rounded_size); diff --git a/repos/base/src/core/include/core_mem_alloc.h b/repos/base/src/core/include/core_mem_alloc.h index a2da39c91f..79b981f6bd 100644 --- a/repos/base/src/core/include/core_mem_alloc.h +++ b/repos/base/src/core/include/core_mem_alloc.h @@ -165,15 +165,16 @@ class Genode::Mapped_mem_allocator : public Genode::Core_mem_translator int add_range(addr_t, size_t) override { return -1; } int remove_range(addr_t, size_t) override { return -1; } - Alloc_return alloc_aligned(size_t, void **, int, addr_t from = 0, - addr_t to = ~0UL) override; + Alloc_return alloc_aligned(size_t, void **, unsigned, Range) override; Alloc_return alloc_addr(size_t, addr_t) override { return Alloc_return::RANGE_CONFLICT; } - void free(void *) override; - size_t avail() const override { return _phys_alloc->avail(); } - bool valid_addr(addr_t addr) const override { + void free(void *) override; + size_t avail() const override { return _phys_alloc->avail(); } + bool valid_addr(addr_t addr) const override { return _virt_alloc->valid_addr(addr); } + using Range_allocator::alloc_aligned; /* import overloads */ + /************************* ** Allocator interface ** @@ -280,11 +281,11 @@ class Genode::Core_mem_allocator : public Genode::Core_mem_translator Alloc_return alloc_addr(size_t, addr_t) override { return Alloc_return::RANGE_CONFLICT; } - Alloc_return alloc_aligned(size_t size, void **out_addr, int align, - addr_t from = 0, addr_t to = ~0UL) override + Alloc_return alloc_aligned(size_t size, void **out_addr, + unsigned align, Range range) override { Mutex::Guard lock_guard(_mutex); - return _mem_alloc.alloc_aligned(size, out_addr, align, from, to); + return _mem_alloc.alloc_aligned(size, out_addr, align, range); } void free(void *addr) override @@ -297,6 +298,8 @@ class Genode::Core_mem_allocator : public Genode::Core_mem_translator bool valid_addr(addr_t addr) const override { return _virt_alloc.valid_addr(addr); } + using Range_allocator::alloc_aligned; /* import overloads */ + /************************* ** Allocator interface ** diff --git a/repos/base/src/core/include/ram_dataspace_factory.h b/repos/base/src/core/include/ram_dataspace_factory.h index 13faaa1912..5a56a92c43 100644 --- a/repos/base/src/core/include/ram_dataspace_factory.h +++ b/repos/base/src/core/include/ram_dataspace_factory.h @@ -32,7 +32,8 @@ class Genode::Ram_dataspace_factory : public Ram_allocator, { public: - struct Phys_range { addr_t start, end; }; + typedef Range_allocator::Range Phys_range; + static Phys_range any_phys_range() { return { 0UL, ~0UL }; } struct Virt_range { addr_t start, size; }; diff --git a/repos/base/src/core/include/synced_range_allocator.h b/repos/base/src/core/include/synced_range_allocator.h index 5a31302239..e831a1c26c 100644 --- a/repos/base/src/core/include/synced_range_allocator.h +++ b/repos/base/src/core/include/synced_range_allocator.h @@ -93,9 +93,9 @@ class Genode::Synced_range_allocator : public Range_allocator int remove_range(addr_t base, size_t size) override { return _synced_object()->remove_range(base, size); } - Alloc_return alloc_aligned(size_t size, void **out_addr, int align, - addr_t from = 0, addr_t to = ~0UL) override { - return _synced_object()->alloc_aligned(size, out_addr, align, from, to); } + Alloc_return alloc_aligned(size_t size, void **out_addr, + unsigned align, Range range) override { + return _synced_object()->alloc_aligned(size, out_addr, align, range); } Alloc_return alloc_addr(size_t size, addr_t addr) override { return _synced_object()->alloc_addr(size, addr); } @@ -108,6 +108,8 @@ class Genode::Synced_range_allocator : public Range_allocator bool valid_addr(addr_t addr) const override { return _synced_object()->valid_addr(addr); } + + using Range_allocator::alloc_aligned; /* import overloads */ }; #endif /* _CORE__INCLUDE__SYNCED_RANGE_ALLOCATOR_H_ */ diff --git a/repos/base/src/core/ram_dataspace_factory.cc b/repos/base/src/core/ram_dataspace_factory.cc index 42cc882efc..a7d356e5ce 100644 --- a/repos/base/src/core/ram_dataspace_factory.cc +++ b/repos/base/src/core/ram_dataspace_factory.cc @@ -47,10 +47,12 @@ Ram_dataspace_factory::alloc(size_t ds_size, Cache_attribute cached) * constraints. */ if (_phys_range.start == 0 && _phys_range.end == ~0UL) { - addr_t const high_start = (sizeof(void *) == 4 ? 3UL : 4UL) << 30; + + addr_t const high_start = (sizeof(void *) == 4 ? 3UL : 4UL) << 30; + Phys_range const range { .start = high_start, .end = _phys_range.end }; + for (size_t align_log2 = log2(ds_size); align_log2 >= 12; align_log2--) { - if (_phys_alloc.alloc_aligned(ds_size, &ds_addr, align_log2, - high_start, _phys_range.end).ok()) { + if (_phys_alloc.alloc_aligned(ds_size, &ds_addr, align_log2, range).ok()) { alloc_succeeded = true; break; } @@ -61,7 +63,7 @@ Ram_dataspace_factory::alloc(size_t ds_size, Cache_attribute cached) if (!alloc_succeeded) { for (size_t align_log2 = log2(ds_size); align_log2 >= 12; align_log2--) { if (_phys_alloc.alloc_aligned(ds_size, &ds_addr, align_log2, - _phys_range.start, _phys_range.end).ok()) { + _phys_range).ok()) { alloc_succeeded = true; break; } diff --git a/repos/base/src/lib/base/allocator_avl.cc b/repos/base/src/lib/base/allocator_avl.cc index cd6807d264..4c5b411390 100644 --- a/repos/base/src/lib/base/allocator_avl.cc +++ b/repos/base/src/lib/base/allocator_avl.cc @@ -24,7 +24,7 @@ using namespace Genode; Allocator_avl_base::Block * Allocator_avl_base::Block::find_best_fit(size_t size, unsigned align, - addr_t from, addr_t to) + Range range) { /* find child with lowest max_avail value */ bool side = _child_max_avail(1) < _child_max_avail(0); @@ -35,13 +35,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, from, to) : 0; + Block *res = child(side) ? child(side)->find_best_fit(size, align, range) : 0; if (res) - return (_fits(size, align, from, to) && size < res->size()) ? this : res; + return (_fits(size, align, range) && size < res->size()) ? this : res; } - return (_fits(size, align, from, to)) ? this : 0; + return (_fits(size, align, range)) ? this : 0; } @@ -304,8 +304,8 @@ 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, - addr_t from, addr_t to) +Allocator_avl_base::alloc_aligned(size_t size, void **out_addr, unsigned align, + Range range) { Block *dst1, *dst2; if (!_alloc_two_blocks_metadata(&dst1, &dst2)) @@ -313,7 +313,7 @@ Allocator_avl_base::alloc_aligned(size_t size, void **out_addr, int align, /* find best fitting block */ Block *b = _addr_tree.first(); - b = b ? b->find_best_fit(size, align, from, to) : 0; + b = b ? b->find_best_fit(size, align, range) : 0; if (!b) { _md_alloc->free(dst1, sizeof(Block)); @@ -322,7 +322,7 @@ Allocator_avl_base::alloc_aligned(size_t size, void **out_addr, int align, } /* calculate address of new (aligned) block */ - addr_t new_addr = align_addr(b->addr() < from ? from : b->addr(), align); + addr_t new_addr = align_addr(max(b->addr(), range.start), align); /* remove new block from containing block */ _cut_from_block(b, new_addr, size, dst1, dst2); diff --git a/repos/dde_bsd/src/lib/audio/pci.cc b/repos/dde_bsd/src/lib/audio/pci.cc index 573cd968cc..a5b0ce1113 100644 --- a/repos/dde_bsd/src/lib/audio/pci.cc +++ b/repos/dde_bsd/src/lib/audio/pci.cc @@ -76,7 +76,7 @@ class Pci_driver : public Bsd::Bus_driver Pci_driver &drv) : Genode::Allocator_avl(&alloc), env(env), _drv(drv) { } - Genode::addr_t alloc(Genode::size_t size, int align) + Genode::addr_t alloc(Genode::size_t size, unsigned align) { using namespace Genode; diff --git a/repos/dde_rump/src/include/util/allocator_fap.h b/repos/dde_rump/src/include/util/allocator_fap.h index 3f75526a4a..e1c6adf5d8 100644 --- a/repos/dde_rump/src/include/util/allocator_fap.h +++ b/repos/dde_rump/src/include/util/allocator_fap.h @@ -142,7 +142,7 @@ namespace Allocator { return _range.alloc(size, out_addr); } - void *alloc_aligned(size_t size, int align = 0) + void *alloc_aligned(size_t size, unsigned align = 0) { void *addr; @@ -207,7 +207,7 @@ namespace Allocator { Fap(bool cached) : _back_allocator(cached ? CACHED : UNCACHED) { } - void *alloc(size_t size, int align = 0) + void *alloc(size_t size, unsigned align = 0) { return _back_allocator.alloc_aligned(size, align); } diff --git a/repos/os/include/os/packet_allocator.h b/repos/os/include/os/packet_allocator.h index 72edb4e300..f34aa4ddd2 100644 --- a/repos/os/include/os/packet_allocator.h +++ b/repos/os/include/os/packet_allocator.h @@ -116,8 +116,8 @@ class Genode::Packet_allocator : public Genode::Range_allocator return 0; } - Alloc_return alloc_aligned(size_t size, void **out_addr, int, addr_t, - addr_t) override + Alloc_return alloc_aligned(size_t size, void **out_addr, unsigned, + Range) override { return alloc(size, out_addr) ? Alloc_return::OK : Alloc_return::RANGE_CONFLICT; diff --git a/repos/os/include/os/packet_stream.h b/repos/os/include/os/packet_stream.h index b0550c4e45..cadc4df09b 100644 --- a/repos/os/include/os/packet_stream.h +++ b/repos/os/include/os/packet_stream.h @@ -662,6 +662,8 @@ class Genode::Packet_stream_source : private Packet_stream_base typedef typename POLICY::Ack_queue Ack_queue; typedef typename POLICY::Content_type Content_type; + enum { PACKET_ALIGNMENT = POLICY::Packet_descriptor::PACKET_ALIGNMENT }; + Genode::Range_allocator &_packet_alloc; Packet_descriptor_transmitter _submit_transmitter; @@ -765,7 +767,7 @@ class Genode::Packet_stream_source : private Packet_stream_base * \return packet descriptor with an assigned range within the * bulk buffer shared between source and sink */ - Packet_descriptor alloc_packet(Genode::size_t size, int align = POLICY::Packet_descriptor::PACKET_ALIGNMENT) + Packet_descriptor alloc_packet(Genode::size_t size, unsigned align = PACKET_ALIGNMENT) { void *base = 0; if (size && _packet_alloc.alloc_aligned(size, &base, align).error())