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.
*/
#include <base/lock_guard.h>
/* Genode includes */
#include <cpu/atomic.h>
#include <cpu/memory_barrier.h>
/* base-hw Core includes */
#include <kernel/cpu.h>
#include <kernel/lock.h>
#include <kernel/kernel.h>
Kernel::Lock & Kernel::data_lock()
{
static Kernel::Lock lock;
return lock;
}
void Kernel::Lock::lock()

View File

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

View File

@ -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 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() };
if (primary_cpu) {
/**
* Create a main object and initialize static reference to it
* Let the primary CPU create a Main object and initialize the static
* reference to it.
*/
if (Cpu::executing_id() == Cpu::primary_id()) {
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<Board::Boot_info>;
Boot_info &boot_info {

View File

@ -11,20 +11,13 @@
* 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/memory_barrier.h>
/* base-hw Core includes */
#include <kernel/cpu.h>
#include <kernel/lock.h>
#include <kernel/kernel.h>
Kernel::Lock & Kernel::data_lock()
{
static Kernel::Lock lock;
return lock;
}
void Kernel::Lock::lock()