mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-22 02:16:44 +00:00
l4lx: avoid creation of redundant thread for vcpus
This commit simplifies the creation of additional threads and VCPUs in L4linux. By now, some Genode::Thread_base methods where overridden to use a Fiasco.OC specific Cpu_session when creating threads. Recent commit: 297538678e06fe091fe6c3370d38c54d33627109 moved the actual creation of the platform thread into the constructor of the generic Thread_base class. Thereby the Vcpu class, which extended the Thread_base class, now unnecessarily created two platform threads for each thread created via Vcpu. Nowadays, the cpu_session capability is available via the Genode::env() environment. So we can use the Thread_base parent class for the setup of the platform thread, and afterwards create a Fiasco.OC specific cpu session client with the same cpu session capability, Thread_base used for creation, to make use of the L4Linux specific features of this interface (VCPU enabling, irq object creation etc.).
This commit is contained in:
parent
074e522990
commit
ae1985bde2
@ -28,33 +28,20 @@ namespace Fiasco {
|
|||||||
|
|
||||||
namespace L4lx {
|
namespace L4lx {
|
||||||
|
|
||||||
extern Genode::Foc_cpu_connection *vcpu_connection();
|
extern Genode::Foc_cpu_session_client *vcpu_connection();
|
||||||
|
|
||||||
|
|
||||||
class Vcpu : public Genode::Thread_base
|
class Vcpu : public Genode::Thread_base
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
Genode::Lock _lock;
|
||||||
L4_CV void (*_func)(void *data);
|
L4_CV void (*_func)(void *data);
|
||||||
unsigned long _data;
|
unsigned long _data;
|
||||||
Genode::addr_t _vcpu_state;
|
Genode::addr_t _vcpu_state;
|
||||||
Timer::Connection _timer;
|
Timer::Connection _timer;
|
||||||
unsigned _cpu_nr;
|
unsigned _cpu_nr;
|
||||||
|
|
||||||
static void _startup()
|
|
||||||
{
|
|
||||||
/* start thread function */
|
|
||||||
Vcpu* vcpu = reinterpret_cast<Vcpu*>(Genode::Thread_base::myself());
|
|
||||||
vcpu->entry();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
void entry() {
|
|
||||||
_func(&_data);
|
|
||||||
Genode::sleep_forever();
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Vcpu(const char *str,
|
Vcpu(const char *str,
|
||||||
@ -64,55 +51,37 @@ namespace L4lx {
|
|||||||
Genode::addr_t vcpu_state,
|
Genode::addr_t vcpu_state,
|
||||||
unsigned cpu_nr)
|
unsigned cpu_nr)
|
||||||
: Genode::Thread_base(str, stack_size),
|
: Genode::Thread_base(str, stack_size),
|
||||||
|
_lock(Genode::Cancelable_lock::LOCKED),
|
||||||
_func(func),
|
_func(func),
|
||||||
_data(data ? *data : 0),
|
_data(data ? *data : 0),
|
||||||
_vcpu_state(vcpu_state),
|
_vcpu_state(vcpu_state),
|
||||||
_cpu_nr(cpu_nr)
|
_cpu_nr(cpu_nr)
|
||||||
|
{
|
||||||
|
start();
|
||||||
|
|
||||||
|
/* set l4linux specific utcb entry: L4X_UTCB_TCR_ID */
|
||||||
|
l4_utcb_tcr_u(utcb())->user[0] = tid();
|
||||||
|
|
||||||
|
/* enable vcpu functionality respectively */
|
||||||
|
if (_vcpu_state)
|
||||||
|
vcpu_connection()->enable_vcpu(_thread_cap, _vcpu_state);
|
||||||
|
|
||||||
|
/* set cpu affinity */
|
||||||
|
set_affinity(_cpu_nr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void entry()
|
||||||
{
|
{
|
||||||
using namespace Genode;
|
_lock.lock();
|
||||||
using namespace Fiasco;
|
_func(&_data);
|
||||||
|
Genode::sleep_forever();
|
||||||
/* create thread at core */
|
|
||||||
char buf[48];
|
|
||||||
name(buf, sizeof(buf));
|
|
||||||
_thread_cap = vcpu_connection()->create_thread(buf);
|
|
||||||
|
|
||||||
/* assign thread to protection domain */
|
|
||||||
env()->pd_session()->bind_thread(_thread_cap);
|
|
||||||
|
|
||||||
/* create new pager object and assign it to the new thread */
|
|
||||||
_pager_cap = env()->rm_session()->add_client(_thread_cap);
|
|
||||||
vcpu_connection()->set_pager(_thread_cap, _pager_cap);
|
|
||||||
|
|
||||||
/* get gate-capability and badge of new thread */
|
|
||||||
Thread_state state = vcpu_connection()->state(_thread_cap);
|
|
||||||
_tid = state.kcap;
|
|
||||||
_context->utcb = state.utcb;
|
|
||||||
|
|
||||||
Cap_index *i = cap_map()->insert(state.id, state.kcap);
|
|
||||||
l4_utcb_tcr_u(state.utcb)->user[UTCB_TCR_BADGE] = (unsigned long) i;
|
|
||||||
l4_utcb_tcr_u(state.utcb)->user[UTCB_TCR_THREAD_OBJ] = (addr_t)this;
|
|
||||||
l4_utcb_tcr_u(state.utcb)->user[0] = state.kcap; /* L4X_UTCB_TCR_ID */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void start()
|
void unblock() { _lock.unlock(); }
|
||||||
{
|
|
||||||
using namespace Genode;
|
|
||||||
|
|
||||||
/* register initial IP and SP at core */
|
|
||||||
addr_t stack = (addr_t)&_context->stack[-4];
|
|
||||||
stack &= ~0xf; /* align initial stack to 16 byte boundary */
|
|
||||||
vcpu_connection()->start(_thread_cap, (addr_t)_startup, stack);
|
|
||||||
|
|
||||||
if (_vcpu_state)
|
|
||||||
vcpu_connection()->enable_vcpu(_thread_cap, _vcpu_state);
|
|
||||||
|
|
||||||
set_affinity(_cpu_nr);
|
|
||||||
}
|
|
||||||
|
|
||||||
Genode::addr_t sp() {
|
Genode::addr_t sp() {
|
||||||
return ((Genode::addr_t)&_context->stack[-4]) & ~0xf; }
|
return ((Genode::addr_t)&_context->stack[-4]) & ~0xf; }
|
||||||
Genode::addr_t ip() { return (Genode::addr_t)_startup; }
|
Genode::addr_t ip() { return (Genode::addr_t)_func; }
|
||||||
|
|
||||||
Fiasco::l4_utcb_t *utcb() { return _context->utcb; };
|
Fiasco::l4_utcb_t *utcb() { return _context->utcb; };
|
||||||
|
|
||||||
|
@ -48,12 +48,12 @@ static l4_addr_t utcb_base_addr()
|
|||||||
return _addr;
|
return _addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Genode::Foc_cpu_connection* L4lx::vcpu_connection()
|
Genode::Foc_cpu_session_client* L4lx::vcpu_connection()
|
||||||
{
|
{
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
static Foc_cpu_connection _con;
|
static Foc_cpu_session_client _client(Genode::env()->cpu_session_cap());
|
||||||
return &_con;
|
return &_client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -143,7 +143,7 @@ l4lx_thread_t l4lx_thread_create(L4_CV void (*thread_func)(void *data),
|
|||||||
vcpus[thread_id(vc->utcb())] = vc;
|
vcpus[thread_id(vc->utcb())] = vc;
|
||||||
|
|
||||||
if (!deferstart)
|
if (!deferstart)
|
||||||
vc->start();
|
vc->unblock();
|
||||||
else {
|
else {
|
||||||
deferstart->l4cap = (l4_cap_idx_t) vc;
|
deferstart->l4cap = (l4_cap_idx_t) vc;
|
||||||
deferstart->sp = (l4_umword_t)vc->sp();
|
deferstart->sp = (l4_umword_t)vc->sp();
|
||||||
@ -161,7 +161,7 @@ int l4lx_thread_start(struct l4lx_thread_start_info_t *startinfo)
|
|||||||
if (DEBUG)
|
if (DEBUG)
|
||||||
PDBG("ip=%lx sp=%lx", startinfo->ip, startinfo->sp);
|
PDBG("ip=%lx sp=%lx", startinfo->ip, startinfo->sp);
|
||||||
L4lx::Vcpu *vc = (L4lx::Vcpu*) startinfo->l4cap;
|
L4lx::Vcpu *vc = (L4lx::Vcpu*) startinfo->l4cap;
|
||||||
vc->start();
|
vc->unblock();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user