hw: replace unsynchronized by unmanaged singleton

ref 
This commit is contained in:
Martin Stein 2013-12-04 23:41:52 +01:00 committed by Norman Feske
parent 212fc47768
commit 77130a9404
7 changed files with 27 additions and 84 deletions

@ -16,8 +16,8 @@
#include <base/printf.h>
#include <drivers/serial_log.h>
/* base-hw includes */
#include "singleton.h"
/* base includes */
#include <unmanaged_singleton.h>
namespace Genode
{
@ -66,7 +66,7 @@ using namespace Genode;
*/
static Platform_console * platform_console()
{
return unsynchronized_singleton<Platform_console>();
return unmanaged_singleton<Platform_console>();
}

@ -14,9 +14,9 @@
#ifndef _PLACEMENT_NEW_H_
#define _PLACEMENT_NEW_H_
/**
* Placement new operator
*/
inline void *operator new(Genode::size_t, void *at) { return at; }
/* base includes */
#include <unmanaged_singleton.h>
/* FIXME: remove this header as soon as the Placeable template is public */
#endif /* _PLACEMENT_NEW_H_ */

@ -1,56 +0,0 @@
/*
* \brief Helper for creating singleton objects
* \author Norman Feske
* \date 2013-05-14
*
* 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'. 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 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 _SINGLETON_H_
#define _SINGLETON_H_
/* Genode includes */
#include <base/stdint.h>
/* base-hw includes */
#include <placement_new.h>
template <typename T, int ALIGN = 2, typename... Args>
static inline T *unsynchronized_singleton(Args... 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.
*/
static bool initialized;
static int inst[sizeof(T)/sizeof(int) + 1] __attribute__((aligned(ALIGN)));
/* execute constructor on first call */
if (!initialized) {
initialized = true;
new (&inst) T(args...);
}
return reinterpret_cast<T *>(inst);
}
#endif /* _SINGLETON_H_ */

@ -31,8 +31,10 @@
#include <timer.h>
#include <pic.h>
/* base includes */
#include <unmanaged_singleton.h>
/* base-hw includes */
#include <singleton.h>
#include <kernel/perf_counter.h>
using namespace Kernel;
@ -47,7 +49,7 @@ namespace Kernel
/**
* Return interrupt-controller singleton
*/
Pic * pic() { return unsynchronized_singleton<Pic>(); }
Pic * pic() { return unmanaged_singleton<Pic>(); }
/* import Genode types */
typedef Genode::umword_t umword_t;
@ -64,15 +66,15 @@ namespace Kernel
*/
static void idle_main() { while (1) ; }
Pd_ids * pd_ids() { return unsynchronized_singleton<Pd_ids>(); }
Thread_ids * thread_ids() { return unsynchronized_singleton<Thread_ids>(); }
Signal_context_ids * signal_context_ids() { return unsynchronized_singleton<Signal_context_ids>(); }
Signal_receiver_ids * signal_receiver_ids() { return unsynchronized_singleton<Signal_receiver_ids>(); }
Pd_ids * pd_ids() { return unmanaged_singleton<Pd_ids>(); }
Thread_ids * thread_ids() { return unmanaged_singleton<Thread_ids>(); }
Signal_context_ids * signal_context_ids() { return unmanaged_singleton<Signal_context_ids>(); }
Signal_receiver_ids * signal_receiver_ids() { return unmanaged_singleton<Signal_receiver_ids>(); }
Pd_pool * pd_pool() { return unsynchronized_singleton<Pd_pool>(); }
Thread_pool * thread_pool() { return unsynchronized_singleton<Thread_pool>(); }
Signal_context_pool * signal_context_pool() { return unsynchronized_singleton<Signal_context_pool>(); }
Signal_receiver_pool * signal_receiver_pool() { return unsynchronized_singleton<Signal_receiver_pool>(); }
Pd_pool * pd_pool() { return unmanaged_singleton<Pd_pool>(); }
Thread_pool * thread_pool() { return unmanaged_singleton<Thread_pool>(); }
Signal_context_pool * signal_context_pool() { return unmanaged_singleton<Signal_context_pool>(); }
Signal_receiver_pool * signal_receiver_pool() { return unmanaged_singleton<Signal_receiver_pool>(); }
/**
* Access to static kernel timer
@ -92,9 +94,8 @@ namespace Kernel
static Pd * core()
{
constexpr int tlb_align = 1 << Core_tlb::ALIGNM_LOG2;
Core_tlb *core_tlb = unsynchronized_singleton<Core_tlb, tlb_align>();
Pd *pd = unsynchronized_singleton<Pd>(core_tlb, nullptr);
Core_tlb *core_tlb = unmanaged_singleton<Core_tlb, tlb_align>();
Pd *pd = unmanaged_singleton<Pd>(core_tlb, nullptr);
return pd;
}
@ -262,8 +263,8 @@ Kernel::Mode_transition_control * Kernel::mtc()
sp = (addr_t)&_kernel_stack_high;
core()->admit(this);
}
} * const k = unsynchronized_singleton<Kernel_context>();
} * const k = unmanaged_singleton<Kernel_context>();
/* initialize mode transition page */
return unsynchronized_singleton<Mode_transition_control>(k);
return unmanaged_singleton<Mode_transition_control>(k);
}

@ -21,9 +21,6 @@
/* core includes */
#include <assert.h>
/* base-hw includes */
#include <singleton.h>
namespace Kernel
{
template <typename T> class Avl_tree : public Genode::Avl_tree<T> { };

@ -16,6 +16,6 @@
namespace Kernel
{
Vm_ids * vm_ids() { return unsynchronized_singleton<Vm_ids>(); }
Vm_pool * vm_pool() { return unsynchronized_singleton<Vm_pool>(); }
Vm_ids * vm_ids() { return unmanaged_singleton<Vm_ids>(); }
Vm_pool * vm_pool() { return unmanaged_singleton<Vm_pool>(); }
}

@ -22,7 +22,8 @@ INC_DIR += $(REP_DIR)/src/core \
$(BASE_DIR)/src/core/include \
$(BASE_DIR)/include \
$(BASE_DIR)/src/platform \
$(BASE_DIR)/src/base/thread
$(BASE_DIR)/src/base/thread \
$(BASE_DIR)/src/base/include
# add C++ sources
SRC_CC += console.cc \