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
|
namespace Genode
|
||||||
{
|
{
|
||||||
class Native_utcb;
|
class Native_utcb;
|
||||||
class Platform_thread;
|
|
||||||
class Platform_pd;
|
class Platform_pd;
|
||||||
class Tlb;
|
class Tlb;
|
||||||
}
|
}
|
||||||
|
@ -30,7 +29,6 @@ namespace Kernel
|
||||||
typedef Genode::Tlb Tlb;
|
typedef Genode::Tlb Tlb;
|
||||||
typedef Genode::addr_t addr_t;
|
typedef Genode::addr_t addr_t;
|
||||||
typedef Genode::size_t size_t;
|
typedef Genode::size_t size_t;
|
||||||
typedef Genode::Platform_thread Platform_thread;
|
|
||||||
typedef Genode::Platform_pd Platform_pd;
|
typedef Genode::Platform_pd Platform_pd;
|
||||||
typedef Genode::Native_utcb Native_utcb;
|
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
|
* \param p memory donation for the new kernel thread object
|
||||||
* that is thereupon allocated to the kernel
|
* \param priority scheduling priority of the new thread
|
||||||
* \param pt assigned platform thread
|
* \param label debugging label of the new thread
|
||||||
*
|
*
|
||||||
* \retval >0 ID of the new thread
|
* \retval >0 kernel name of the new thread
|
||||||
* \retval 0 if no new thread was created
|
* \retval 0 failed
|
||||||
*
|
*
|
||||||
* Restricted to core threads. Regaining of the supplied memory can be done
|
* Restricted to core threads.
|
||||||
* through 'delete_thread'.
|
|
||||||
*/
|
*/
|
||||||
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
|
class Platform_thread
|
||||||
{
|
{
|
||||||
enum { NAME_MAX_LEN = 32 };
|
enum { LABEL_MAX_LEN = 32 };
|
||||||
|
|
||||||
Thread_base * _thread_base;
|
Thread_base * _thread_base;
|
||||||
size_t _stack_size;
|
size_t _stack_size;
|
||||||
|
@ -52,9 +52,8 @@ namespace Genode {
|
||||||
Native_utcb * _utcb_virt;
|
Native_utcb * _utcb_virt;
|
||||||
Tlb * _tlb;
|
Tlb * _tlb;
|
||||||
Ram_dataspace_capability _utcb;
|
Ram_dataspace_capability _utcb;
|
||||||
char _name[NAME_MAX_LEN];
|
char _label[LABEL_MAX_LEN];
|
||||||
char _kernel_thread[sizeof(Kernel::Thread)];
|
char _kernel_thread[sizeof(Kernel::Thread)];
|
||||||
unsigned _priority;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wether this thread is the main thread of a program.
|
* Wether this thread is the main thread of a program.
|
||||||
|
@ -80,14 +79,24 @@ namespace Genode {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for core threads
|
* 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);
|
size_t const stack_size, unsigned const pd_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for threads outside of core
|
* 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);
|
addr_t const utcb);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -96,13 +105,14 @@ namespace Genode {
|
||||||
~Platform_thread();
|
~Platform_thread();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Join PD identified by 'pd_id'
|
* Join a protection domain
|
||||||
*
|
*
|
||||||
* \param pd_id ID of targeted PD
|
* \param pd_id kernel name of targeted protection domain
|
||||||
* \param main_thread wether we are the main thread in this PD
|
* \param main_thread wether thread is the first in protection domain
|
||||||
|
* \param address_space corresponding Genode address space
|
||||||
*
|
*
|
||||||
* \retval 0 on success
|
* \retval 0 succeeded
|
||||||
* \retval <0 otherwise
|
* \retval -1 failed
|
||||||
*/
|
*/
|
||||||
int join_pd(unsigned const pd_id, bool const main_thread,
|
int join_pd(unsigned const pd_id, bool const main_thread,
|
||||||
Weak_ptr<Address_space> address_space);
|
Weak_ptr<Address_space> address_space);
|
||||||
|
@ -166,8 +176,6 @@ namespace Genode {
|
||||||
** Accessors **
|
** Accessors **
|
||||||
***************/
|
***************/
|
||||||
|
|
||||||
inline char const * name() const { return _name; }
|
|
||||||
|
|
||||||
void pager(Pager_object * const pager);
|
void pager(Pager_object * const pager);
|
||||||
|
|
||||||
Pager_object * pager();
|
Pager_object * pager();
|
||||||
|
@ -180,7 +188,7 @@ namespace Genode {
|
||||||
|
|
||||||
Thread_base * thread_base()
|
Thread_base * thread_base()
|
||||||
{
|
{
|
||||||
if (!_thread_base && !main_thread()) {
|
if (!_thread_base && !_main_thread) {
|
||||||
PERR("invalid thread base");
|
PERR("invalid thread base");
|
||||||
}
|
}
|
||||||
return _thread_base;
|
return _thread_base;
|
||||||
|
@ -188,15 +196,9 @@ namespace Genode {
|
||||||
|
|
||||||
Native_utcb * utcb_phys() const { return _utcb_phys; }
|
Native_utcb * utcb_phys() const { return _utcb_phys; }
|
||||||
|
|
||||||
Native_utcb * utcb_virt() const { return _utcb_virt; }
|
|
||||||
|
|
||||||
Ram_dataspace_capability utcb() const { return _utcb; }
|
Ram_dataspace_capability utcb() const { return _utcb; }
|
||||||
|
|
||||||
bool main_thread() const { return _main_thread; }
|
|
||||||
|
|
||||||
Tlb * tlb() const { return _tlb; }
|
Tlb * tlb() const { return _tlb; }
|
||||||
|
|
||||||
unsigned priority() { return _priority; }
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -115,7 +115,7 @@ namespace Kernel
|
||||||
/* create idle thread */
|
/* create idle thread */
|
||||||
static char idle_stack[DEFAULT_STACK_SIZE]
|
static char idle_stack[DEFAULT_STACK_SIZE]
|
||||||
__attribute__((aligned(Cpu::DATA_ACCESS_ALIGNM)));
|
__attribute__((aligned(Cpu::DATA_ACCESS_ALIGNM)));
|
||||||
static Thread idle((Platform_thread *)0);
|
static Thread idle(Priority::MAX, "idle");
|
||||||
static bool init = 0;
|
static bool init = 0;
|
||||||
if (!init) {
|
if (!init) {
|
||||||
enum { STACK_SIZE = sizeof(idle_stack)/sizeof(idle_stack[0]) };
|
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 */
|
/* start thread with stack pointer at the top of stack */
|
||||||
static Native_utcb utcb;
|
static Native_utcb utcb;
|
||||||
_main_utcb = &utcb;
|
_main_utcb = &utcb;
|
||||||
static Thread t((Platform_thread *)0);
|
static Thread t(Priority::MAX, "core");
|
||||||
t.ip = (addr_t)CORE_MAIN;;
|
t.ip = (addr_t)CORE_MAIN;;
|
||||||
t.sp = (addr_t)s + STACK_SIZE;
|
t.sp = (addr_t)s + STACK_SIZE;
|
||||||
t.init(0, core_id(), &utcb, 1);
|
t.init(0, core_id(), &utcb, 1);
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include <kernel/kernel.h>
|
#include <kernel/kernel.h>
|
||||||
#include <kernel/thread.h>
|
#include <kernel/thread.h>
|
||||||
#include <kernel/vm.h>
|
#include <kernel/vm.h>
|
||||||
#include <platform_thread.h>
|
|
||||||
#include <platform_pd.h>
|
#include <platform_pd.h>
|
||||||
|
|
||||||
using namespace Kernel;
|
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),
|
Thread_cpu_support(this),
|
||||||
_platform_thread(pt),
|
|
||||||
_state(AWAITS_START),
|
_state(AWAITS_START),
|
||||||
_pd(0),
|
_pd(0),
|
||||||
_utcb_phys(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
|
char const * Kernel::Thread::pd_label() const
|
||||||
{
|
{
|
||||||
if (_core()) { return "core"; }
|
if (_core()) { return "core"; }
|
||||||
|
@ -335,18 +324,17 @@ void Thread::_call_kill_pd()
|
||||||
void Thread::_call_new_thread()
|
void Thread::_call_new_thread()
|
||||||
{
|
{
|
||||||
/* check permissions */
|
/* check permissions */
|
||||||
assert(_core());
|
if (!_core()) {
|
||||||
|
PERR("not entitled to create thread");
|
||||||
/* dispatch arguments */
|
user_arg_0(0);
|
||||||
Call_arg const arg1 = user_arg_1();
|
return;
|
||||||
Call_arg const arg2 = user_arg_2();
|
}
|
||||||
|
/* create new thread */
|
||||||
/* create thread */
|
void * const p = (void *)user_arg_1();
|
||||||
Thread * const t = new ((void *)arg1)
|
unsigned const priority = user_arg_2();
|
||||||
Thread((Platform_thread *)arg2);
|
char const * const label = (char *)user_arg_3();
|
||||||
|
Thread * const t = new (p) Thread(priority, label);
|
||||||
/* return thread ID */
|
user_arg_0(t->id());
|
||||||
user_arg_0((Call_ret)t->id());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -22,11 +22,6 @@
|
||||||
#include <cpu_support.h>
|
#include <cpu_support.h>
|
||||||
#include <cpu.h>
|
#include <cpu.h>
|
||||||
|
|
||||||
namespace Genode
|
|
||||||
{
|
|
||||||
class Platform_thread;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
{
|
{
|
||||||
class Thread;
|
class Thread;
|
||||||
|
@ -78,11 +73,11 @@ class Kernel::Thread
|
||||||
STOPPED = 8,
|
STOPPED = 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
Platform_thread * const _platform_thread;
|
State _state;
|
||||||
State _state;
|
Pd * _pd;
|
||||||
Pd * _pd;
|
Native_utcb * _utcb_phys;
|
||||||
Native_utcb * _utcb_phys;
|
Signal_receiver * _signal_receiver;
|
||||||
Signal_receiver * _signal_receiver;
|
char const * const _label;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notice that another thread yielded the CPU to this thread
|
* Notice that another thread yielded the CPU to this thread
|
||||||
|
@ -255,9 +250,10 @@ class Kernel::Thread
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* 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
|
* Prepare thread to get scheduled the first time
|
||||||
|
@ -283,11 +279,10 @@ class Kernel::Thread
|
||||||
** Accessors **
|
** Accessors **
|
||||||
***************/
|
***************/
|
||||||
|
|
||||||
Platform_thread * platform_thread() const { return _platform_thread; }
|
unsigned id() const { return Object::id(); }
|
||||||
unsigned id() const { return Object::id(); }
|
char const * label() const { return _label; };
|
||||||
char const * label() const;
|
unsigned pd_id() const;
|
||||||
unsigned pd_id() const;
|
char const * pd_label() const;
|
||||||
char const * pd_label() const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _KERNEL__THREAD_H_ */
|
#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
|
* virtual context area by itself, as it is done for other threads
|
||||||
* through a sub RM-session.
|
* 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 */
|
/* the RM client may be destructed before platform thread */
|
||||||
if (_rm_client) {
|
if (_rm_client) {
|
||||||
Rm_session_component * const rm = _rm_client->member_rm_session();
|
Rm_session_component * const rm = _rm_client->member_rm_session();
|
||||||
rm->detach(utcb_virt());
|
rm->detach(_utcb_virt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* free UTCB */
|
/* free UTCB */
|
||||||
if (_pd_id == Kernel::core_id()) {
|
if (_pd_id == Kernel::core_id()) {
|
||||||
Range_allocator * const ram = platform()->ram_alloc();
|
Range_allocator * const ram = platform()->ram_alloc();
|
||||||
ram->free(utcb_phys(), sizeof(Native_utcb));
|
ram->free(_utcb_phys, sizeof(Native_utcb));
|
||||||
} else {
|
} else {
|
||||||
Ram_session_component * const ram =
|
Ram_session_component * const ram =
|
||||||
dynamic_cast<Ram_session_component *>(core_env()->ram_session());
|
dynamic_cast<Ram_session_component *>(core_env()->ram_session());
|
||||||
|
@ -72,16 +72,19 @@ Platform_thread::~Platform_thread()
|
||||||
Kernel::delete_thread(_id);
|
Kernel::delete_thread(_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
Platform_thread::Platform_thread(const char * name,
|
|
||||||
|
Platform_thread::Platform_thread(const char * const label,
|
||||||
Thread_base * const thread_base,
|
Thread_base * const thread_base,
|
||||||
size_t const stack_size, unsigned const pd_id)
|
size_t const stack_size, unsigned const pd_id)
|
||||||
:
|
:
|
||||||
_thread_base(thread_base), _stack_size(stack_size),
|
_thread_base(thread_base),
|
||||||
_pd_id(pd_id), _rm_client(0), _utcb_virt(0),
|
_stack_size(stack_size),
|
||||||
_priority(Kernel::Priority::MAX),
|
_pd_id(pd_id),
|
||||||
|
_rm_client(0),
|
||||||
|
_utcb_virt(0),
|
||||||
_main_thread(0)
|
_main_thread(0)
|
||||||
{
|
{
|
||||||
strncpy(_name, name, NAME_MAX_LEN);
|
strncpy(_label, label, LABEL_MAX_LEN);
|
||||||
|
|
||||||
/* create UTCB for a core thread */
|
/* create UTCB for a core thread */
|
||||||
Range_allocator * const ram = platform()->ram_alloc();
|
Range_allocator * const ram = platform()->ram_alloc();
|
||||||
|
@ -93,20 +96,27 @@ Platform_thread::Platform_thread(const char * name,
|
||||||
}
|
}
|
||||||
_utcb_virt = _utcb_phys;
|
_utcb_virt = _utcb_phys;
|
||||||
|
|
||||||
/* common constructor parts */
|
/* create kernel object */
|
||||||
_init();
|
_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,
|
Platform_thread::Platform_thread(const char * const label,
|
||||||
addr_t utcb)
|
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),
|
_utcb_virt((Native_utcb *)utcb),
|
||||||
_priority(Cpu_session::scale_priority(Kernel::Priority::MAX, priority)),
|
|
||||||
_main_thread(0)
|
_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
|
* 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);
|
_utcb_phys = (Native_utcb *)ram->phys_addr(_utcb);
|
||||||
|
|
||||||
/* common constructor parts */
|
/* create kernel object */
|
||||||
_init();
|
_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,
|
int Platform_thread::join_pd(unsigned const pd_id, bool const main_thread,
|
||||||
Weak_ptr<Address_space> address_space)
|
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) {
|
if (_pd_id && _pd_id != pd_id) {
|
||||||
PERR("already joined a PD");
|
PERR("thread already in another protection domain");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/* denote configuration for start method */
|
/* join protection domain */
|
||||||
_pd_id = pd_id;
|
_pd_id = pd_id;
|
||||||
_main_thread = main_thread;
|
_main_thread = main_thread;
|
||||||
_address_space = address_space;
|
_address_space = address_space;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -146,12 +160,6 @@ int Platform_thread::join_pd(unsigned const pd_id, bool const main_thread,
|
||||||
|
|
||||||
void Platform_thread::_init()
|
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;
|
write_regs[1] = Reg_id::SP;
|
||||||
addr_t write_values[] = {
|
addr_t write_values[] = {
|
||||||
(addr_t)ip,
|
(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)) {
|
if (Kernel::access_thread_regs(id(), 0, WRITES, 0, write_values)) {
|
||||||
PERR("failed to initialize thread registers");
|
PERR("failed to initialize thread registers");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/* let thread participate in CPU scheduling */
|
/* 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) {
|
if (!_tlb) {
|
||||||
PERR("failed to start thread");
|
PERR("failed to start thread");
|
||||||
return -1;
|
return -1;
|
||||||
|
|
Loading…
Reference in New Issue