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;