diff --git a/repos/base-hw/src/core/kernel/lock.cc b/repos/base-hw/src/core/kernel/lock.cc
index 00a85a6582..21ed98b44d 100644
--- a/repos/base-hw/src/core/kernel/lock.cc
+++ b/repos/base-hw/src/core/kernel/lock.cc
@@ -11,19 +11,13 @@
* under the terms of the GNU Affero General Public License version 3.
*/
-#include
+/* Genode includes */
#include
#include
+/* base-hw Core includes */
#include
#include
-#include
-
-Kernel::Lock & Kernel::data_lock()
-{
- static Kernel::Lock lock;
- return lock;
-}
void Kernel::Lock::lock()
diff --git a/repos/base-hw/src/core/kernel/lock.h b/repos/base-hw/src/core/kernel/lock.h
index 6c7c5c9fb6..1befd37bac 100644
--- a/repos/base-hw/src/core/kernel/lock.h
+++ b/repos/base-hw/src/core/kernel/lock.h
@@ -15,12 +15,10 @@
#ifndef _CORE__SPEC__SMP__KERNEL__LOCK_H_
#define _CORE__SPEC__SMP__KERNEL__LOCK_H_
-namespace Kernel {
+/* Genode includes */
+#include
- class Lock;
-
- Lock & data_lock();
-}
+namespace Kernel { class Lock; }
class Kernel::Lock
diff --git a/repos/base-hw/src/core/kernel/main.cc b/repos/base-hw/src/core/kernel/main.cc
index 253e066e9f..99f3e7d66c 100644
--- a/repos/base-hw/src/core/kernel/main.cc
+++ b/repos/base-hw/src/core/kernel/main.cc
@@ -36,6 +36,8 @@ class Kernel::Main
static Main *_instance;
+ Lock _data_lock { };
+
void _handle_kernel_entry();
};
@@ -49,7 +51,7 @@ void Kernel::Main::_handle_kernel_entry()
Cpu_job * new_job;
{
- Lock::Guard guard(data_lock());
+ Lock::Guard guard(_data_lock);
new_job = &cpu.schedule();
}
@@ -66,32 +68,34 @@ void Kernel::main_handle_kernel_entry()
void Kernel::main_initialize_and_handle_kernel_entry()
{
- static volatile bool lock_ready = false;
- static volatile bool pool_ready = false;
- static volatile bool kernel_ready = false;
+ static volatile bool instance_initialized = false;
+ static volatile bool pool_ready = false;
+ static volatile bool kernel_ready = false;
- /**
- * It is essential to guard the initialization of the data_lock object
- * in the SMP case, because otherwise the __cxa_guard_aquire of the cxx
- * library contention path might get called, which ends up in
- * calling a Semaphore, which will call Kernel::stop_thread() or
- * Kernel::yield() system-calls in this code
- */
- while (Cpu::executing_id() != Cpu::primary_id() && !lock_ready) { }
+ bool const primary_cpu { Cpu::executing_id() == Cpu::primary_id() };
- /**
- * Create a main object and initialize static reference to it
- */
- if (Cpu::executing_id() == Cpu::primary_id()) {
+ if (primary_cpu) {
+ /**
+ * Let the primary CPU create a Main object and initialize the static
+ * reference to it.
+ */
static Main instance { };
Main::_instance = &instance;
+
+ } else {
+
+ /**
+ * Let secondary CPUs block until the primary CPU has managed to set
+ * up the Main instance.
+ */
+ while (!instance_initialized) { }
}
{
- Lock::Guard guard(data_lock());
+ Lock::Guard guard(Main::_instance->_data_lock);
- lock_ready = true;
+ instance_initialized = true;
/* initialize current cpu */
pool_ready = cpu_pool().initialize();
@@ -101,8 +105,8 @@ void Kernel::main_initialize_and_handle_kernel_entry()
while (!pool_ready) { ; }
/* the boot-cpu initializes the rest of the kernel */
- if (Cpu::executing_id() == Cpu::primary_id()) {
- Lock::Guard guard(data_lock());
+ if (primary_cpu) {
+ Lock::Guard guard(Main::_instance->_data_lock);
using Boot_info = Hw::Boot_info;
Boot_info &boot_info {
diff --git a/repos/base-hw/src/core/spec/arm/kernel/lock.cc b/repos/base-hw/src/core/spec/arm/kernel/lock.cc
index ae59d9ba36..f017b7e93d 100644
--- a/repos/base-hw/src/core/spec/arm/kernel/lock.cc
+++ b/repos/base-hw/src/core/spec/arm/kernel/lock.cc
@@ -11,20 +11,13 @@
* under the terms of the GNU Affero General Public License version 3.
*/
-#include
+/* Genode includes */
#include
#include
+/* base-hw Core includes */
#include
#include
-#include
-
-
-Kernel::Lock & Kernel::data_lock()
-{
- static Kernel::Lock lock;
- return lock;
-}
void Kernel::Lock::lock()