nova: unify code for normal and server threads

This commit is contained in:
Alexander Boettcher 2013-07-22 09:14:40 +02:00 committed by Norman Feske
parent 5fe29e8e4a
commit f1af8e371d
2 changed files with 24 additions and 59 deletions

View File

@ -206,68 +206,23 @@ Rpc_entrypoint::Rpc_entrypoint(Cap_session *cap_session, size_t stack_size,
_delay_start(Lock::LOCKED),
_cap_session(cap_session)
{
/*
* Create thread if we aren't running in core.
*
* For core this code can't be performed since the sessions aren't
* setup in the early bootstrap phase of core. In core the thread
* is created 'manually'.
*/
/* when not running in core set the affinity via cpu session */
if (_tid.ec_sel == Native_thread::INVALID_INDEX) {
/* create new pager object and assign it to the new thread */
_pager_cap = env()->rm_session()->add_client(_thread_cap);
if (!_pager_cap.valid())
throw Cpu_session::Thread_creation_failed();
if (env()->cpu_session()->set_pager(_thread_cap, _pager_cap))
throw Cpu_session::Thread_creation_failed();
/* place new thread on the specified CPU, if specified */
/* place new thread on the specified CPU */
if (location.valid())
env()->cpu_session()->affinity(_thread_cap, location);
addr_t thread_sp = (addr_t)&_context->stack[-4];
Thread_state state;
state.sel_exc_base = _tid.exc_pt_sel;
try { env()->cpu_session()->state(_thread_cap, state); }
catch(...) { throw Cpu_session::Thread_creation_failed(); }
if (env()->cpu_session()->start(_thread_cap, 0, thread_sp))
throw Cpu_session::Thread_creation_failed();
for (unsigned i = 0; i < Nova::PT_SEL_PARENT; i++)
request_event_portal(_pager_cap, _tid.exc_pt_sel, i);
request_event_portal(_pager_cap, _tid.exc_pt_sel,
Nova::PT_SEL_STARTUP);
request_event_portal(_pager_cap, _tid.exc_pt_sel,
Nova::SM_SEL_EC);
request_event_portal(_pager_cap, _tid.exc_pt_sel,
Nova::PT_SEL_RECALL);
/*
* Request native thread cap, _thread_cap only a token.
* The native thread cap is required to attach new rpc objects
* (to create portals bound to the ec)
*/
Genode::Nova_cpu_connection cpu;
Native_capability ec_cap = cpu.native_cap(_thread_cap);
if (!ec_cap.valid())
throw Cpu_session::Thread_creation_failed();
_tid.ec_sel = ec_cap.local_name();
/* magic value evaluated by thread_nova.cc to start a local thread */
_tid.ec_sel = Native_thread::INVALID_INDEX - 1;
} else {
/* tell thread starting code to use a specific CPU */
/* tell affinity CPU in 'core' via stack */
reinterpret_cast<Affinity::Location *>(stack_top())[-1] = location;
/*
* Required for core threads (creates local EC)
*/
Thread_base::start();
}
/* required to create a 'local' EC */
Thread_base::start();
/* create cleanup portal */
_cap = _cap_session->alloc(Native_capability(_tid.ec_sel),
(addr_t)_activation_entry);

View File

@ -127,9 +127,15 @@ void Thread_base::_deinit_platform_thread()
void Thread_base::start()
{
if (_tid.ec_sel != ~0UL)
if (_tid.ec_sel < Native_thread::INVALID_INDEX - 1)
throw Cpu_session::Thread_creation_failed();
/*
* Default: create global thread - ec.sel == INVALID_INDEX
* create local thread - ec.sel == INVALID_INDEX - 1
*/
bool global = _tid.ec_sel == Native_thread::INVALID_INDEX;
using namespace Genode;
/* create new pager object and assign it to the new thread */
@ -142,16 +148,19 @@ void Thread_base::start()
/* create EC at core */
addr_t thread_sp = reinterpret_cast<addr_t>(&_context->stack[-4]);
thread_sp &= ~0xf; /* align initial stack to 16 byte boundary */
thread_sp &= ~0xfUL; /* align initial stack to 16 byte boundary */
Thread_state state;
state.sel_exc_base = _tid.exc_pt_sel;
state.is_vcpu = _tid.is_vcpu;
/* local thread have no start instruction pointer - set via portal entry */
addr_t thread_ip = global ? reinterpret_cast<addr_t>(_thread_start) : 0;
try { env()->cpu_session()->state(_thread_cap, state); }
catch (...) { throw Cpu_session::Thread_creation_failed(); }
if (env()->cpu_session()->start(_thread_cap, (addr_t)_thread_start,
thread_sp))
if (env()->cpu_session()->start(_thread_cap, thread_ip, thread_sp))
throw Cpu_session::Thread_creation_failed();
/* request native EC thread cap */
@ -178,8 +187,9 @@ void Thread_base::start()
utcb_obj->crd_xlt = Obj_crd();
}
/* request creation of SC to let thread run*/
env()->cpu_session()->resume(_thread_cap);
if (global)
/* request creation of SC to let thread run*/
env()->cpu_session()->resume(_thread_cap);
}