base-hw: kernel-data lock as Main member

Let the global kernel-data lock be a member of the one Kernel::Main object
instead of having it as global static variable.

Ref #4217
This commit is contained in:
Martin Stein 2021-07-08 01:32:13 +02:00 committed by Norman Feske
parent 82cf31ac27
commit be3d5232c8
4 changed files with 31 additions and 42 deletions

View File

@ -11,19 +11,13 @@
* under the terms of the GNU Affero General Public License version 3. * under the terms of the GNU Affero General Public License version 3.
*/ */
#include <base/lock_guard.h> /* Genode includes */
#include <cpu/atomic.h> #include <cpu/atomic.h>
#include <cpu/memory_barrier.h> #include <cpu/memory_barrier.h>
/* base-hw Core includes */
#include <kernel/cpu.h> #include <kernel/cpu.h>
#include <kernel/lock.h> #include <kernel/lock.h>
#include <kernel/kernel.h>
Kernel::Lock & Kernel::data_lock()
{
static Kernel::Lock lock;
return lock;
}
void Kernel::Lock::lock() void Kernel::Lock::lock()

View File

@ -15,12 +15,10 @@
#ifndef _CORE__SPEC__SMP__KERNEL__LOCK_H_ #ifndef _CORE__SPEC__SMP__KERNEL__LOCK_H_
#define _CORE__SPEC__SMP__KERNEL__LOCK_H_ #define _CORE__SPEC__SMP__KERNEL__LOCK_H_
namespace Kernel { /* Genode includes */
#include <base/lock_guard.h>
class Lock; namespace Kernel { class Lock; }
Lock & data_lock();
}
class Kernel::Lock class Kernel::Lock

View File

@ -36,6 +36,8 @@ class Kernel::Main
static Main *_instance; static Main *_instance;
Lock _data_lock { };
void _handle_kernel_entry(); void _handle_kernel_entry();
}; };
@ -49,7 +51,7 @@ void Kernel::Main::_handle_kernel_entry()
Cpu_job * new_job; Cpu_job * new_job;
{ {
Lock::Guard guard(data_lock()); Lock::Guard guard(_data_lock);
new_job = &cpu.schedule(); new_job = &cpu.schedule();
} }
@ -66,32 +68,34 @@ void Kernel::main_handle_kernel_entry()
void Kernel::main_initialize_and_handle_kernel_entry() void Kernel::main_initialize_and_handle_kernel_entry()
{ {
static volatile bool lock_ready = false; static volatile bool instance_initialized = false;
static volatile bool pool_ready = false; static volatile bool pool_ready = false;
static volatile bool kernel_ready = false; static volatile bool kernel_ready = false;
/** bool const primary_cpu { Cpu::executing_id() == Cpu::primary_id() };
* 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) { }
/** if (primary_cpu) {
* Create a main object and initialize static reference to it
*/
if (Cpu::executing_id() == Cpu::primary_id()) {
/**
* Let the primary CPU create a Main object and initialize the static
* reference to it.
*/
static Main instance { }; static Main instance { };
Main::_instance = &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 */ /* initialize current cpu */
pool_ready = cpu_pool().initialize(); pool_ready = cpu_pool().initialize();
@ -101,8 +105,8 @@ void Kernel::main_initialize_and_handle_kernel_entry()
while (!pool_ready) { ; } while (!pool_ready) { ; }
/* the boot-cpu initializes the rest of the kernel */ /* the boot-cpu initializes the rest of the kernel */
if (Cpu::executing_id() == Cpu::primary_id()) { if (primary_cpu) {
Lock::Guard guard(data_lock()); Lock::Guard guard(Main::_instance->_data_lock);
using Boot_info = Hw::Boot_info<Board::Boot_info>; using Boot_info = Hw::Boot_info<Board::Boot_info>;
Boot_info &boot_info { Boot_info &boot_info {

View File

@ -11,20 +11,13 @@
* under the terms of the GNU Affero General Public License version 3. * under the terms of the GNU Affero General Public License version 3.
*/ */
#include <base/lock_guard.h> /* Genode includes */
#include <cpu/atomic.h> #include <cpu/atomic.h>
#include <cpu/memory_barrier.h> #include <cpu/memory_barrier.h>
/* base-hw Core includes */
#include <kernel/cpu.h> #include <kernel/cpu.h>
#include <kernel/lock.h> #include <kernel/lock.h>
#include <kernel/kernel.h>
Kernel::Lock & Kernel::data_lock()
{
static Kernel::Lock lock;
return lock;
}
void Kernel::Lock::lock() void Kernel::Lock::lock()