diff --git a/repos/base-hw/src/bootstrap/init.cc b/repos/base-hw/src/bootstrap/init.cc index 9fcda2fec3..e29fe4b91b 100644 --- a/repos/base-hw/src/bootstrap/init.cc +++ b/repos/base-hw/src/bootstrap/init.cc @@ -16,7 +16,6 @@ /* base includes */ #include -#include using namespace Genode; @@ -26,13 +25,23 @@ size_t bootstrap_stack_size = STACK_SIZE; uint8_t bootstrap_stack[Board::NR_OF_CPUS][STACK_SIZE] __attribute__((aligned(get_page_size()))); -Bootstrap::Platform & Bootstrap::platform() { - return *unmanaged_singleton(); } + +Bootstrap::Platform & Bootstrap::platform() +{ + /* + * Don't use static local variable because cmpxchg cannot be executed + * w/o MMU on ARMv6. + */ + static long _obj[(sizeof(Bootstrap::Platform)+sizeof(long))/sizeof(long)]; + static Bootstrap::Platform *ptr; + if (!ptr) + ptr = construct_at(_obj); + + return *ptr; +} extern "C" void init() __attribute__ ((noreturn)); - - extern "C" void init() { Bootstrap::Platform & p = Bootstrap::platform(); diff --git a/repos/base-hw/src/bootstrap/log.cc b/repos/base-hw/src/bootstrap/log.cc index fedee7e2cd..4877c33e1b 100644 --- a/repos/base-hw/src/bootstrap/log.cc +++ b/repos/base-hw/src/bootstrap/log.cc @@ -20,7 +20,6 @@ #include #include #include -#include #include @@ -55,7 +54,11 @@ struct Buffer }; -Genode::Log &Genode::Log::log() { return unmanaged_singleton()->log; } +Genode::Log &Genode::Log::log() +{ + static Buffer buffer { }; + return buffer.log; +} void Genode::raw_write_string(char const *str) { log(str); } diff --git a/repos/base-hw/src/core/platform.cc b/repos/base-hw/src/core/platform.cc index 2090cf763d..33f4c4a65c 100644 --- a/repos/base-hw/src/core/platform.cc +++ b/repos/base-hw/src/core/platform.cc @@ -31,7 +31,6 @@ /* base internal includes */ #include #include -#include /* base includes */ #include @@ -60,8 +59,9 @@ Hw::Page_table::Allocator & Platform::core_page_table_allocator() using Allocator = Hw::Page_table::Allocator; using Array = Allocator::Array; addr_t virt_addr = Hw::Mm::core_page_tables().base + sizeof(Hw::Page_table); - return *unmanaged_singleton(_boot_info().table_allocator, - virt_addr); + + static Array::Allocator alloc { _boot_info().table_allocator, virt_addr }; + return alloc; } @@ -70,6 +70,7 @@ addr_t Platform::core_main_thread_phys_utcb() return core_phys_addr(_boot_info().core_main_thread_utcb); } + void Platform::_init_io_mem_alloc() { /* add entire adress space minus the RAM memory regions */ @@ -81,8 +82,9 @@ void Platform::_init_io_mem_alloc() Hw::Memory_region_array const & Platform::_core_virt_regions() { - return *unmanaged_singleton( - Hw::Memory_region(stack_area_virtual_base(), stack_area_virtual_size())); + static Hw::Memory_region_array array { + Hw::Memory_region(stack_area_virtual_base(), stack_area_virtual_size()) }; + return array; } diff --git a/repos/base-hw/src/core/spec/arm/virtualization/vm_session_component.cc b/repos/base-hw/src/core/spec/arm/virtualization/vm_session_component.cc index e83d7169f3..fdd40179e5 100644 --- a/repos/base-hw/src/core/spec/arm/virtualization/vm_session_component.cc +++ b/repos/base-hw/src/core/spec/arm/virtualization/vm_session_component.cc @@ -14,9 +14,6 @@ /* Genode includes */ #include -/* base internal includes */ -#include - /* core includes */ #include #include diff --git a/repos/base/include/base/heap.h b/repos/base/include/base/heap.h index f67918e10a..1abd508bdb 100644 --- a/repos/base/include/base/heap.h +++ b/repos/base/include/base/heap.h @@ -119,7 +119,7 @@ class Genode::Heap : public Allocator public: - enum { UNLIMITED = ~0 }; + static constexpr size_t UNLIMITED = ~0; Heap(Ram_allocator *ram_allocator, Region_map *region_map, diff --git a/repos/base/include/spec/x86/bios_data_area.h b/repos/base/include/spec/x86/bios_data_area.h index 8d67fd72c9..562abc7fa4 100644 --- a/repos/base/include/spec/x86/bios_data_area.h +++ b/repos/base/include/spec/x86/bios_data_area.h @@ -17,15 +17,11 @@ /* Genode includes */ #include -/* base-internal includes */ -#include - namespace Genode { class Bios_data_area; } + class Genode::Bios_data_area : Mmio<0x12> { - friend Unmanaged_singleton_constructor; - private: struct Serial_base_com1 : Register<0x0, 16> { }; @@ -52,8 +48,11 @@ class Genode::Bios_data_area : Mmio<0x12> /** * Return BDA singleton */ - static Bios_data_area * singleton() { - return unmanaged_singleton(); } + static Bios_data_area * singleton() + { + static Bios_data_area bda { }; + return &bda; + } }; #endif /* _INCLUDE__SPEC__X86__BIOS_DATA_AREA_H_ */ diff --git a/repos/base/src/core/default_log.cc b/repos/base/src/core/default_log.cc index 1da89e4deb..8193429ae4 100644 --- a/repos/base/src/core/default_log.cc +++ b/repos/base/src/core/default_log.cc @@ -17,7 +17,6 @@ /* base-internal includes */ #include -#include /* core includes */ #include @@ -36,7 +35,8 @@ Genode::Log &Genode::Log::log() Log log { buffer }; }; - return unmanaged_singleton()->log; + static Buffer buffer { }; + return buffer.log; } diff --git a/repos/base/src/include/base/internal/unmanaged_singleton.h b/repos/base/src/include/base/internal/unmanaged_singleton.h deleted file mode 100644 index 0909cd5d71..0000000000 --- a/repos/base/src/include/base/internal/unmanaged_singleton.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * \brief Singleton objects that aren't implicitly constructed or destructed - * \author Norman Feske - * \author Martin Stein - * \date 2013-12-04 - * - * Before enabling the MMU on ARM, the 'cmpxchg' implementation is not always - * guaranteed to work. For example, on the Raspberry Pi, the 'ldrex' as used by - * 'cmpxchg' causes the machine to reboot. After enabling the MMU, everything - * is fine. Hence, we need to avoid executing 'cmpxchg' prior this point. - * Unfortunately, 'cmpxchg' is implicitly called each time when creating a - * singleton object via a local-static object pattern. In this case, the - * compiler generates code that calls the '__cxa_guard_acquire' function of the - * C++ runtime, which, in turn, relies 'cmpxchg' for synchronization. - * - * The utility provided herein is an alternative way to create single object - * instances without implicitly calling 'cmpxchg'. Furthermore, the created - * objects are not destructed automatically at program exit which is useful - * because it prevents the main thread of a program from destructing the - * enviroment it needs to finish program close-down. Because object creation - * is not synchronized via a spin lock, it must not be used in scenarios where - * multiple threads may contend. - */ - -/* - * Copyright (C) 2013-2017 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -#ifndef _INCLUDE__BASE__INTERNAL__UNMANAGED_SINGLETON_H_ -#define _INCLUDE__BASE__INTERNAL__UNMANAGED_SINGLETON_H_ - -/* Genode includes */ -#include - -/** - * Placement new operator - * - * \param p destination address - */ -inline void * operator new(__SIZE_TYPE__, void * p) { return p; } - -/** - * Helper class for the use of unmanaged_singleton with the singleton pattern - * - * If a class wants to make its constructor private to force the singleton - * pattern, it can declare this class as friend to be able to still use the - * unmanaged_singleton template. - */ -struct Unmanaged_singleton_constructor -{ - /** - * Call the constructor of 'T' with arguments 'args' at 'dst' - */ - template - static void call(char * const dst, auto &&... args) { new (dst) T(args...); } -}; - -/** - * Create a singleton object that isn't implicitly constructed or destructed - * - * \param T object type - * \param ALIGNMENT object alignment - * \param ARGS arguments to the object constructor - * - * \return object pointer - */ -template -static inline T * unmanaged_singleton(auto &&... args) -{ - /* - * Each instantiation of the function template with a different type 'T' - * yields a dedicated instance of the local static variables, thereby - * creating the living space for the singleton objects. - */ - enum { OBJECT_SIZE = sizeof(T) / sizeof(char) + 1 }; - static bool object_constructed = false; - static char object_space[OBJECT_SIZE] __attribute__((aligned(ALIGNMENT))); - - /* execute constructor on first call */ - if (!object_constructed) { - object_constructed = true; - Unmanaged_singleton_constructor::call(object_space, args...); - } - return reinterpret_cast(object_space); -} - -#endif /* _INCLUDE__BASE__INTERNAL__UNMANAGED_SINGLETON_H_ */ diff --git a/repos/base/src/lib/base/default_log.cc b/repos/base/src/lib/base/default_log.cc index ab84657471..609f7b48aa 100644 --- a/repos/base/src/lib/base/default_log.cc +++ b/repos/base/src/lib/base/default_log.cc @@ -20,7 +20,6 @@ /* base-internal includes */ #include -#include using namespace Genode; @@ -100,7 +99,8 @@ void Genode::init_log(Parent &parent) if (log_ptr) return; - back_end_ptr = unmanaged_singleton(parent); + static Back_end back_end { parent }; + back_end_ptr = &back_end; struct Write_fn { void operator () (char const *s) { @@ -111,12 +111,10 @@ void Genode::init_log(Parent &parent) using Buffered_log_output = Buffered_output; - static Buffered_log_output *buffered_log_output = - unmanaged_singleton(Write_fn()); + static Buffered_log_output buffered_log_output { Write_fn() }; + static Log log { buffered_log_output }; + static Trace_output trace { }; - log_ptr = unmanaged_singleton(*buffered_log_output); - - /* enable trace back end */ - trace_ptr = unmanaged_singleton(); + log_ptr = &log; + trace_ptr = &trace; } - diff --git a/repos/base/src/lib/base/env_session_id_space.cc b/repos/base/src/lib/base/env_session_id_space.cc index 4749f42469..baa6c99445 100644 --- a/repos/base/src/lib/base/env_session_id_space.cc +++ b/repos/base/src/lib/base/env_session_id_space.cc @@ -17,15 +17,13 @@ /* base-internal includes */ #include -#include using namespace Genode; Id_space &Genode::env_session_id_space() { - Id_space &id_space = - *unmanaged_singleton >(); + static Id_space id_space { }; /* pre-allocate env session IDs */ static Parent::Client dummy; diff --git a/repos/base/src/lib/base/heartbeat.cc b/repos/base/src/lib/base/heartbeat.cc index 186cef6f0c..88882b97f7 100644 --- a/repos/base/src/lib/base/heartbeat.cc +++ b/repos/base/src/lib/base/heartbeat.cc @@ -13,11 +13,9 @@ /* Genode includes */ #include -#include /* base-internal includes */ #include -#include using namespace Genode; @@ -48,14 +46,7 @@ namespace { } -static Constructible *_heartbeat_handler_ptr = nullptr; - - void Genode::init_heartbeat_monitoring(Env &env) { - if (_heartbeat_handler_ptr) - return; - - _heartbeat_handler_ptr = unmanaged_singleton>(); - _heartbeat_handler_ptr->construct(env); + static Heartbeat_handler heartbeat_handler { env }; } diff --git a/repos/base/src/lib/base/raw_output.cc b/repos/base/src/lib/base/raw_output.cc index 3da8ac8aaf..46c70f1744 100644 --- a/repos/base/src/lib/base/raw_output.cc +++ b/repos/base/src/lib/base/raw_output.cc @@ -16,7 +16,6 @@ #include /* base-internal includes */ -#include #include @@ -24,10 +23,7 @@ Genode::Output &Genode::Raw::_output() { struct Write_fn { void operator () (char const *s) { raw_write_string(s); } }; - using Buffered_raw_output = Buffered_output<256, Write_fn>; + static Buffered_output<256, Write_fn> buffered_raw_output { Write_fn() }; - static Buffered_raw_output *buffered_raw_output = - unmanaged_singleton(Write_fn()); - - return *buffered_raw_output; + return buffered_raw_output; } diff --git a/repos/base/src/lib/base/signal.cc b/repos/base/src/lib/base/signal.cc index 2fbe929f29..5f01180971 100644 --- a/repos/base/src/lib/base/signal.cc +++ b/repos/base/src/lib/base/signal.cc @@ -22,7 +22,6 @@ /* base-internal includes */ #include -#include #include using namespace Genode; @@ -89,7 +88,8 @@ class Signal_handler_thread : Thread, Blockade */ static Constructible & signal_handler_thread() { - return *unmanaged_singleton >(); + static Constructible signal_handler_thread { }; + return signal_handler_thread; } diff --git a/repos/base/src/lib/cxx/guard.cc b/repos/base/src/lib/cxx/guard.cc index 55324eaec5..feb5f4ca5a 100644 --- a/repos/base/src/lib/cxx/guard.cc +++ b/repos/base/src/lib/cxx/guard.cc @@ -18,7 +18,6 @@ /* base-internal includes */ #include -#include using Blockers = Genode::Registry >; @@ -29,7 +28,8 @@ static Blockers *blockers_ptr; void Genode::init_cxx_guard() { - blockers_ptr = unmanaged_singleton(); + static Blockers blockers { }; + blockers_ptr = &blockers; } diff --git a/repos/base/src/lib/cxx/malloc_free.cc b/repos/base/src/lib/cxx/malloc_free.cc index 7b744c5545..7a0a487246 100644 --- a/repos/base/src/lib/cxx/malloc_free.cc +++ b/repos/base/src/lib/cxx/malloc_free.cc @@ -21,7 +21,6 @@ /* base-internal includes */ #include -#include using namespace Genode; @@ -58,8 +57,8 @@ void Genode::init_cxx_heap(Ram_allocator &ram, Region_map &rm) */ static char initial_block[1024*sizeof(long)]; - cxx_heap_ptr = unmanaged_singleton(&ram, &rm, Heap::UNLIMITED, - initial_block, sizeof(initial_block)); + static Heap heap { &ram, &rm, Heap::UNLIMITED, initial_block, sizeof(initial_block) }; + cxx_heap_ptr = &heap; } diff --git a/repos/base/src/lib/ldso/main.cc b/repos/base/src/lib/ldso/main.cc index c9b21c3d52..242820ec70 100644 --- a/repos/base/src/lib/ldso/main.cc +++ b/repos/base/src/lib/ldso/main.cc @@ -22,7 +22,6 @@ #include /* base-internal includes */ -#include #include /* local includes */ @@ -58,7 +57,8 @@ Linker::Region_map::Constructible_region_map &Linker::Region_map::r() * the singleton object as the destructor would try to access * the capabilities also in the forked process. */ - return *unmanaged_singleton(); + static Constructible_region_map rm { }; + return rm; } @@ -637,7 +637,8 @@ extern "C" void init_rtld() static Genode::Constructible &heap() { - return *unmanaged_singleton>(); + static Constructible heap; + return heap; } @@ -684,7 +685,7 @@ void Genode::init_ldso_phdr(Env &env) Linker_area_region_map() { } }; - Linker_area_region_map &ld_rm = *unmanaged_singleton(); + static Linker_area_region_map ld_rm { }; /* * Use a statically allocated initial block to make the first dynamic @@ -781,7 +782,8 @@ void Component::construct(Genode::Env &env) /* load binary and all dependencies */ try { - binary_ptr = unmanaged_singleton(env, *heap(), config, binary_name()); + static Binary binary { env, *heap(), config, binary_name() }; + binary_ptr = &binary; } catch(Linker::Not_found &symbol) { error("LD: symbol not found: '", symbol, "'"); throw;