base: remove base/internal/unmanaged_singleton.h

Fixes #5418
This commit is contained in:
Norman Feske 2025-01-13 14:36:56 +01:00 committed by Christian Helmuth
parent 580456ef7b
commit 2ac0a7368c
16 changed files with 59 additions and 155 deletions

View File

@ -16,7 +16,6 @@
/* base includes */
#include <base/internal/globals.h>
#include <base/internal/unmanaged_singleton.h>
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 & 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<Bootstrap::Platform>(_obj);
return *ptr;
}
extern "C" void init() __attribute__ ((noreturn));
extern "C" void init()
{
Bootstrap::Platform & p = Bootstrap::platform();

View File

@ -20,7 +20,6 @@
#include <base/internal/globals.h>
#include <base/internal/output.h>
#include <base/internal/raw_write_string.h>
#include <base/internal/unmanaged_singleton.h>
#include <board.h>
@ -55,7 +54,11 @@ struct Buffer
};
Genode::Log &Genode::Log::log() { return unmanaged_singleton<Buffer>()->log; }
Genode::Log &Genode::Log::log()
{
static Buffer buffer { };
return buffer.log;
}
void Genode::raw_write_string(char const *str) { log(str); }

View File

@ -31,7 +31,6 @@
/* base internal includes */
#include <base/internal/crt0.h>
#include <base/internal/stack_area.h>
#include <base/internal/unmanaged_singleton.h>
/* base includes */
#include <trace/source_registry.h>
@ -60,8 +59,9 @@ Hw::Page_table::Allocator & Platform::core_page_table_allocator()
using Allocator = Hw::Page_table::Allocator;
using Array = Allocator::Array<Hw::Page_table::CORE_TRANS_TABLE_COUNT>;
addr_t virt_addr = Hw::Mm::core_page_tables().base + sizeof(Hw::Page_table);
return *unmanaged_singleton<Array::Allocator>(_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_array>(
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;
}

View File

@ -14,9 +14,6 @@
/* Genode includes */
#include <util/construct_at.h>
/* base internal includes */
#include <base/internal/unmanaged_singleton.h>
/* core includes */
#include <kernel/core_interface.h>
#include <vm_session_component.h>

View File

@ -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,

View File

@ -17,15 +17,11 @@
/* Genode includes */
#include <util/mmio.h>
/* base-internal includes */
#include <base/internal/unmanaged_singleton.h>
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<Bios_data_area>(); }
static Bios_data_area * singleton()
{
static Bios_data_area bda { };
return &bda;
}
};
#endif /* _INCLUDE__SPEC__X86__BIOS_DATA_AREA_H_ */

View File

@ -17,7 +17,6 @@
/* base-internal includes */
#include <base/internal/globals.h>
#include <base/internal/unmanaged_singleton.h>
/* core includes */
#include <core_log.h>
@ -36,7 +35,8 @@ Genode::Log &Genode::Log::log()
Log log { buffer };
};
return unmanaged_singleton<Buffer>()->log;
static Buffer buffer { };
return buffer.log;
}

View File

@ -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 <base/stdint.h>
/**
* 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 <typename T>
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 <typename T, int ALIGNMENT = sizeof(Genode::addr_t)>
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<T>(object_space, args...);
}
return reinterpret_cast<T *>(object_space);
}
#endif /* _INCLUDE__BASE__INTERNAL__UNMANAGED_SINGLETON_H_ */

View File

@ -20,7 +20,6 @@
/* base-internal includes */
#include <base/internal/globals.h>
#include <base/internal/unmanaged_singleton.h>
using namespace Genode;
@ -100,7 +99,8 @@ void Genode::init_log(Parent &parent)
if (log_ptr)
return;
back_end_ptr = unmanaged_singleton<Back_end>(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<Log_session::MAX_STRING_LEN, Write_fn>;
static Buffered_log_output *buffered_log_output =
unmanaged_singleton<Buffered_log_output>(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<Log>(*buffered_log_output);
/* enable trace back end */
trace_ptr = unmanaged_singleton<Trace_output>();
log_ptr = &log;
trace_ptr = &trace;
}

View File

@ -17,15 +17,13 @@
/* base-internal includes */
#include <base/internal/globals.h>
#include <base/internal/unmanaged_singleton.h>
using namespace Genode;
Id_space<Parent::Client> &Genode::env_session_id_space()
{
Id_space<Parent::Client> &id_space =
*unmanaged_singleton<Id_space<Parent::Client> >();
static Id_space<Parent::Client> id_space { };
/* pre-allocate env session IDs */
static Parent::Client dummy;

View File

@ -13,11 +13,9 @@
/* Genode includes */
#include <base/env.h>
#include <base/log.h>
/* base-internal includes */
#include <base/internal/globals.h>
#include <base/internal/unmanaged_singleton.h>
using namespace Genode;
@ -48,14 +46,7 @@ namespace {
}
static Constructible<Heartbeat_handler> *_heartbeat_handler_ptr = nullptr;
void Genode::init_heartbeat_monitoring(Env &env)
{
if (_heartbeat_handler_ptr)
return;
_heartbeat_handler_ptr = unmanaged_singleton<Constructible<Heartbeat_handler>>();
_heartbeat_handler_ptr->construct(env);
static Heartbeat_handler heartbeat_handler { env };
}

View File

@ -16,7 +16,6 @@
#include <base/buffered_output.h>
/* base-internal includes */
#include <base/internal/unmanaged_singleton.h>
#include <base/internal/raw_write_string.h>
@ -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<Buffered_raw_output>(Write_fn());
return *buffered_raw_output;
return buffered_raw_output;
}

View File

@ -22,7 +22,6 @@
/* base-internal includes */
#include <base/internal/globals.h>
#include <base/internal/unmanaged_singleton.h>
#include <signal_source/client.h>
using namespace Genode;
@ -89,7 +88,8 @@ class Signal_handler_thread : Thread, Blockade
*/
static Constructible<Signal_handler_thread> & signal_handler_thread()
{
return *unmanaged_singleton<Constructible<Signal_handler_thread> >();
static Constructible<Signal_handler_thread> signal_handler_thread { };
return signal_handler_thread;
}

View File

@ -18,7 +18,6 @@
/* base-internal includes */
#include <base/internal/globals.h>
#include <base/internal/unmanaged_singleton.h>
using Blockers = Genode::Registry<Genode::Registered_no_delete<Genode::Semaphore> >;
@ -29,7 +28,8 @@ static Blockers *blockers_ptr;
void Genode::init_cxx_guard()
{
blockers_ptr = unmanaged_singleton<Blockers>();
static Blockers blockers { };
blockers_ptr = &blockers;
}

View File

@ -21,7 +21,6 @@
/* base-internal includes */
#include <base/internal/globals.h>
#include <base/internal/unmanaged_singleton.h>
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<Heap>(&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;
}

View File

@ -22,7 +22,6 @@
#include <base/sleep.h>
/* base-internal includes */
#include <base/internal/unmanaged_singleton.h>
#include <base/internal/globals.h>
/* 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<Constructible_region_map>();
static Constructible_region_map rm { };
return rm;
}
@ -637,7 +637,8 @@ extern "C" void init_rtld()
static Genode::Constructible<Heap> &heap()
{
return *unmanaged_singleton<Constructible<Heap>>();
static Constructible<Heap> 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<Linker_area_region_map>();
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<Binary>(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;