diff --git a/repos/libports/lib/mk/libc.mk b/repos/libports/lib/mk/libc.mk
index efa6a790a8..e7a4d1e942 100644
--- a/repos/libports/lib/mk/libc.mk
+++ b/repos/libports/lib/mk/libc.mk
@@ -40,10 +40,6 @@ CC_OPT_dummies += -I$(LIBC_DIR)/sys
INC_DIR += $(REP_DIR)/src/lib/libc
INC_DIR += $(REP_DIR)/src/lib/libc/include
-# needed for base/internal/unmanaged_singleton.h
-INC_DIR += $(BASE_DIR)/src/include
-INC_DIR += $(BASE_DIR)/sys
-
#
# Files from string library that are not included in libc-raw_string because
# they depend on the locale library.
diff --git a/repos/libports/src/lib/libc/component.cc b/repos/libports/src/lib/libc/component.cc
index 237ec974dc..0f565b8b37 100644
--- a/repos/libports/src/lib/libc/component.cc
+++ b/repos/libports/src/lib/libc/component.cc
@@ -15,9 +15,6 @@
/* Genode includes */
#include
-/* base-internal includes */
-#include
-
/* libc-internal includes */
#include
#include
@@ -35,8 +32,8 @@ void Component::construct(Genode::Env &env)
static char *null_env = nullptr;
if (!environ) environ = &null_env;
- Genode::Allocator &heap =
- *unmanaged_singleton(env.ram(), env.rm());
+ /* call of '__cxa_atexit' is ignored prior 'init_atexit' */
+ static Genode::Heap heap { env.ram(), env.rm() };
/* pass Genode::Env to libc subsystems that depend on it */
Libc::init_fd_alloc(heap);
@@ -44,7 +41,9 @@ void Component::construct(Genode::Env &env)
Libc::init_dl(env);
Libc::sysctl_init(env);
- Libc::Kernel &kernel = *unmanaged_singleton(env, heap);
+ /* prevent call of '__cxa_atexit' for the 'Kernel' object */
+ static long _kernel_obj[(sizeof(Libc::Kernel) + sizeof(long))/sizeof(long)];
+ Libc::Kernel &kernel = *new (_kernel_obj) Libc::Kernel(env, heap);
Libc::libc_config_init(kernel.libc_env().libc_config());
diff --git a/repos/libports/src/lib/libc/internal/kernel.h b/repos/libports/src/lib/libc/internal/kernel.h
index 41a5aca118..069ae77ef9 100644
--- a/repos/libports/src/lib/libc/internal/kernel.h
+++ b/repos/libports/src/lib/libc/internal/kernel.h
@@ -412,6 +412,9 @@ struct Libc::Kernel final : Vfs::Read_ready_response_handler,
~Kernel() { error(__PRETTY_FUNCTION__, " should not be executed!"); }
+ /* use placement new instead of 'construct_at' because 'Kernel' is final */
+ void *operator new (size_t, void *ptr) { return ptr; }
+
Libc::Env & libc_env() { return _libc_env; }
/**
diff --git a/repos/libports/src/lib/libc/malloc.cc b/repos/libports/src/lib/libc/malloc.cc
index 1a9e67b3b7..2998070d42 100644
--- a/repos/libports/src/lib/libc/malloc.cc
+++ b/repos/libports/src/lib/libc/malloc.cc
@@ -26,9 +26,6 @@ extern "C" {
#include
}
-/* Genode-internal includes */
-#include
-
/* libc-internal includes */
#include
#include
@@ -285,34 +282,24 @@ int posix_memalign(void **memptr, size_t alignment, size_t size)
}
-static Genode::Constructible &constructible_malloc()
-{
- return *unmanaged_singleton >();
-}
+/* space for singleton object w/o destructor */
+static long _malloc_obj[(sizeof(Malloc) + sizeof(long))/sizeof(long)];
void Libc::init_malloc(Genode::Allocator &heap)
{
-
- Constructible &_malloc = constructible_malloc();
-
- _malloc.construct(heap);
-
- mallocator = _malloc.operator->();
+ mallocator = construct_at(_malloc_obj, heap);
}
void Libc::init_malloc_cloned(Clone_connection &clone_connection)
{
- clone_connection.object_content(constructible_malloc());
-
- mallocator = constructible_malloc().operator->();
+ clone_connection.object_content(_malloc_obj);
+ mallocator = (Malloc *)_malloc_obj;
}
void Libc::reinit_malloc(Genode::Allocator &heap)
{
- Malloc &malloc = *constructible_malloc();
-
- construct_at(&malloc, heap);
+ construct_at(_malloc_obj, heap);
}
diff --git a/repos/libports/src/lib/libc/pthread.cc b/repos/libports/src/lib/libc/pthread.cc
index 644db5cb4f..830611f2fc 100644
--- a/repos/libports/src/lib/libc/pthread.cc
+++ b/repos/libports/src/lib/libc/pthread.cc
@@ -18,9 +18,6 @@
#include
#include
-/* Genode-internal includes */
-#include
-
/* libc includes */
#include
#include
@@ -751,11 +748,16 @@ extern "C" {
/*
* We create a pthread object associated to the main thread's Thread
* object. We ensure the pthread object does never get deleted by
- * allocating it as unmanaged_singleton. Otherwise, the static
+ * allocating it as unmanaged singleton '_obj'. Otherwise, the static
* destruction of the pthread object would also destruct the 'Thread'
* of the main thread.
*/
- return unmanaged_singleton(*Thread::myself(), &pthread_myself);
+ static pthread_t main_pthread_t = nullptr;
+ if (!main_pthread_t) {
+ static long _obj[(sizeof(pthread) + sizeof(long))/sizeof(long)];
+ main_pthread_t = construct_at(_obj, *Thread::myself(), &pthread_myself);
+ }
+ return main_pthread_t;
}
typeof(pthread_self) _pthread_self
diff --git a/repos/libports/src/lib/libc/time.cc b/repos/libports/src/lib/libc/time.cc
index 80667ff351..76b88d19dd 100644
--- a/repos/libports/src/lib/libc/time.cc
+++ b/repos/libports/src/lib/libc/time.cc
@@ -16,9 +16,6 @@
#include
#include
-/* Genode-internal includes */
-#include
-
/* libc includes */
#include
#include