mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-07 19:34:56 +00:00
hw: simplify Kernel::new_thread
Don't set priority and label in platform thread and then communicate this core object via Kernel::new_thread but communicate priority and label directly. This way kernel doesn't need to know anymore what a platform thread is. ref #953
This commit is contained in:
parent
210216e5e1
commit
99c649c42f
@ -20,7 +20,6 @@
|
||||
namespace Genode
|
||||
{
|
||||
class Native_utcb;
|
||||
class Platform_thread;
|
||||
class Platform_pd;
|
||||
class Tlb;
|
||||
}
|
||||
@ -30,7 +29,6 @@ namespace Kernel
|
||||
typedef Genode::Tlb Tlb;
|
||||
typedef Genode::addr_t addr_t;
|
||||
typedef Genode::size_t size_t;
|
||||
typedef Genode::Platform_thread Platform_thread;
|
||||
typedef Genode::Platform_pd Platform_pd;
|
||||
typedef Genode::Native_utcb Native_utcb;
|
||||
|
||||
@ -200,21 +198,22 @@ namespace Kernel
|
||||
|
||||
|
||||
/**
|
||||
* Create a new thread that is stopped initially
|
||||
* Create kernel object that acts as thread that isn't executed initially
|
||||
*
|
||||
* \param dst physical base of an appropriate portion of memory
|
||||
* that is thereupon allocated to the kernel
|
||||
* \param pt assigned platform thread
|
||||
* \param p memory donation for the new kernel thread object
|
||||
* \param priority scheduling priority of the new thread
|
||||
* \param label debugging label of the new thread
|
||||
*
|
||||
* \retval >0 ID of the new thread
|
||||
* \retval 0 if no new thread was created
|
||||
* \retval >0 kernel name of the new thread
|
||||
* \retval 0 failed
|
||||
*
|
||||
* Restricted to core threads. Regaining of the supplied memory can be done
|
||||
* through 'delete_thread'.
|
||||
* Restricted to core threads.
|
||||
*/
|
||||
inline int new_thread(void * const dst, Platform_thread * const pt)
|
||||
inline int new_thread(void * const p, unsigned const priority,
|
||||
char const * const label)
|
||||
{
|
||||
return call(Call_id::NEW_THREAD, (Call_arg)dst, (Call_arg)pt);
|
||||
return call((Call_arg)Call_id::NEW_THREAD, (Call_arg)p, (Call_arg)priority,
|
||||
(Call_arg)label);
|
||||
}
|
||||
|
||||
|
||||
|
@ -40,7 +40,7 @@ namespace Genode {
|
||||
*/
|
||||
class Platform_thread
|
||||
{
|
||||
enum { NAME_MAX_LEN = 32 };
|
||||
enum { LABEL_MAX_LEN = 32 };
|
||||
|
||||
Thread_base * _thread_base;
|
||||
size_t _stack_size;
|
||||
@ -52,9 +52,8 @@ namespace Genode {
|
||||
Native_utcb * _utcb_virt;
|
||||
Tlb * _tlb;
|
||||
Ram_dataspace_capability _utcb;
|
||||
char _name[NAME_MAX_LEN];
|
||||
char _label[LABEL_MAX_LEN];
|
||||
char _kernel_thread[sizeof(Kernel::Thread)];
|
||||
unsigned _priority;
|
||||
|
||||
/*
|
||||
* Wether this thread is the main thread of a program.
|
||||
@ -80,14 +79,24 @@ namespace Genode {
|
||||
|
||||
/**
|
||||
* Constructor for core threads
|
||||
*
|
||||
* \param label debugging label
|
||||
* \param thread_base Genode thread object
|
||||
* \param stack_size initial size of the stack
|
||||
* \param pd_id kernel name of targeted protection domain
|
||||
*/
|
||||
Platform_thread(const char * name, Thread_base * const thread_base,
|
||||
Platform_thread(const char * const label,
|
||||
Thread_base * const thread_base,
|
||||
size_t const stack_size, unsigned const pd_id);
|
||||
|
||||
/**
|
||||
* Constructor for threads outside of core
|
||||
*
|
||||
* \param label debugging label
|
||||
* \param priority processor-scheduling priority
|
||||
* \param utcb core local pointer to userland thread-context
|
||||
*/
|
||||
Platform_thread(const char * name, unsigned const priority,
|
||||
Platform_thread(const char * const label, unsigned const priority,
|
||||
addr_t const utcb);
|
||||
|
||||
/**
|
||||
@ -96,13 +105,14 @@ namespace Genode {
|
||||
~Platform_thread();
|
||||
|
||||
/**
|
||||
* Join PD identified by 'pd_id'
|
||||
* Join a protection domain
|
||||
*
|
||||
* \param pd_id ID of targeted PD
|
||||
* \param main_thread wether we are the main thread in this PD
|
||||
* \param pd_id kernel name of targeted protection domain
|
||||
* \param main_thread wether thread is the first in protection domain
|
||||
* \param address_space corresponding Genode address space
|
||||
*
|
||||
* \retval 0 on success
|
||||
* \retval <0 otherwise
|
||||
* \retval 0 succeeded
|
||||
* \retval -1 failed
|
||||
*/
|
||||
int join_pd(unsigned const pd_id, bool const main_thread,
|
||||
Weak_ptr<Address_space> address_space);
|
||||
@ -166,8 +176,6 @@ namespace Genode {
|
||||
** Accessors **
|
||||
***************/
|
||||
|
||||
inline char const * name() const { return _name; }
|
||||
|
||||
void pager(Pager_object * const pager);
|
||||
|
||||
Pager_object * pager();
|
||||
@ -180,7 +188,7 @@ namespace Genode {
|
||||
|
||||
Thread_base * thread_base()
|
||||
{
|
||||
if (!_thread_base && !main_thread()) {
|
||||
if (!_thread_base && !_main_thread) {
|
||||
PERR("invalid thread base");
|
||||
}
|
||||
return _thread_base;
|
||||
@ -188,15 +196,9 @@ namespace Genode {
|
||||
|
||||
Native_utcb * utcb_phys() const { return _utcb_phys; }
|
||||
|
||||
Native_utcb * utcb_virt() const { return _utcb_virt; }
|
||||
|
||||
Ram_dataspace_capability utcb() const { return _utcb; }
|
||||
|
||||
bool main_thread() const { return _main_thread; }
|
||||
|
||||
Tlb * tlb() const { return _tlb; }
|
||||
|
||||
unsigned priority() { return _priority; }
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -115,7 +115,7 @@ namespace Kernel
|
||||
/* create idle thread */
|
||||
static char idle_stack[DEFAULT_STACK_SIZE]
|
||||
__attribute__((aligned(Cpu::DATA_ACCESS_ALIGNM)));
|
||||
static Thread idle((Platform_thread *)0);
|
||||
static Thread idle(Priority::MAX, "idle");
|
||||
static bool init = 0;
|
||||
if (!init) {
|
||||
enum { STACK_SIZE = sizeof(idle_stack)/sizeof(idle_stack[0]) };
|
||||
@ -233,7 +233,7 @@ extern "C" void kernel()
|
||||
/* start thread with stack pointer at the top of stack */
|
||||
static Native_utcb utcb;
|
||||
_main_utcb = &utcb;
|
||||
static Thread t((Platform_thread *)0);
|
||||
static Thread t(Priority::MAX, "core");
|
||||
t.ip = (addr_t)CORE_MAIN;;
|
||||
t.sp = (addr_t)s + STACK_SIZE;
|
||||
t.init(0, core_id(), &utcb, 1);
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include <kernel/kernel.h>
|
||||
#include <kernel/thread.h>
|
||||
#include <kernel/vm.h>
|
||||
#include <platform_thread.h>
|
||||
#include <platform_pd.h>
|
||||
|
||||
using namespace Kernel;
|
||||
@ -184,15 +183,15 @@ void Thread::_schedule()
|
||||
}
|
||||
|
||||
|
||||
Thread::Thread(Platform_thread * const pt)
|
||||
Thread::Thread(unsigned const priority, char const * const label)
|
||||
:
|
||||
Execution_context(pt ? pt->priority() : Priority::MAX),
|
||||
Execution_context(priority),
|
||||
Thread_cpu_support(this),
|
||||
_platform_thread(pt),
|
||||
_state(AWAITS_START),
|
||||
_pd(0),
|
||||
_utcb_phys(0),
|
||||
_signal_receiver(0)
|
||||
_signal_receiver(0),
|
||||
_label(label)
|
||||
{ }
|
||||
|
||||
|
||||
@ -270,16 +269,6 @@ void Thread::proceed()
|
||||
}
|
||||
|
||||
|
||||
char const * Kernel::Thread::label() const
|
||||
{
|
||||
if (!platform_thread()) {
|
||||
if (!_utcb_phys) { return "idle"; }
|
||||
return "core";
|
||||
}
|
||||
return platform_thread()->name();
|
||||
}
|
||||
|
||||
|
||||
char const * Kernel::Thread::pd_label() const
|
||||
{
|
||||
if (_core()) { return "core"; }
|
||||
@ -335,18 +324,17 @@ void Thread::_call_kill_pd()
|
||||
void Thread::_call_new_thread()
|
||||
{
|
||||
/* check permissions */
|
||||
assert(_core());
|
||||
|
||||
/* dispatch arguments */
|
||||
Call_arg const arg1 = user_arg_1();
|
||||
Call_arg const arg2 = user_arg_2();
|
||||
|
||||
/* create thread */
|
||||
Thread * const t = new ((void *)arg1)
|
||||
Thread((Platform_thread *)arg2);
|
||||
|
||||
/* return thread ID */
|
||||
user_arg_0((Call_ret)t->id());
|
||||
if (!_core()) {
|
||||
PERR("not entitled to create thread");
|
||||
user_arg_0(0);
|
||||
return;
|
||||
}
|
||||
/* create new thread */
|
||||
void * const p = (void *)user_arg_1();
|
||||
unsigned const priority = user_arg_2();
|
||||
char const * const label = (char *)user_arg_3();
|
||||
Thread * const t = new (p) Thread(priority, label);
|
||||
user_arg_0(t->id());
|
||||
}
|
||||
|
||||
|
||||
|
@ -22,11 +22,6 @@
|
||||
#include <cpu_support.h>
|
||||
#include <cpu.h>
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
class Platform_thread;
|
||||
}
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
class Thread;
|
||||
@ -78,11 +73,11 @@ class Kernel::Thread
|
||||
STOPPED = 8,
|
||||
};
|
||||
|
||||
Platform_thread * const _platform_thread;
|
||||
State _state;
|
||||
Pd * _pd;
|
||||
Native_utcb * _utcb_phys;
|
||||
Signal_receiver * _signal_receiver;
|
||||
State _state;
|
||||
Pd * _pd;
|
||||
Native_utcb * _utcb_phys;
|
||||
Signal_receiver * _signal_receiver;
|
||||
char const * const _label;
|
||||
|
||||
/**
|
||||
* Notice that another thread yielded the CPU to this thread
|
||||
@ -255,9 +250,10 @@ class Kernel::Thread
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param platform_thread corresponding userland object
|
||||
* \param priority scheduling priority
|
||||
* \param label debugging label
|
||||
*/
|
||||
Thread(Platform_thread * const platform_thread);
|
||||
Thread(unsigned const priority, char const * const label);
|
||||
|
||||
/**
|
||||
* Prepare thread to get scheduled the first time
|
||||
@ -283,11 +279,10 @@ class Kernel::Thread
|
||||
** Accessors **
|
||||
***************/
|
||||
|
||||
Platform_thread * platform_thread() const { return _platform_thread; }
|
||||
unsigned id() const { return Object::id(); }
|
||||
char const * label() const;
|
||||
unsigned pd_id() const;
|
||||
char const * pd_label() const;
|
||||
unsigned id() const { return Object::id(); }
|
||||
char const * label() const { return _label; };
|
||||
unsigned pd_id() const;
|
||||
char const * pd_label() const;
|
||||
};
|
||||
|
||||
#endif /* _KERNEL__THREAD_H_ */
|
||||
|
@ -28,7 +28,7 @@ bool Platform_thread::_attaches_utcb_by_itself()
|
||||
* virtual context area by itself, as it is done for other threads
|
||||
* through a sub RM-session.
|
||||
*/
|
||||
return _pd_id == Kernel::core_id() || !main_thread();
|
||||
return _pd_id == Kernel::core_id() || !_main_thread;
|
||||
}
|
||||
|
||||
|
||||
@ -46,13 +46,13 @@ Platform_thread::~Platform_thread()
|
||||
/* the RM client may be destructed before platform thread */
|
||||
if (_rm_client) {
|
||||
Rm_session_component * const rm = _rm_client->member_rm_session();
|
||||
rm->detach(utcb_virt());
|
||||
rm->detach(_utcb_virt);
|
||||
}
|
||||
}
|
||||
/* free UTCB */
|
||||
if (_pd_id == Kernel::core_id()) {
|
||||
Range_allocator * const ram = platform()->ram_alloc();
|
||||
ram->free(utcb_phys(), sizeof(Native_utcb));
|
||||
ram->free(_utcb_phys, sizeof(Native_utcb));
|
||||
} else {
|
||||
Ram_session_component * const ram =
|
||||
dynamic_cast<Ram_session_component *>(core_env()->ram_session());
|
||||
@ -72,16 +72,19 @@ Platform_thread::~Platform_thread()
|
||||
Kernel::delete_thread(_id);
|
||||
}
|
||||
|
||||
Platform_thread::Platform_thread(const char * name,
|
||||
|
||||
Platform_thread::Platform_thread(const char * const label,
|
||||
Thread_base * const thread_base,
|
||||
size_t const stack_size, unsigned const pd_id)
|
||||
:
|
||||
_thread_base(thread_base), _stack_size(stack_size),
|
||||
_pd_id(pd_id), _rm_client(0), _utcb_virt(0),
|
||||
_priority(Kernel::Priority::MAX),
|
||||
_thread_base(thread_base),
|
||||
_stack_size(stack_size),
|
||||
_pd_id(pd_id),
|
||||
_rm_client(0),
|
||||
_utcb_virt(0),
|
||||
_main_thread(0)
|
||||
{
|
||||
strncpy(_name, name, NAME_MAX_LEN);
|
||||
strncpy(_label, label, LABEL_MAX_LEN);
|
||||
|
||||
/* create UTCB for a core thread */
|
||||
Range_allocator * const ram = platform()->ram_alloc();
|
||||
@ -93,20 +96,27 @@ Platform_thread::Platform_thread(const char * name,
|
||||
}
|
||||
_utcb_virt = _utcb_phys;
|
||||
|
||||
/* common constructor parts */
|
||||
_init();
|
||||
/* create kernel object */
|
||||
_id = Kernel::new_thread(_kernel_thread, Kernel::Priority::MAX, _label);
|
||||
if (!_id) {
|
||||
PERR("failed to create kernel object");
|
||||
throw Cpu_session::Thread_creation_failed();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Platform_thread::Platform_thread(const char * name, unsigned int priority,
|
||||
addr_t utcb)
|
||||
Platform_thread::Platform_thread(const char * const label,
|
||||
unsigned const priority,
|
||||
addr_t const utcb)
|
||||
:
|
||||
_thread_base(0), _stack_size(0), _pd_id(0), _rm_client(0),
|
||||
_thread_base(0),
|
||||
_stack_size(0),
|
||||
_pd_id(0),
|
||||
_rm_client(0),
|
||||
_utcb_virt((Native_utcb *)utcb),
|
||||
_priority(Cpu_session::scale_priority(Kernel::Priority::MAX, priority)),
|
||||
_main_thread(0)
|
||||
{
|
||||
strncpy(_name, name, NAME_MAX_LEN);
|
||||
strncpy(_label, label, LABEL_MAX_LEN);
|
||||
|
||||
/*
|
||||
* Allocate UTCB backing store for a thread outside of core. Page alignment
|
||||
@ -123,22 +133,26 @@ Platform_thread::Platform_thread(const char * name, unsigned int priority,
|
||||
}
|
||||
_utcb_phys = (Native_utcb *)ram->phys_addr(_utcb);
|
||||
|
||||
/* common constructor parts */
|
||||
_init();
|
||||
/* create kernel object */
|
||||
_id = Kernel::new_thread(_kernel_thread, priority, _label);
|
||||
if (!_id) {
|
||||
PERR("failed to create kernel object");
|
||||
throw Cpu_session::Thread_creation_failed();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int Platform_thread::join_pd(unsigned const pd_id, bool const main_thread,
|
||||
Weak_ptr<Address_space> address_space)
|
||||
{
|
||||
/* check if we're already in another PD */
|
||||
/* check if thread is already in another protection domain */
|
||||
if (_pd_id && _pd_id != pd_id) {
|
||||
PERR("already joined a PD");
|
||||
PERR("thread already in another protection domain");
|
||||
return -1;
|
||||
}
|
||||
/* denote configuration for start method */
|
||||
_pd_id = pd_id;
|
||||
_main_thread = main_thread;
|
||||
/* join protection domain */
|
||||
_pd_id = pd_id;
|
||||
_main_thread = main_thread;
|
||||
_address_space = address_space;
|
||||
return 0;
|
||||
}
|
||||
@ -146,12 +160,6 @@ int Platform_thread::join_pd(unsigned const pd_id, bool const main_thread,
|
||||
|
||||
void Platform_thread::_init()
|
||||
{
|
||||
/* create kernel object */
|
||||
_id = Kernel::new_thread(_kernel_thread, this);
|
||||
if (!_id) {
|
||||
PERR("failed to create kernel object");
|
||||
throw Cpu_session::Thread_creation_failed();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -186,14 +194,14 @@ int Platform_thread::start(void * const ip, void * const sp,
|
||||
write_regs[1] = Reg_id::SP;
|
||||
addr_t write_values[] = {
|
||||
(addr_t)ip,
|
||||
main_thread() ? (addr_t)_utcb_virt : (addr_t)sp
|
||||
_main_thread ? (addr_t)_utcb_virt : (addr_t)sp
|
||||
};
|
||||
if (Kernel::access_thread_regs(id(), 0, WRITES, 0, write_values)) {
|
||||
PERR("failed to initialize thread registers");
|
||||
return -1;
|
||||
}
|
||||
/* let thread participate in CPU scheduling */
|
||||
_tlb = Kernel::start_thread(id(), cpu_id, _pd_id, utcb_phys());
|
||||
_tlb = Kernel::start_thread(id(), cpu_id, _pd_id, _utcb_phys);
|
||||
if (!_tlb) {
|
||||
PERR("failed to start thread");
|
||||
return -1;
|
||||
|
Loading…
x
Reference in New Issue
Block a user