diff --git a/base-codezero/src/core/include/platform.h b/base-codezero/src/core/include/platform.h index 6e76b498e..8489c2295 100644 --- a/base-codezero/src/core/include/platform.h +++ b/base-codezero/src/core/include/platform.h @@ -60,7 +60,7 @@ namespace Genode { Range_allocator *io_port_alloc() { return &_io_port_alloc; } Range_allocator *irq_alloc() { return &_irq_alloc; } Range_allocator *region_alloc() { return _core_mem_alloc.virt_alloc(); } - Allocator *core_mem_alloc() { return &_core_mem_alloc; } + Range_allocator *core_mem_alloc() { return &_core_mem_alloc; } addr_t vm_start() const { return _vm_base; } size_t vm_size() const { return _vm_size; } Rom_fs *rom_fs() { return &_rom_fs; } diff --git a/base-codezero/src/core/include/util.h b/base-codezero/src/core/include/util.h index 0355ebf76..7992152ad 100644 --- a/base-codezero/src/core/include/util.h +++ b/base-codezero/src/core/include/util.h @@ -23,9 +23,9 @@ namespace Genode { - inline size_t get_page_size_log2() { return 12; } - inline size_t get_page_size() { return 1 << get_page_size_log2(); } - inline addr_t get_page_mask() { return ~(get_page_size() - 1); } + constexpr size_t get_page_size_log2() { return 12; } + constexpr size_t get_page_size() { return 1 << get_page_size_log2(); } + constexpr addr_t get_page_mask() { return ~(get_page_size() - 1); } inline addr_t trunc_page(addr_t addr) { return addr & get_page_mask(); } inline addr_t round_page(addr_t addr) { return trunc_page(addr + get_page_size() - 1); } diff --git a/base-codezero/src/core/platform.cc b/base-codezero/src/core/platform.cc index 2bbebba76..2a9a39e86 100644 --- a/base-codezero/src/core/platform.cc +++ b/base-codezero/src/core/platform.cc @@ -126,9 +126,15 @@ int Platform::_init_rom_fs() ** Support for core memory management ** ****************************************/ -bool Core_mem_allocator::Mapped_mem_allocator::_map_local(addr_t virt_addr, addr_t phys_addr, unsigned size_log2) +bool Core_mem_allocator::_map_local(addr_t virt_addr, addr_t phys_addr, unsigned size) { - return map_local(phys_addr, virt_addr, 1 << (size_log2 - get_page_size_log2())); + return map_local(phys_addr, virt_addr, size / get_page_size()); +} + + +bool Core_mem_allocator::_unmap_local(addr_t virt_addr, unsigned size) +{ + return unmap_local(virt_addr, size / get_page_size()); } diff --git a/base-fiasco/src/core/include/platform.h b/base-fiasco/src/core/include/platform.h index 0fa5641ef..5f7796b5a 100644 --- a/base-fiasco/src/core/include/platform.h +++ b/base-fiasco/src/core/include/platform.h @@ -141,7 +141,7 @@ namespace Genode { ** Generic platform interface ** ********************************/ - Allocator *core_mem_alloc() { return &_ram_alloc; } + Range_allocator *core_mem_alloc() { return &_ram_alloc; } Range_allocator *ram_alloc() { return &_ram_alloc; } Range_allocator *io_mem_alloc() { return &_io_mem_alloc; } Range_allocator *io_port_alloc() { return &_io_port_alloc; } diff --git a/base-fiasco/src/core/include/util.h b/base-fiasco/src/core/include/util.h index 3261428a6..28bebf09e 100644 --- a/base-fiasco/src/core/include/util.h +++ b/base-fiasco/src/core/include/util.h @@ -92,13 +92,10 @@ namespace Genode { return l4_round_superpage(addr); } - inline size_t get_page_size() { return L4_PAGESIZE; } - - inline size_t get_page_size_log2() { return L4_LOG2_PAGESIZE; } - - inline size_t get_super_page_size() { return L4_SUPERPAGESIZE; } - - inline size_t get_super_page_size_log2() { return L4_LOG2_SUPERPAGESIZE; } + constexpr size_t get_page_size() { return L4_PAGESIZE; } + constexpr size_t get_page_size_log2() { return L4_LOG2_PAGESIZE; } + constexpr size_t get_super_page_size() { return L4_SUPERPAGESIZE; } + constexpr size_t get_super_page_size_log2() { return L4_LOG2_SUPERPAGESIZE; } inline void print_page_fault(const char *msg, addr_t pf_addr, addr_t pf_ip, Rm_session::Fault_type pf_type, diff --git a/base-foc/src/core/include/platform.h b/base-foc/src/core/include/platform.h index 516e664c6..41b582f39 100644 --- a/base-foc/src/core/include/platform.h +++ b/base-foc/src/core/include/platform.h @@ -149,7 +149,7 @@ namespace Genode { ** Generic platform interface ** ********************************/ - Allocator *core_mem_alloc() { return &_ram_alloc; } + Range_allocator *core_mem_alloc() { return &_ram_alloc; } Range_allocator *ram_alloc() { return &_ram_alloc; } Range_allocator *io_mem_alloc() { return &_io_mem_alloc; } Range_allocator *io_port_alloc() { return &_io_port_alloc; } diff --git a/base-foc/src/core/include/util.h b/base-foc/src/core/include/util.h index 29549fa49..45388fd21 100644 --- a/base-foc/src/core/include/util.h +++ b/base-foc/src/core/include/util.h @@ -91,13 +91,10 @@ namespace Genode { return (addr + L4_SUPERPAGESIZE-1) & L4_SUPERPAGEMASK; } - inline size_t get_page_size() { return L4_PAGESIZE; } - - inline size_t get_page_size_log2() { return L4_LOG2_PAGESIZE; } - - inline size_t get_super_page_size() { return L4_SUPERPAGESIZE; } - - inline size_t get_super_page_size_log2() { return L4_LOG2_SUPERPAGESIZE; } + constexpr size_t get_page_size() { return L4_PAGESIZE; } + constexpr size_t get_page_size_log2() { return L4_LOG2_PAGESIZE; } + constexpr size_t get_super_page_size() { return L4_SUPERPAGESIZE; } + constexpr size_t get_super_page_size_log2() { return L4_LOG2_SUPERPAGESIZE; } inline void print_page_fault(const char *msg, addr_t pf_addr, addr_t pf_ip, Rm_session::Fault_type pf_type, diff --git a/base-host/src/core/include/platform.h b/base-host/src/core/include/platform.h index 2f6ef2a58..8925bae46 100644 --- a/base-host/src/core/include/platform.h +++ b/base-host/src/core/include/platform.h @@ -38,7 +38,7 @@ namespace Genode { Range_allocator *io_port_alloc() { return 0; } Range_allocator *irq_alloc() { return 0; } Range_allocator *region_alloc() { return 0; } - Allocator *core_mem_alloc() { return 0; } + Range_allocator *core_mem_alloc() { return 0; } addr_t vm_start() const { return 0; } size_t vm_size() const { return 0; } Rom_fs *rom_fs() { return 0; } diff --git a/base-host/src/core/include/util.h b/base-host/src/core/include/util.h index 1f7992e4c..2bc82addf 100644 --- a/base-host/src/core/include/util.h +++ b/base-host/src/core/include/util.h @@ -20,9 +20,9 @@ namespace Genode { - inline size_t get_page_size_log2() { return 12; } - inline size_t get_page_size() { return 1 << get_page_size_log2(); } - inline addr_t get_page_mask() { return ~(get_page_size() - 1); } + constexpr size_t get_page_size_log2() { return 12; } + constexpr size_t get_page_size() { return 1 << get_page_size_log2(); } + constexpr addr_t get_page_mask() { return ~(get_page_size() - 1); } inline addr_t trunc_page(addr_t addr) { return addr & get_page_mask(); } inline addr_t round_page(addr_t addr) { return trunc_page(addr + get_page_size() - 1); } diff --git a/base-hw/src/core/include/util.h b/base-hw/src/core/include/util.h index ec6f83f8f..6f7af050f 100644 --- a/base-hw/src/core/include/util.h +++ b/base-hw/src/core/include/util.h @@ -38,19 +38,19 @@ namespace Genode /** * Get the the minimal supported page-size log 2 */ - inline size_t get_page_size_log2() { return MIN_PAGE_SIZE_LOG2; } + constexpr size_t get_page_size_log2() { return MIN_PAGE_SIZE_LOG2; } /** * Get the the minimal supported page-size */ - inline size_t get_page_size() { return 1 << get_page_size_log2(); } + constexpr size_t get_page_size() { return 1 << get_page_size_log2(); } /** * Get the base mask for the minimal supported page-size */ - inline addr_t get_page_mask() { return ~(get_page_size() - 1); } + constexpr addr_t get_page_mask() { return ~(get_page_size() - 1); } /** diff --git a/base-linux/src/core/include/util.h b/base-linux/src/core/include/util.h new file mode 100644 index 000000000..2ff35dc9c --- /dev/null +++ b/base-linux/src/core/include/util.h @@ -0,0 +1,22 @@ +/* + * \brief Core-internal utilities + * \author Stefan Kalkowski + * \date 2014-03-10 + */ + +/* + * Copyright (C) 2014 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _CORE__INCLUDE__UTIL_H_ +#define _CORE__INCLUDE__UTIL_H_ + +namespace Genode { + constexpr size_t get_page_size_log2() { return 12; } + constexpr size_t get_page_size() { return 1 << get_page_size_log2(); } +} + +#endif /* _CORE__INCLUDE__UTIL_H_ */ diff --git a/base-nova/src/core/include/platform.h b/base-nova/src/core/include/platform.h index 676b45064..7d67a905b 100644 --- a/base-nova/src/core/include/platform.h +++ b/base-nova/src/core/include/platform.h @@ -67,7 +67,7 @@ namespace Genode { Range_allocator *io_port_alloc() { return &_io_port_alloc; } Range_allocator *irq_alloc() { return &_irq_alloc; } Range_allocator *region_alloc() { return _core_mem_alloc.virt_alloc(); } - Allocator *core_mem_alloc() { return &_core_mem_alloc; } + Range_allocator *core_mem_alloc() { return &_core_mem_alloc; } addr_t vm_start() const { return _vm_base; } size_t vm_size() const { return _vm_size; } Rom_fs *rom_fs() { return &_rom_fs; } diff --git a/base-nova/src/core/include/util.h b/base-nova/src/core/include/util.h index b4bee00fc..a353452d6 100644 --- a/base-nova/src/core/include/util.h +++ b/base-nova/src/core/include/util.h @@ -20,11 +20,11 @@ namespace Genode { - inline size_t get_page_size_log2() { return 12; } - inline size_t get_page_size() { return 1 << get_page_size_log2(); } - inline addr_t get_page_mask() { return ~(get_page_size() - 1); } - inline size_t get_super_page_size_log2() { return 22; } - inline size_t get_super_page_size() { return 1 << get_super_page_size_log2(); } + constexpr size_t get_page_size_log2() { return 12; } + constexpr size_t get_page_size() { return 1 << get_page_size_log2(); } + constexpr addr_t get_page_mask() { return ~(get_page_size() - 1); } + constexpr size_t get_super_page_size_log2() { return 22; } + constexpr size_t get_super_page_size() { return 1 << get_super_page_size_log2(); } inline addr_t trunc_page(addr_t addr) { return addr & get_page_mask(); } inline addr_t round_page(addr_t addr) { return trunc_page(addr + get_page_size() - 1); } diff --git a/base-nova/src/core/platform.cc b/base-nova/src/core/platform.cc index 0f18a7ed3..91d38f0f3 100644 --- a/base-nova/src/core/platform.cc +++ b/base-nova/src/core/platform.cc @@ -321,12 +321,23 @@ Platform::Platform() : map_local_phys_to_virt(__main_thread_utcb, Mem_crd(BDA_PHY, 0, Rights(true, false, false)), Mem_crd(BDA_VIRT, 0, Rights(true, false, false))); - + /* * Now that we can access the I/O ports for comport 0, printf works... */ + /* + * remap main utcb to default utcb address + * we do this that early, because Core_mem_allocator uses + * the main_thread_utcb very early to establish mappings + */ + if (map_local(__main_thread_utcb, (addr_t)__main_thread_utcb, + (addr_t)main_thread_utcb(), 1, Rights(true, true, false))) { + PERR("could not remap utcb of main thread"); + nova_die(); + } + /* sanity checks */ if (hip->sel_exc + 3 > NUM_INITIAL_PT_RESERVED) { printf("configuration error\n"); @@ -616,13 +627,6 @@ Platform::Platform() : _irq_alloc.add_range(0, hip->sel_gsi - 1); _gsi_base_sel = (hip->mem_desc_offset - hip->cpu_desc_offset) / hip->cpu_desc_size; - /* remap main utcb to default utcb address */ - if (map_local(__main_thread_utcb, (addr_t)__main_thread_utcb, - (addr_t)main_thread_utcb(), 1, Rights(true, true, false))) { - PERR("could not remap utcb of main thread"); - nova_die(); - } - if (verbose_boot_info) { printf(":virt_alloc: "); _core_mem_alloc.virt_alloc()->raw()->dump_addr_tree(); printf(":phys_alloc: "); _core_mem_alloc.phys_alloc()->raw()->dump_addr_tree(); @@ -661,17 +665,24 @@ Platform::Platform() : ** Support for core memory management ** ****************************************/ -bool Core_mem_allocator::Mapped_mem_allocator::_map_local(addr_t virt_addr, - addr_t phys_addr, - unsigned size_log2) +bool Core_mem_allocator::_map_local(addr_t virt_addr, addr_t phys_addr, + unsigned size) { map_local((Utcb *)Thread_base::myself()->utcb(), phys_addr, - virt_addr, 1 << (size_log2 - get_page_size_log2()), + virt_addr, size / get_page_size(), Rights(true, true, true), true); return true; } +bool Core_mem_allocator::_unmap_local(addr_t virt_addr, unsigned size) +{ + unmap_local((Utcb *)Thread_base::myself()->utcb(), + virt_addr, size / get_page_size()); + return true; +} + + /******************************** ** Generic platform interface ** ********************************/ diff --git a/base-okl4/src/core/include/platform.h b/base-okl4/src/core/include/platform.h index f3f1409be..9a6a5c255 100644 --- a/base-okl4/src/core/include/platform.h +++ b/base-okl4/src/core/include/platform.h @@ -35,15 +35,19 @@ namespace Genode { { private: - typedef Core_mem_allocator::Phys_allocator Phys_allocator; + using Phys_allocator = Core_mem_allocator::Phys_allocator; + using Rom_slab = Tslab; + using Thread_slab = Tslab; - Platform_pd *_core_pd; /* core protection domain */ - Platform_thread *_core_pager; /* pager for core threads */ - Core_mem_allocator _core_mem_alloc; /* core-accessible memory */ - Phys_allocator _io_mem_alloc; /* MMIO allocator */ - Phys_allocator _io_port_alloc; /* I/O port allocator */ - Phys_allocator _irq_alloc; /* IRQ allocator */ - Rom_fs _rom_fs; /* ROM file system */ + Platform_pd *_core_pd; /* core protection domain */ + Platform_thread *_core_pager; /* pager for core threads */ + Core_mem_allocator _core_mem_alloc; /* core-accessible memory */ + Phys_allocator _io_mem_alloc; /* MMIO allocator */ + Phys_allocator _io_port_alloc; /* I/O port allocator */ + Phys_allocator _irq_alloc; /* IRQ allocator */ + Rom_slab _rom_slab; /* Slab for rom modules */ + Rom_fs _rom_fs; /* ROM file system */ + Thread_slab _thread_slab; /* Slab for platform threads */ /* * Virtual-memory range for non-core address spaces. @@ -75,6 +79,10 @@ namespace Genode { */ Platform_thread *core_pager() { return _core_pager; } + /** + * Accessor for platform thread object slab allocator + */ + Thread_slab *thread_slab() { return &_thread_slab; } /********************************************** ** Callbacks used for parsing the boot info ** @@ -113,7 +121,7 @@ namespace Genode { Range_allocator *io_port_alloc() { return &_io_port_alloc; } Range_allocator *irq_alloc() { return &_irq_alloc; } Range_allocator *region_alloc() { return _core_mem_alloc.virt_alloc(); } - Allocator *core_mem_alloc() { return &_core_mem_alloc; } + Range_allocator *core_mem_alloc() { return &_core_mem_alloc; } addr_t vm_start() const { return _vm_start; } size_t vm_size() const { return _vm_size; } Rom_fs *rom_fs() { return &_rom_fs; } diff --git a/base-okl4/src/core/include/util.h b/base-okl4/src/core/include/util.h index 1d4149610..cd61c9712 100644 --- a/base-okl4/src/core/include/util.h +++ b/base-okl4/src/core/include/util.h @@ -61,9 +61,9 @@ namespace Genode { } } - inline size_t get_page_size_log2() { return 12; } - inline size_t get_page_size() { return 1 << get_page_size_log2(); } - inline addr_t get_page_mask() { return ~(get_page_size() - 1); } + constexpr size_t get_page_size_log2() { return 12; } + constexpr size_t get_page_size() { return 1 << get_page_size_log2(); } + constexpr addr_t get_page_mask() { return ~(get_page_size() - 1); } inline size_t get_super_page_size_log2() { diff --git a/base-okl4/src/core/platform.cc b/base-okl4/src/core/platform.cc index 457f7668f..e59b62fec 100644 --- a/base-okl4/src/core/platform.cc +++ b/base-okl4/src/core/platform.cc @@ -53,12 +53,13 @@ static int num_boot_module_objects; ** Support for core memory management ** ****************************************/ -bool Core_mem_allocator::Mapped_mem_allocator::_map_local(addr_t virt_addr, - addr_t phys_addr, - unsigned size_log2) -{ - return map_local(phys_addr, virt_addr, 1 << (size_log2 - get_page_size_log2())); -} +bool Core_mem_allocator::_map_local(addr_t virt_addr, addr_t phys_addr, + unsigned size) { + return map_local(phys_addr, virt_addr, size / get_page_size()); } + + +bool Core_mem_allocator::_unmap_local(addr_t virt_addr, unsigned size) { + return unmap_local(virt_addr, size / get_page_size()); } /********************** @@ -185,9 +186,14 @@ Okl4::bi_name_t Platform::bi_new_ms(Okl4::bi_name_t owner, } +static char init_slab_block_rom[get_page_size()]; +static char init_slab_block_thread[get_page_size()]; + Platform::Platform() : _io_mem_alloc(core_mem_alloc()), _io_port_alloc(core_mem_alloc()), - _irq_alloc(core_mem_alloc()) + _irq_alloc(core_mem_alloc()), + _rom_slab(core_mem_alloc(), (Slab_block *)&init_slab_block_rom), + _thread_slab(core_mem_alloc(), (Slab_block *)&init_slab_block_thread) { /* * We must be single-threaded at this stage and so this is safe. @@ -247,7 +253,7 @@ Platform::Platform() : /* make gathered boot-module info known to '_rom_fs' */ int num_boot_modules = min(num_boot_module_objects, num_boot_module_memsects); for (int i = 0; i < num_boot_modules; i++) { - Rom_module *r = new (core_mem_alloc()) + Rom_module *r = new (&_rom_slab) Rom_module(boot_modules[i].base, boot_modules[i].size, boot_modules[i].name); @@ -294,7 +300,7 @@ Platform::Platform() : * not destroy this task, it should be no problem. */ Platform_thread *core_thread = - new(core_mem_alloc()) Platform_thread("core.main"); + new(&_thread_slab) Platform_thread("core.main"); core_thread->set_l4_thread_id(Okl4::L4_rootserver); diff --git a/base-okl4/src/core/thread_start.cc b/base-okl4/src/core/thread_start.cc index 9a8d89a46..5ecb37cf6 100644 --- a/base-okl4/src/core/thread_start.cc +++ b/base-okl4/src/core/thread_start.cc @@ -34,7 +34,8 @@ void Thread_base::_thread_start() void Thread_base::start() { /* create and start platform thread */ - _tid.pt = new(platform()->core_mem_alloc()) Platform_thread(_context->name); + _tid.pt = new(platform_specific()->thread_slab()) + Platform_thread(_context->name); platform_specific()->core_pd()->bind_thread(_tid.pt); @@ -53,5 +54,5 @@ void Thread_base::cancel_blocking() void Thread_base::_deinit_platform_thread() { /* destruct platform thread */ - destroy(platform()->core_mem_alloc(), _tid.pt); + destroy(platform_specific()->thread_slab(), _tid.pt); } diff --git a/base-pistachio/src/core/include/platform.h b/base-pistachio/src/core/include/platform.h index dfdd14c6a..10923a2be 100644 --- a/base-pistachio/src/core/include/platform.h +++ b/base-pistachio/src/core/include/platform.h @@ -139,7 +139,7 @@ namespace Genode { ** Generic platform interface ** ********************************/ - Allocator *core_mem_alloc() { return &_ram_alloc; } + Range_allocator *core_mem_alloc() { return &_ram_alloc; } Range_allocator *ram_alloc() { return &_ram_alloc; } Range_allocator *io_mem_alloc() { return &_io_mem_alloc; } Range_allocator *io_port_alloc() { return &_io_port_alloc; } diff --git a/base-pistachio/src/core/include/util.h b/base-pistachio/src/core/include/util.h index cb71afe35..6ec49c997 100644 --- a/base-pistachio/src/core/include/util.h +++ b/base-pistachio/src/core/include/util.h @@ -78,9 +78,9 @@ namespace Genode { touch_read_write(bptr); } - inline size_t get_page_size() { return Pistachio::get_page_size(); } - inline size_t get_page_size_log2() { return Pistachio::get_page_size_log2(); } - inline addr_t get_page_mask() { return Pistachio::get_page_mask(); } + constexpr size_t get_page_size_log2() { return 12; } + constexpr size_t get_page_size() { return 1 << get_page_size_log2(); } + constexpr addr_t get_page_mask() { return ~(get_page_size() - 1); } inline size_t get_super_page_size_log2() { diff --git a/base/include/base/allocator_avl.h b/base/include/base/allocator_avl.h index f2caadd4e..57d4bd93a 100644 --- a/base/include/base/allocator_avl.h +++ b/base/include/base/allocator_avl.h @@ -257,13 +257,11 @@ namespace Genode { * * \param BMDT block meta-data type */ - template + template class Allocator_avl_tpl : public Allocator_avl_base { private: - enum { SLAB_BLOCK_SIZE = 256 * sizeof(addr_t) }; - /* * Pump up the Block class with custom meta-data type */ diff --git a/base/src/base/env/platform_env_common.h b/base/src/base/env/platform_env_common.h index e0257f51f..087376304 100644 --- a/base/src/base/env/platform_env_common.h +++ b/base/src/base/env/platform_env_common.h @@ -117,7 +117,7 @@ struct Genode::Expanding_ram_session_client : Upgradeable_clientparent()->resource_request(buf); diff --git a/base/src/core/context_area.cc b/base/src/core/context_area.cc index 83ca382a1..3a7ecd650 100644 --- a/base/src/core/context_area.cc +++ b/base/src/core/context_area.cc @@ -124,7 +124,14 @@ class Context_area_rm_session : public Rm_session class Context_area_ram_session : public Ram_session { - enum { verbose = false }; + private: + + enum { verbose = false }; + + using Ds_slab = Synchronized_allocator >; + + Ds_slab _ds_slab { platform()->core_mem_alloc() }; public: @@ -153,7 +160,7 @@ class Context_area_ram_session : public Ram_session if (verbose) PDBG("phys_base = %p, size = 0x%zx", phys_base, size); - context_ds[i] = new (platform()->core_mem_alloc()) + context_ds[i] = new (&_ds_slab) Dataspace_component(size, 0, (addr_t)phys_base, false, true, 0); Dataspace_capability cap = Dataspace_capability::local_cap(context_ds[i]); @@ -180,7 +187,7 @@ class Context_area_ram_session : public Ram_session if (verbose) PDBG("phys_addr = %p, size = 0x%zx", phys_addr, size); - destroy(platform()->core_mem_alloc(), dataspace_component); + destroy(&_ds_slab, dataspace_component); platform_specific()->ram_alloc()->free(phys_addr, size); } diff --git a/base/src/core/core_mem_alloc.cc b/base/src/core/core_mem_alloc.cc index ea8f7f3c6..190184176 100644 --- a/base/src/core/core_mem_alloc.cc +++ b/base/src/core/core_mem_alloc.cc @@ -1,6 +1,7 @@ /* * \brief Allocator for core-local memory * \author Norman Feske + * \author Stefan Kalkowski * \date 2009-10-12 */ @@ -16,48 +17,46 @@ /* local includes */ #include -#include using namespace Genode; static const bool verbose_core_mem_alloc = false; -bool Core_mem_allocator::Mapped_mem_allocator::alloc(size_t size, void **out_addr) +Range_allocator::Alloc_return +Core_mem_allocator::alloc_aligned(size_t size, void **out_addr, int align) { - /* try to allocate block in cores already mapped virtual address ranges */ - if (_alloc.alloc(size, out_addr)) - return true; - - /* there is no sufficient space in core's mapped virtual memory, expansion needed */ size_t page_rounded_size = (size + get_page_size() - 1) & get_page_mask(); - void *phys_addr = 0, *virt_addr = 0; + void *phys_addr = 0; + align = max((size_t)align, get_page_size_log2()); /* allocate physical pages */ - if (!_phys_alloc->alloc(page_rounded_size, &phys_addr)) { - PERR("Could not allocate physical memory region of size %zu\n", page_rounded_size); - return false; + Alloc_return ret1 = _phys_alloc.raw()->alloc_aligned(page_rounded_size, + &phys_addr, align); + if (!ret1.is_ok()) { + PERR("Could not allocate physical memory region of size %zu\n", + page_rounded_size); + return ret1; } /* allocate range in core's virtual address space */ - if (!_virt_alloc->alloc(page_rounded_size, &virt_addr)) { - PERR("Could not allocate virtual address range in core of size %zu\n", page_rounded_size); + Alloc_return ret2 = _virt_alloc.raw()->alloc_aligned(page_rounded_size, + out_addr, align); + if (!ret2.is_ok()) { + PERR("Could not allocate virtual address range in core of size %zu\n", + page_rounded_size); /* revert physical allocation */ - _phys_alloc->free(phys_addr); - return false; + _phys_alloc.raw()->free(phys_addr); + return ret2; } if (verbose_core_mem_alloc) printf("added core memory block of %zu bytes at virt=%p phys=%p\n", - page_rounded_size, virt_addr, phys_addr); + page_rounded_size, *out_addr, phys_addr); /* make physical page accessible at the designated virtual address */ - _map_local((addr_t)virt_addr, (addr_t)phys_addr, get_page_size_log2()); + _map_local((addr_t)*out_addr, (addr_t)phys_addr, page_rounded_size); - /* add new range to core's allocator for mapped virtual memory */ - _alloc.add_range((addr_t)virt_addr, page_rounded_size); - - /* now that we have added enough memory, try again... */ - return _alloc.alloc(size, out_addr); + return Alloc_return::OK; } diff --git a/base/src/core/include/core_mem_alloc.h b/base/src/core/include/core_mem_alloc.h index 1717a0e8f..8906471c2 100644 --- a/base/src/core/include/core_mem_alloc.h +++ b/base/src/core/include/core_mem_alloc.h @@ -1,6 +1,7 @@ /* * \brief Allocator infrastructure for core * \author Norman Feske + * \author Stefan Kalkowski * \date 2009-10-12 */ @@ -17,162 +18,102 @@ #include #include #include +#include namespace Genode { - - /** - * Allocators for physical memory, core's virtual address space, - * and core-local memory. The interface of this class is thread safe. - */ - class Core_mem_allocator : public Allocator - { - public: - - typedef Synchronized_range_allocator Phys_allocator; - - private: - - /** - * Unsynchronized allocator for core-mapped memory - * - * This is an allocator of core-mapped memory. It is meant to be used as - * meta-data allocator for the other allocators and as back end for core's - * synchronized memory allocator. - */ - class Mapped_mem_allocator : public Allocator - { - private: - - Allocator_avl _alloc; - Range_allocator *_phys_alloc; - Range_allocator *_virt_alloc; - - /** - * Initial chunk to populate the core mem allocator - * - * This chunk is used at platform initialization time. - */ - char _initial_chunk[16*1024]; - - /** - * Map physical page locally to specified virtual address - * - * \param virt_addr core-local address - * \param phys_addr physical memory address - * \param size_log2 size of memory block to map - * \return true on success - */ - bool _map_local(addr_t virt_addr, addr_t phys_addr, unsigned size_log2); - - public: - - /** - * Constructor - * - * \param phys_alloc allocator of physical memory - * \param virt_alloc allocator of core-local virtual memory ranges - */ - Mapped_mem_allocator(Range_allocator *phys_alloc, - Range_allocator *virt_alloc) - : _alloc(0), _phys_alloc(phys_alloc), _virt_alloc(virt_alloc) - { - _alloc.add_range((addr_t)_initial_chunk, sizeof(_initial_chunk)); - } + class Core_mem_allocator; +}; - /************************* - ** Allocator interface ** - *************************/ +/** + * Allocators for physical memory, core's virtual address space, + * and core-local memory. The interface of this class is thread safe. + * The class itself implements a ready-to-use memory allocator for + * core that allows to allocate memory at page granularity only. + */ +class Genode::Core_mem_allocator : public Genode::Range_allocator +{ + public: - bool alloc(size_t size, void **out_addr); - void free(void *addr, size_t size) { _alloc.free(addr, size); } - size_t consumed() { return _phys_alloc->consumed(); } - size_t overhead(size_t size) { return _phys_alloc->overhead(size); } + using Page_allocator = Allocator_avl_tpl; + using Phys_allocator = Synchronized_range_allocator; - bool need_size_for_free() const override { - return _phys_alloc->need_size_for_free(); } - }; + protected: + + /** + * Lock used for synchronization of all operations on the + * embedded allocators. + */ + Lock _lock; + + /** + * Synchronized allocator of physical memory ranges + * + * This allocator must only be used to allocate memory + * ranges at page granularity. + */ + Phys_allocator _phys_alloc; + + /** + * Synchronized allocator of core's virtual memory ranges + * + * This allocator must only be used to allocate memory + * ranges at page granularity. + */ + Phys_allocator _virt_alloc; + + bool _map_local(addr_t virt_addr, addr_t phys_addr, unsigned size); + bool _unmap_local(addr_t virt_addr, unsigned size); + + public: + + /** + * Constructor + */ + Core_mem_allocator() + : _phys_alloc(&_lock, this), + _virt_alloc(&_lock, this) { } + + /** + * Access physical-memory allocator + */ + Phys_allocator *phys_alloc() { return &_phys_alloc; } + + /** + * Access core's virtual-memory allocator + */ + Phys_allocator *virt_alloc() { return &_virt_alloc; } - /** - * Lock used for synchronization of all operations on the - * embedded allocators. - */ - Lock _lock; + /******************************* + ** Range allocator interface ** + *******************************/ - /** - * Synchronized allocator of physical memory ranges - * - * This allocator must only be used to allocate memory - * ranges at page granularity. - */ - Phys_allocator _phys_alloc; + 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); + Alloc_return alloc_addr(size_t size, addr_t addr) { + return Alloc_return::RANGE_CONFLICT; } + void free(void *addr) {} + size_t avail() { return _phys_alloc.avail(); } - /** - * Synchronized allocator of core's virtual memory ranges - * - * This allocator must only be used to allocate memory - * ranges at page granularity. - */ - Phys_allocator _virt_alloc; - - /** - * Unsynchronized core-mapped memory allocator - * - * This allocator is internally used within this class for - * allocating meta data for the other allocators. It is not - * synchronized to avoid nested locking. The lock-guarded - * access to this allocator from the outer world is - * provided via the 'Allocator' interface implemented by - * 'Core_mem_allocator'. The allocator works at byte - * granularity. - */ - Mapped_mem_allocator _mem_alloc; - - public: - - /** - * Constructor - */ - Core_mem_allocator() : - _phys_alloc(&_lock, &_mem_alloc), - _virt_alloc(&_lock, &_mem_alloc), - _mem_alloc(_phys_alloc.raw(), _virt_alloc.raw()) - { } - - /** - * Access physical-memory allocator - */ - Phys_allocator *phys_alloc() { return &_phys_alloc; } - - /** - * Access core's virtual-memory allocator - */ - Phys_allocator *virt_alloc() { return &_virt_alloc; } + bool valid_addr(addr_t addr) { return _virt_alloc.valid_addr(addr); } - /************************* - ** Allocator interface ** - *************************/ + /************************* + ** Allocator interface ** + *************************/ - bool alloc(size_t size, void **out_addr) - { - Lock::Guard lock_guard(_lock); - return _mem_alloc.alloc(size, out_addr); - } + bool alloc(size_t size, void **out_addr) { + return alloc_aligned(size, out_addr).is_ok(); } - void free(void *addr, size_t size) - { - Lock::Guard lock_guard(_lock); - _mem_alloc.free(addr, size); - } + void free(void *addr, size_t) { free(addr); } - size_t consumed() { return _phys_alloc.consumed(); } - size_t overhead(size_t size) { return _phys_alloc.overhead(size); } + size_t consumed() { return _phys_alloc.consumed(); } + size_t overhead(size_t size) { return _phys_alloc.overhead(size); } - bool need_size_for_free() const override { - return _phys_alloc.need_size_for_free(); } - }; -} + bool need_size_for_free() const override { + return _phys_alloc.need_size_for_free(); } +}; #endif /* _CORE__INCLUDE__CORE_MEM_ALLOC_H_ */ diff --git a/base/src/core/include/platform_generic.h b/base/src/core/include/platform_generic.h index 2367b2313..538859f6a 100644 --- a/base/src/core/include/platform_generic.h +++ b/base/src/core/include/platform_generic.h @@ -37,7 +37,7 @@ namespace Genode { /** * Allocator of core-local mapped virtual memory */ - virtual Allocator *core_mem_alloc() = 0; + virtual Range_allocator *core_mem_alloc() = 0; /** * Allocator of physical memory diff --git a/base/src/core/include/ram_session_component.h b/base/src/core/include/ram_session_component.h index 5d56bfd66..7cf439926 100644 --- a/base/src/core/include/ram_session_component.h +++ b/base/src/core/include/ram_session_component.h @@ -23,6 +23,7 @@ /* core includes */ #include +#include namespace Genode { @@ -37,9 +38,10 @@ namespace Genode { class Invalid_dataspace : public Exception { }; - enum { SBS = 1024 }; /* slab block size */ + static constexpr size_t SBS = get_page_size(); - typedef Synchronized_allocator > Ds_slab; + using Ds_slab = Synchronized_allocator >; Rpc_entrypoint *_ds_ep; Rpc_entrypoint *_ram_session_ep;