Merge Native_capability implementations (fix #145).

This patch unifies the Native_capability classes for the different kernel
platforms by introducing an appropriate template, and eliminating naming
differences. Please refer issue #145.
This commit is contained in:
Stefan Kalkowski 2012-03-08 12:45:18 +01:00 committed by Norman Feske
parent 9992efed03
commit c9c21ad39c
37 changed files with 248 additions and 546 deletions

View File

@ -14,7 +14,7 @@
#ifndef _INCLUDE__BASE__NATIVE_TYPES_H_
#define _INCLUDE__BASE__NATIVE_TYPES_H_
#include <util/string.h>
#include <base/native_capability.h>
namespace Codezero {
@ -49,6 +49,9 @@ namespace Genode {
Native_thread_id(int l4id) : tid(l4id), running_lock(0) { }
Native_thread_id(int l4id, Codezero::l4_mutex *rl) : tid(l4id), running_lock(rl) { }
static bool valid(int tid) { return tid != Codezero::NILTHREAD; }
static int invalid() { return Codezero::NILTHREAD; }
};
struct Native_thread
@ -102,54 +105,7 @@ namespace Genode {
inline bool operator == (Native_thread_id t1, Native_thread_id t2) { return t1.tid == t2.tid; }
inline bool operator != (Native_thread_id t1, Native_thread_id t2) { return t1.tid != t2.tid; }
/*
* Because Codezero does not support local names for capabilities, a Genode
* capability consists of the global thread ID and a global object ID, not
* protected by the kernel when transmitted as IPC payloads.
*/
class Native_capability
{
private:
Native_thread_id _tid; /* global thread ID */
int _local_name; /* global unique object ID */
protected:
Native_capability(void* ptr) : _local_name((int)ptr) {
_tid.tid = Codezero::NILTHREAD; }
public:
/**
* Default constructor creates invalid capability
*/
Native_capability()
: _local_name(0) { _tid.tid = Codezero::NILTHREAD; }
/**
* Constructor for hand-crafting capabilities
*
* This constructor is only used internally be the framework.
*/
Native_capability(Native_thread_id tid, int local_name)
: _tid(tid), _local_name(local_name) { }
bool valid() const { return _tid.tid != Codezero::NILTHREAD; }
int local_name() const { return _local_name; }
void* local() const { return (void*)_local_name; }
int dst() const { return _tid.tid; }
Native_thread_id tid() const { return _tid; }
/**
* Copy this capability to another pd.
*/
void copy_to(void* dst) {
memcpy(dst, this, sizeof(Native_capability)); }
};
typedef Native_capability_tpl<int,Native_thread_id> Native_capability;
typedef int Native_connection_state;
}

View File

@ -34,17 +34,17 @@ void Ipc_ostream::_send()
{
if (verbose_ipc)
PDBG("thread %d sends IPC to %d, write_offset=%d",
thread_myself(), _dst.tid().tid, _write_offset);
thread_myself(), _dst.tid(), _write_offset);
umword_t snd_size = min(_write_offset, (unsigned)L4_IPC_EXTENDED_MAX_SIZE);
*(umword_t *)_snd_msg->addr() = _dst.local_name();
int ret = l4_send_extended(_dst.tid().tid, L4_IPC_TAG_SYNC_EXTENDED,
int ret = l4_send_extended(_dst.tid(), L4_IPC_TAG_SYNC_EXTENDED,
snd_size, _snd_msg->addr());
if (ret < 0)
PERR("l4_send_extended (to thread %d) returned ret=%d",
_dst.tid().tid, ret);
_dst.tid(), ret);
_write_offset = sizeof(umword_t);
}
@ -71,7 +71,7 @@ void Ipc_istream::_wait()
if (verbose_ipc)
PDBG("thread %d waits for IPC from %d, rcv_buf at %p, rcv_size=%d",
tid().tid, _rcv_cs, rcv_buf, (int)rcv_size);
tid(), _rcv_cs, rcv_buf, (int)rcv_size);
int ret = l4_receive_extended(_rcv_cs, rcv_size, rcv_buf);
if (ret < 0)
@ -79,7 +79,7 @@ void Ipc_istream::_wait()
if (verbose_ipc)
PDBG("thread %d received IPC from %d",
tid().tid, l4_get_sender());
tid(), l4_get_sender());
_read_offset = sizeof(umword_t);
}
@ -107,7 +107,7 @@ void Ipc_client::_call()
{
#warning l4_sendrecv_extended is not yet implemented in l4lib/arch/syslib.h
_send();
_rcv_cs = _dst.tid().tid;
_rcv_cs = _dst.tid();
_wait();
_rcv_cs = L4_ANYTHREAD;

View File

@ -14,15 +14,16 @@
#ifndef _INCLUDE__BASE__NATIVE_TYPES_H_
#define _INCLUDE__BASE__NATIVE_TYPES_H_
#include <util/string.h>
#include <base/native_capability.h>
namespace Fiasco {
#include <l4/sys/types.h>
/**
* Return invalid L4 thread ID
*/
inline l4_threadid_t invalid_l4_threadid_t() { return L4_INVALID_ID; }
struct Thread_id_check
{
static bool valid(l4_threadid_t id) { return !l4_is_invalid_id(id); }
static l4_threadid_t invalid() { return L4_INVALID_ID;}
};
}
namespace Genode {
@ -64,66 +65,7 @@ namespace Genode {
*/
typedef struct { } Native_utcb;
/*
* On Fiasco, the local_name member of a capability is global
* to the whole system. Therefore, capabilities are to be
* created at a central place that prevents id clashes.
*/
class Native_capability
{
protected:
Fiasco::l4_threadid_t _tid;
long _local_name;
protected:
Native_capability(void *ptr)
: _tid(Fiasco::invalid_l4_threadid_t()), _local_name((long)ptr) { }
public:
/**
* Default constructor
*/
Native_capability()
: _tid(Fiasco::invalid_l4_threadid_t()), _local_name(0) { }
long local_name() const { return _local_name; }
Fiasco::l4_threadid_t dst() const { return _tid; }
void* local() const { return (void*)_local_name; }
bool valid() const { return l4_is_invalid_id(_tid) == 0; }
/*****************************************************
** Functions to be used by the Fiasco backend only **
*****************************************************/
/**
* Constructor
*
* This constructor can be called to create a Fiasco
* capability by hand. It must never be used from
* generic code!
*/
Native_capability(Fiasco::l4_threadid_t tid,
Fiasco::l4_umword_t local_name)
: _tid(tid), _local_name(local_name) { }
/**
* Access raw capability data
*/
Fiasco::l4_threadid_t tid() const { return _tid; }
/**
* Copy this capability to another pd.
*/
void copy_to(void* dst) {
memcpy(dst, this, sizeof(Native_capability)); }
};
typedef Native_capability_tpl<Native_thread_id,Fiasco::Thread_id_check> Native_capability;
typedef Fiasco::l4_threadid_t Native_connection_state;
}

View File

@ -163,8 +163,7 @@ namespace Genode
/**
* Constructor
*/
Capability_allocator_tpl()
: _cap_idx(Fiasco::Fiasco_capability::USER_BASE_CAP) { }
Capability_allocator_tpl() : _cap_idx(Fiasco::USER_BASE_CAP) { }
/************************************

View File

@ -27,7 +27,7 @@ inline void Genode::Ipc_ostream::_marshal_capability(Genode::Native_capability c
long unique_id = cap.local_name();
_write_to_buf(unique_id);
if (unique_id)
_snd_msg->snd_append_cap_sel(cap.dst());
_snd_msg->snd_append_cap_sel(cap.tid());
}

View File

@ -154,7 +154,7 @@ namespace Genode {
* Set destination for next reply
*/
void set_reply_dst(Native_capability pager_object) {
_last = pager_object.dst(); }
_last = pager_object.tid(); }
/**
* Answer call without sending a flex-page mapping

View File

@ -1,44 +1,31 @@
#ifndef _INCLUDE__BASE__NATIVE_TYPES_H_
#define _INCLUDE__BASE__NATIVE_TYPES_H_
#include <util/string.h>
#include <base/native_capability.h>
namespace Fiasco {
#include <l4/sys/consts.h>
#include <l4/sys/types.h>
#include <l4/sys/utcb.h>
class Fiasco_capability
struct Thread_id_check
{
private:
static bool valid(l4_cap_idx_t idx) {
return !(idx & Fiasco::L4_INVALID_CAP_BIT) && idx != 0; }
l4_cap_idx_t _cap_idx;
static l4_cap_idx_t invalid() { return L4_INVALID_CAP;}
};
public:
enum Cap_selectors {
INVALID_CAP = L4_INVALID_CAP,
TASK_CAP = L4_BASE_TASK_CAP,
PARENT_CAP = 0x8UL << L4_CAP_SHIFT,
THREADS_BASE_CAP = 0x9UL << L4_CAP_SHIFT,
USER_BASE_CAP = 0x200UL << L4_CAP_SHIFT,
THREAD_GATE_CAP = 0,
THREAD_PAGER_CAP = 0x1UL << L4_CAP_SHIFT,
THREAD_IRQ_CAP = 0x2UL << L4_CAP_SHIFT,
THREAD_CAP_SLOT = THREAD_IRQ_CAP + L4_CAP_SIZE,
MAIN_THREAD_CAP = THREADS_BASE_CAP + THREAD_GATE_CAP
};
Fiasco_capability(l4_cap_idx_t cap = L4_INVALID_CAP)
: _cap_idx(cap) { }
Fiasco_capability(void* cap)
: _cap_idx((l4_cap_idx_t)cap) { }
bool valid() const { return !(_cap_idx & Fiasco::L4_INVALID_CAP_BIT)
&& _cap_idx != 0; }
operator l4_cap_idx_t () { return _cap_idx; }
enum Cap_selectors {
TASK_CAP = L4_BASE_TASK_CAP,
PARENT_CAP = 0x8UL << L4_CAP_SHIFT,
THREADS_BASE_CAP = 0x9UL << L4_CAP_SHIFT,
USER_BASE_CAP = 0x200UL << L4_CAP_SHIFT,
THREAD_GATE_CAP = 0,
THREAD_PAGER_CAP = 0x1UL << L4_CAP_SHIFT,
THREAD_IRQ_CAP = 0x2UL << L4_CAP_SHIFT,
THREAD_CAP_SLOT = THREAD_IRQ_CAP + L4_CAP_SIZE,
MAIN_THREAD_CAP = THREADS_BASE_CAP + THREAD_GATE_CAP
};
enum Utcb_regs {
@ -49,51 +36,14 @@ namespace Fiasco {
namespace Genode {
typedef volatile int Native_lock;
typedef Fiasco::Fiasco_capability Native_thread_id;
typedef Fiasco::Fiasco_capability Native_thread;
typedef Fiasco::Fiasco_capability Native_task;
typedef Fiasco::l4_utcb_t* Native_utcb;
class Native_capability
{
private:
Native_thread _cap_sel;
int _unique_id;
protected:
Native_capability(void* ptr) : _unique_id((int)ptr) { }
public:
/**
* Default constructor creates an invalid capability
*/
Native_capability() : _unique_id(0) { }
/**
* Construct capability manually
*/
Native_capability(Native_thread cap_sel, int unique_id)
: _cap_sel(cap_sel), _unique_id(unique_id) { }
int local_name() const { return _unique_id; }
void* local() const { return (void*)_unique_id; }
Native_thread dst() const { return _cap_sel; }
Native_thread_id tid() const { return _cap_sel; }
bool valid() const { return _cap_sel.valid() && _unique_id != 0; }
/**
* Copy this capability to another pd.
*/
void copy_to(void* dst) {
memcpy(dst, this, sizeof(Native_capability)); }
};
typedef int Native_connection_state;
typedef volatile int Native_lock;
typedef Fiasco::l4_cap_idx_t Native_thread_id;
typedef Fiasco::l4_cap_idx_t Native_thread;
typedef Fiasco::l4_cap_idx_t Native_task;
typedef Fiasco::l4_utcb_t* Native_utcb;
typedef int Native_connection_state;
typedef Native_capability_tpl<Fiasco::l4_cap_idx_t,
Fiasco::Thread_id_check> Native_capability;
}
#endif /* _INCLUDE__BASE__NATIVE_TYPES_H_ */

View File

@ -51,7 +51,7 @@ namespace Genode {
/* request mapping of semaphore capability selector */
_sem = call<Rpc_request_semaphore>();
l4_msgtag_t tag = l4_irq_attach(_sem.dst(), 0,
l4_msgtag_t tag = l4_irq_attach(_sem.tid(), 0,
Thread_base::myself()->tid());
if (l4_error(tag))
PERR("l4_irq_attach failed with %ld!", l4_error(tag));
@ -76,7 +76,7 @@ namespace Genode {
using namespace Fiasco;
/* block on semaphore, will be unblocked if signal is available */
l4_irq_receive(_sem.dst(), L4_IPC_NEVER);
l4_irq_receive(_sem.tid(), L4_IPC_NEVER);
/*
* Now that the server has unblocked the semaphore, we are sure

View File

@ -142,7 +142,7 @@ static l4_msgtag_t copy_msgbuf_to_utcb(Msgbuf_base *snd_msg, unsigned offset,
void Ipc_ostream::_send()
{
l4_msgtag_t tag = copy_msgbuf_to_utcb(_snd_msg, _write_offset, _dst);
tag = l4_ipc_send(_dst.dst(), l4_utcb(), tag, L4_IPC_NEVER);
tag = l4_ipc_send(_dst.tid(), l4_utcb(), tag, L4_IPC_NEVER);
if (ipc_error(tag, DEBUG_MSG))
throw Ipc_error();
@ -215,7 +215,7 @@ void Ipc_client::_call()
rcv_cap_sel += L4_CAP_SIZE;
}
tag = l4_ipc_call(_dst.dst(), l4_utcb(), tag, L4_IPC_NEVER);
tag = l4_ipc_call(_dst.tid(), l4_utcb(), tag, L4_IPC_NEVER);
if (l4_ipc_error(tag, l4_utcb()) == L4_IPC_RECANCELED)
throw Genode::Blocking_canceled();
if (ipc_error(tag, DEBUG_MSG))

View File

@ -98,7 +98,7 @@ void Ipc_pager::reply_and_wait_for_fault()
void Ipc_pager::acknowledge_wakeup()
{
l4_cap_idx_t dst = _last.valid() ? _last : L4_SYSF_REPLY;
l4_cap_idx_t dst = Thread_id_check::valid(_last) ? _last : L4_SYSF_REPLY;
/* answer wakeup call from one of core's region-manager sessions */
l4_ipc_send(dst, l4_utcb(), l4_msgtag(0, 0, 0, 0), L4_IPC_SEND_TIMEOUT_0);

View File

@ -55,20 +55,16 @@ static inline void thread_yield() { Fiasco::l4_thread_yield(); }
*/
static inline bool thread_check_stopped_and_restart(Genode::Native_thread_id tid)
{
using namespace Fiasco;
Genode::Native_thread_id irq = tid + Fiasco_capability::THREAD_IRQ_CAP;
l4_irq_trigger(irq);
Genode::Native_thread_id irq = tid + Fiasco::THREAD_IRQ_CAP;
Fiasco::l4_irq_trigger(irq);
return true;
}
static inline Genode::Native_thread_id thread_get_my_native_id()
{
using namespace Fiasco;
Genode::Thread_base *myself = Genode::Thread_base::myself();
return myself ? myself->tid() : Fiasco_capability::MAIN_THREAD_CAP;
return myself ? myself->tid() : Fiasco::MAIN_THREAD_CAP;
}
@ -85,7 +81,7 @@ static inline Genode::Native_thread_id thread_invalid_id()
*/
static inline bool thread_id_valid(Genode::Native_thread_id tid)
{
return tid.valid();
return Fiasco::Thread_id_check::valid(tid);
}
@ -105,8 +101,7 @@ static inline void thread_stop_myself()
{
using namespace Fiasco;
Genode::Native_thread_id irq = thread_get_my_native_id()
+ Fiasco_capability::THREAD_IRQ_CAP;
Genode::Native_thread_id irq = thread_get_my_native_id() + THREAD_IRQ_CAP;
l4_irq_receive(irq, L4_IPC_NEVER);
}

View File

@ -49,7 +49,7 @@ void Thread_base::start()
/* get gate-capability and badge of new thread */
Thread_state state;
env()->cpu_session()->state(_thread_cap, &state);
_tid = state.cap.dst();
_tid = state.cap.tid();
/*
* send newly constructed thread, pointer to its Thread_base object,

View File

@ -118,10 +118,10 @@ void Cap_session_component::free(Native_capability cap)
Capability_tree::tree()->remove(n);
l4_msgtag_t tag = l4_task_unmap(L4_BASE_TASK_CAP,
l4_obj_fpage(cap.dst(), 0, L4_FPAGE_RWX),
l4_obj_fpage(cap.tid(), 0, L4_FPAGE_RWX),
L4_FP_ALL_SPACES | L4_FP_DELETE_OBJ);
if (l4_msgtag_has_error(tag))
PERR("destruction of ipc-gate %lx failed!", (unsigned long) cap.dst());
PERR("destruction of ipc-gate %lx failed!", (unsigned long) cap.tid());
/* free badge _after_ invalidating all caps */
Badge_allocator::allocator()->free(n->badge());

View File

@ -61,7 +61,7 @@ Genode::Native_capability Genode::Cpu_session_component::alloc_irq()
{
using namespace Fiasco;
Fiasco_capability irq_cap(Genode::cap_alloc()->alloc());
Native_thread_id irq_cap(Genode::cap_alloc()->alloc());
l4_msgtag_t res = l4_factory_create_irq(L4_BASE_FACTORY_CAP, irq_cap);
if (l4_error(res))
PWRN("Allocation of irq object failed!");

View File

@ -111,7 +111,7 @@ namespace Genode {
Native_task native_task() { return _l4_task_cap; }
unsigned badge() { return _badge; }
Native_thread parent_cap() { return _parent.dst(); }
Native_thread parent_cap() { return _parent.tid(); }
};
}

View File

@ -147,14 +147,14 @@ namespace Genode {
* Return identification of thread when faulting
*/
unsigned long pager_object_badge() {
return (unsigned long) _thread_cap.dst(); }
return (unsigned long) _thread_cap.tid(); }
/*******************************
** Fiasco-specific Accessors **
*******************************/
Native_thread native_thread() const { return _thread_cap.dst(); }
Native_thread native_thread() const { return _thread_cap.tid(); }
Native_capability thread_cap() const { return _thread_cap; }
Native_capability gate() const { return _remote_gate_cap; }
const char *name() const { return _name; }

View File

@ -56,7 +56,7 @@ Irq_session_component::Interrupt::Interrupt()
Native_thread Irq_session_component::Interrupt_handler::handler_cap()
{
static Interrupt_handler handler;
return handler._thread_cap.dst();
return handler._thread_cap.tid();
}

View File

@ -43,7 +43,7 @@ static addr_t core_utcb_base() {
void Platform_pd::_create_pd(bool syscall)
{
if (!_l4_task_cap.valid())
if (!Thread_id_check::valid(_l4_task_cap))
_l4_task_cap = cap_alloc()->alloc();
if (syscall) {
@ -75,8 +75,6 @@ void Platform_pd::_destroy_pd()
int Platform_pd::bind_thread(Platform_thread *thread)
{
using namespace Fiasco;
for (unsigned i = 0; i < THREAD_MAX; i++) {
if (_threads[i])
continue;
@ -87,12 +85,11 @@ int Platform_pd::bind_thread(Platform_thread *thread)
else
thread->_utcb =
reinterpret_cast<l4_utcb_t*>(UTCB_AREA_START + i * L4_UTCB_OFFSET);
Native_thread cap_offset = Fiasco_capability::THREADS_BASE_CAP +
i * Fiasco_capability::THREAD_CAP_SLOT;
thread->_remote_gate_cap = Native_capability(cap_offset + Fiasco_capability::THREAD_GATE_CAP,
Native_thread cap_offset = THREADS_BASE_CAP + i * THREAD_CAP_SLOT;
thread->_remote_gate_cap = Native_capability(cap_offset + THREAD_GATE_CAP,
thread->_gate_cap.local_name());
thread->_remote_pager_cap = cap_offset + Fiasco_capability::THREAD_PAGER_CAP;
thread->_remote_irq_cap = cap_offset + Fiasco_capability::THREAD_IRQ_CAP;
thread->_remote_pager_cap = cap_offset + THREAD_PAGER_CAP;
thread->_remote_irq_cap = cap_offset + THREAD_IRQ_CAP;
/* inform thread about binding */
thread->bind(this);
@ -129,8 +126,8 @@ void Platform_pd::map_parent_cap()
{
if (!_parent_cap_mapped) {
l4_msgtag_t tag = l4_task_map(_l4_task_cap, L4_BASE_TASK_CAP,
l4_obj_fpage(_parent.dst(), 0, L4_FPAGE_RWX),
Fiasco_capability::PARENT_CAP | L4_ITEM_MAP);
l4_obj_fpage(_parent.tid(), 0, L4_FPAGE_RWX),
PARENT_CAP | L4_ITEM_MAP);
if (l4_msgtag_has_error(tag))
PWRN("mapping parent cap failed");
@ -144,7 +141,7 @@ void Platform_pd::map_task_cap()
if (!_task_cap_mapped) {
l4_msgtag_t tag = l4_task_map(_l4_task_cap, L4_BASE_TASK_CAP,
l4_obj_fpage(_l4_task_cap, 0, L4_FPAGE_RWX),
Fiasco_capability::TASK_CAP | L4_ITEM_MAP);
TASK_CAP | L4_ITEM_MAP);
if (l4_msgtag_has_error(tag))
PWRN("mapping task cap failed");
_task_cap_mapped = true;

View File

@ -41,7 +41,7 @@ int Platform_thread::start(void *ip, void *sp)
if (_pager && _platform_pd) {
/* map pager cap */
l4_msgtag_t tag = l4_task_map(_platform_pd->native_task(), L4_BASE_TASK_CAP,
l4_obj_fpage(_pager->cap().dst(), 0, L4_FPAGE_RWX),
l4_obj_fpage(_pager->cap().tid(), 0, L4_FPAGE_RWX),
_remote_pager_cap | L4_ITEM_MAP);
if (l4_msgtag_has_error(tag))
PWRN("mapping pager cap failed");
@ -53,15 +53,15 @@ int Platform_thread::start(void *ip, void *sp)
l4_thread_control_exc_handler(_remote_pager_cap);
l4_thread_control_bind(_utcb, _platform_pd->native_task());
l4_msgtag_t tag = l4_thread_control_commit(_thread_cap.dst());
l4_msgtag_t tag = l4_thread_control_commit(_thread_cap.tid());
if (l4_msgtag_has_error(tag)) {
PWRN("l4_thread_control_commit for %lx failed!",
(unsigned long) _thread_cap.dst());
(unsigned long) _thread_cap.tid());
return -1;
}
/* set ip and sp and run the thread */
tag = l4_thread_ex_regs(_thread_cap.dst(), (l4_addr_t) ip, (l4_addr_t) sp, 0);
tag = l4_thread_ex_regs(_thread_cap.tid(), (l4_addr_t) ip, (l4_addr_t) sp, 0);
if (l4_msgtag_has_error(tag)) {
PWRN("l4_thread_ex_regs failed!");
return -1;
@ -96,7 +96,7 @@ void Platform_thread::pause()
* The pager thread, which also acts as exception handler, will
* leave the thread in exception state until, it gets woken again
*/
l4_thread_ex_regs_ret(_thread_cap.dst(), &_pager->state.ip,
l4_thread_ex_regs_ret(_thread_cap.tid(), &_pager->state.ip,
&_pager->state.sp, &flags);
bool in_syscall = flags == 0;
_pager->state.lock.unlock();
@ -111,7 +111,7 @@ void Platform_thread::pause()
* the requested thread, and stored its thread state
*/
while (exc == _pager->state.exceptions && !_pager->state.in_exception)
l4_thread_switch(_thread_cap.dst());
l4_thread_switch(_thread_cap.tid());
}
}
@ -150,8 +150,8 @@ void Platform_thread::bind(Platform_pd *pd)
if (_gate_cap.valid()) {
/* map thread's gate cap */
tag = l4_task_map(task, L4_BASE_TASK_CAP,
l4_obj_fpage(_gate_cap.dst(), 0, L4_FPAGE_RWX),
_remote_gate_cap.dst() | L4_ITEM_MAP);
l4_obj_fpage(_gate_cap.tid(), 0, L4_FPAGE_RWX),
_remote_gate_cap.tid() | L4_ITEM_MAP);
if (l4_msgtag_has_error(tag))
PWRN("mapping thread's gate cap failed");
}
@ -167,12 +167,12 @@ void Platform_thread::bind(Platform_pd *pd)
void Platform_thread::unbind()
{
l4_thread_ex_regs(_thread_cap.dst(), 0, 0, 0);
l4_thread_ex_regs(_thread_cap.tid(), 0, 0, 0);
l4_task_unmap(L4_BASE_TASK_CAP,
l4_obj_fpage(_gate_cap.dst(), 0, L4_FPAGE_RWX),
l4_obj_fpage(_gate_cap.tid(), 0, L4_FPAGE_RWX),
L4_FP_ALL_SPACES | L4_FP_DELETE_OBJ);
l4_task_unmap(L4_BASE_TASK_CAP,
l4_obj_fpage(_thread_cap.dst(), 0, L4_FPAGE_RWX),
l4_obj_fpage(_thread_cap.tid(), 0, L4_FPAGE_RWX),
L4_FP_ALL_SPACES | L4_FP_DELETE_OBJ);
_platform_pd = (Platform_pd*) 0;
}
@ -203,7 +203,7 @@ void Platform_thread::cancel_blocking()
void Platform_thread::_create_thread()
{
l4_msgtag_t tag = l4_factory_create_thread(L4_BASE_FACTORY_CAP,
_thread_cap.dst());
_thread_cap.tid());
if (l4_msgtag_has_error(tag))
PERR("cannot create more thread kernel-objects!");
}
@ -218,18 +218,18 @@ void Platform_thread::_finalize_construction(const char *name, unsigned prio)
PWRN("creating thread's irq failed");
/* attach thread to irq */
tag = l4_irq_attach(_irq_cap, 0, _thread_cap.dst());
tag = l4_irq_attach(_irq_cap, 0, _thread_cap.tid());
if (l4_msgtag_has_error(tag))
PWRN("attaching thread's irq failed");
/* set human readable name in kernel debugger */
strncpy(_name, name, sizeof(_name));
Fiasco::l4_debugger_set_object_name(_thread_cap.dst(), name);
Fiasco::l4_debugger_set_object_name(_thread_cap.tid(), name);
/* set priority of thread */
prio = Cpu_session::scale_priority(DEFAULT_PRIORITY, prio);
l4_sched_param_t params = l4_sched_param(prio);
l4_scheduler_run_thread(L4_BASE_SCHEDULER_CAP, _thread_cap.dst(), &params);
l4_scheduler_run_thread(L4_BASE_SCHEDULER_CAP, _thread_cap.tid(), &params);
}
@ -239,7 +239,7 @@ Platform_thread::Platform_thread(const char *name,
_badge(Badge_allocator::allocator()->alloc()),
_thread_cap(cap_alloc()->alloc_id(_badge),
_badge),
_node(_thread_cap.local_name(), 0, this, _thread_cap.dst()),
_node(_thread_cap.local_name(), 0, this, _thread_cap.tid()),
_utcb(0),
_platform_pd(0),
_pager(0)
@ -259,7 +259,7 @@ Platform_thread::Platform_thread(const char *name,
Platform_thread::Platform_thread(Native_thread cap, const char *name)
: _core_thread(true),
_thread_cap(cap, -1),
_node(_thread_cap.local_name(), 0, this, _thread_cap.dst()),
_node(_thread_cap.local_name(), 0, this, _thread_cap.tid()),
_utcb(0),
_platform_pd(0),
_pager(0)
@ -276,7 +276,7 @@ Platform_thread::Platform_thread(const char *name)
_badge(Badge_allocator::allocator()->alloc()),
_thread_cap(cap_alloc()->alloc_id(_badge),
_badge),
_node(_thread_cap.local_name(), 0, this, _thread_cap.dst()),
_node(_thread_cap.local_name(), 0, this, _thread_cap.tid()),
_utcb(0),
_platform_pd(0),
_pager(0)
@ -304,6 +304,6 @@ Platform_thread::~Platform_thread()
/* remove the thread capability */
Capability_tree::tree()->remove(&_node);
cap_alloc()->free(_thread_cap.dst());
cap_alloc()->free(_thread_cap.tid());
Badge_allocator::allocator()->free(_badge);
}

View File

@ -44,7 +44,7 @@ void Signal_source_component::submit(Signal_context_component *context,
_signal_queue.enqueue(context);
/* wake up client */
Fiasco::l4_irq_trigger(_blocking_semaphore.dst());
Fiasco::l4_irq_trigger(_blocking_semaphore.tid());
}
}
@ -69,9 +69,9 @@ Signal_source_component::Signal_source_component(Rpc_entrypoint *ep)
{
using namespace Fiasco;
unsigned long badge = Badge_allocator::allocator()->alloc();
Fiasco_capability irq = cap_alloc()->alloc_id(badge);
l4_msgtag_t res = l4_factory_create_irq(L4_BASE_FACTORY_CAP, irq);
unsigned long badge = Badge_allocator::allocator()->alloc();
Native_thread_id irq = cap_alloc()->alloc_id(badge);
l4_msgtag_t res = l4_factory_create_irq(L4_BASE_FACTORY_CAP, irq);
if (l4_error(res))
PERR("Allocation of irq object failed!");

View File

@ -44,7 +44,7 @@ void Thread_base::start()
new(platform()->core_mem_alloc()) Platform_thread(_context->name);
platform_specific()->core_pd()->bind_thread(pt);
_tid = pt->gate().dst();
_tid = pt->gate().tid();
_thread_cap = reinterpret_cap_cast<Cpu_thread>(pt->thread_cap());
pt->pager(platform_specific()->core_pager());

View File

@ -28,8 +28,7 @@ namespace Genode {
/* assemble parent capability from object ID and Fiasco cap */
return reinterpret_cap_cast<Parent>(
Native_capability(Fiasco::Fiasco_capability::PARENT_CAP,
cap.local_name()));
Native_capability(Fiasco::PARENT_CAP, cap.local_name()));
}
}

View File

@ -14,45 +14,21 @@
#ifndef _INCLUDE__BASE__NATIVE_TYPES_H_
#define _INCLUDE__BASE__NATIVE_TYPES_H_
#include <util/string.h>
#include <base/native_capability.h>
namespace Genode {
struct Empty_thread_id {
static bool valid(Empty_thread_id id) { return true; }
static Empty_thread_id invalid() { return Empty_thread_id();}
};
typedef volatile int Native_lock;
typedef int Native_thread;
typedef Native_thread Native_thread_id;
typedef struct { } Native_utcb;
class Native_capability
{
private:
long _local_name;
protected:
Native_capability(void* ptr) : _local_name((long)ptr) { }
public:
Native_capability() : _local_name(0) { }
Native_capability(Native_thread_id, long local_name)
: _local_name(local_name) { }
bool valid() const { return _local_name != 0; }
int local_name() const { return _local_name; }
void* local() const { return (void*)_local_name; }
int dst() const { return 0; }
Native_thread_id tid() const { return 0; }
/**
* Copy this capability to another pd.
*/
void copy_to(void* dst) {
memcpy(dst, this, sizeof(Native_capability)); }
};
typedef int Native_connection_state;
typedef Native_capability_tpl<Empty_thread_id,Empty_thread_id> Native_capability;
}
#endif /* _INCLUDE__BASE__NATIVE_TYPES_H_ */

View File

@ -14,7 +14,7 @@
#ifndef _INCLUDE__BASE__NATIVE_TYPES_H_
#define _INCLUDE__BASE__NATIVE_TYPES_H_
#include <util/string.h>
#include <base/native_capability.h>
/*
* We cannot just include <semaphore.h> and <pthread.h> here
@ -93,68 +93,17 @@ namespace Genode {
inline bool operator != (Native_thread_id t1, Native_thread_id t2) {
return (t1.tid != t2.tid) || (t1.pid != t2.pid); }
struct Thread_id_check {
static bool valid(long id) { return id != 0; }
static long invalid() { return 0; }
};
/**
* Empty UTCB type expected by the thread library, unused on Linux
*/
typedef struct { } Native_utcb;
/*
* On Linux, the local_name member of a capability is global
* to the whole system. Therefore, capabilities are to be
* created at a central place that prevents id clashes.
*/
class Native_capability
{
protected:
long _tid; /* target thread */
long _local_name;
protected:
Native_capability(void* ptr) : _local_name((long)ptr) { }
public:
/**
* Default constructor
*/
Native_capability() : _tid(0), _local_name(0) { }
long local_name() const { return _local_name; }
void* local() const { return (void*)_local_name; }
bool valid() const { return _tid != 0; }
/****************************************************
** Functions to be used by the Linux backend only **
****************************************************/
/**
* Constructor
*
* This constructor can be called to create a Linux
* capability by hand. It must never be used from
* generic code!
*/
Native_capability(long tid, long local_name)
: _tid(tid), _local_name(local_name) { }
/**
* Access raw capability data
*/
long dst() const { return _tid; }
long tid() const { return _tid; }
/**
* Copy this capability to another pd.
*/
void copy_to(void* dst) {
memcpy(dst, this, sizeof(Native_capability)); }
};
typedef Native_capability_tpl<long, Thread_id_check> Native_capability;
typedef int Native_connection_state; /* socket descriptor */
}

View File

@ -14,8 +14,8 @@
#ifndef _INCLUDE__BASE__NATIVE_TYPES_H_
#define _INCLUDE__BASE__NATIVE_TYPES_H_
#include <util/string.h>
#include <kernel/types.h>
#include <base/native_capability.h>
namespace Genode {
@ -30,41 +30,17 @@ namespace Genode {
Native_thread_id my_thread_id();
class Native_capability
struct Thread_id_check
{
private:
Native_thread_id _tid;
long _local_name;
protected:
Native_capability(void* ptr) : _local_name((long)ptr) {}
public:
Native_capability() : _tid(0), _local_name(0) { }
Native_capability(Native_thread_id tid, long local_name)
: _tid(tid), _local_name(local_name) { }
bool valid() const { return _tid!=0; }
int local_name() const { return _local_name; }
void* local() const { return (void*)_local_name; }
int dst() const { return (int)_tid; }
Native_thread_id tid() const { return _tid; }
/**
* Copy this capability to another pd.
*/
void copy_to(void* dst) {
memcpy(dst, this, sizeof(Native_capability)); }
static bool valid(Kernel::Thread_id tid) {
return tid != Kernel::INVALID_THREAD_ID; }
static Kernel::Thread_id invalid()
{ return Kernel::INVALID_THREAD_ID; }
};
typedef Native_capability_tpl<Kernel::Thread_id,Thread_id_check> Native_capability;
typedef int Native_connection_state;
}

View File

@ -19,9 +19,9 @@
inline void Genode::Ipc_ostream::_marshal_capability(Genode::Native_capability const &cap)
{
long unique_id = cap.unique_id();
long unique_id = cap.local_name();
_write_to_buf(unique_id);
_snd_msg->snd_append_pt_sel(cap.pt_sel());
_snd_msg->snd_append_pt_sel(cap.tid());
}

View File

@ -14,7 +14,7 @@
#ifndef _INCLUDE__BASE__NATIVE_TYPES_H_
#define _INCLUDE__BASE__NATIVE_TYPES_H_
#include <util/string.h>
#include <base/native_capability.h>
namespace Genode {
@ -53,48 +53,13 @@ namespace Genode {
long _utcb[UTCB_SIZE/sizeof(long)];
};
class Native_capability
struct Portal_checker
{
private:
int _pt_sel;
int _unique_id;
protected:
Native_capability(void* ptr) : _unique_id((int)ptr) {}
public:
/**
* Default constructor creates an invalid capability
*/
Native_capability() : _pt_sel(0), _unique_id(0) { }
/**
* Construct capability manually
*
* This constructor should be called only from the platform-specific
* part of the Genode framework.
*/
Native_capability(int pt_sel, int unique_id)
: _pt_sel(pt_sel), _unique_id(unique_id) { }
bool valid() const { return _pt_sel != 0 && _unique_id != 0; }
int local_name() const { return _unique_id; }
void* local() const { return (void*)_unique_id; }
int dst() const { return _pt_sel; }
int unique_id() const { return _unique_id; }
int pt_sel() const { return _pt_sel; }
/**
* Copy this capability to another pd.
*/
void copy_to(void* dst) {
memcpy(dst, this, sizeof(Native_capability)); }
static bool valid(int pt) { return pt != 0; }
static int invalid() { return 0; }
};
typedef Native_capability_tpl<int, Portal_checker> Native_capability;
typedef int Native_connection_state;
}

View File

@ -67,7 +67,7 @@ namespace Genode {
_init_sem();
/* block on semaphore, will be unblocked if signal is available */
Nova::sm_ctrl(_sem.pt_sel(), Nova::SEMAPHORE_DOWN);
Nova::sm_ctrl(_sem.tid(), Nova::SEMAPHORE_DOWN);
/*
* Now that the server has unblocked the semaphore, we are sure

View File

@ -138,9 +138,9 @@ void Ipc_client::_call()
_rcv_msg->rcv_prepare_pt_sel_window(utcb);
/* establish the mapping via a portal traversal */
if (_dst.pt_sel() == 0)
if (_dst.tid() == 0)
PWRN("destination portal is zero");
int res = Nova::call(_dst.pt_sel());
int res = Nova::call(_dst.tid());
if (res)
PERR("call returned %d", res);

View File

@ -49,7 +49,7 @@ static void request_event_portal(Pager_capability pager_cap,
utcb->set_msg_word(1);
utcb->crd_rcv = Obj_crd(exc_base + event, 0);
int res = call(pager_cap.pt_sel());
int res = call(pager_cap.tid());
if (res)
PERR("request of event (%d) capability selector failed", event);

View File

@ -38,7 +38,7 @@ namespace Genode {
{
Lock::Guard lock_guard(_lock());
return Native_capability(ep.pt_sel(), ++_unique_id_cnt);
return Native_capability(ep.tid(), ++_unique_id_cnt);
}
void free(Native_capability cap) { }

View File

@ -63,7 +63,7 @@ namespace Genode {
/**
* Return portal capability selector for parent interface
*/
int parent_pt_sel() { return _parent.pt_sel(); }
int parent_pt_sel() { return _parent.tid(); }
/**
* Assign PD selector to PD

View File

@ -40,7 +40,7 @@ void Signal_source_component::submit(Signal_context_component *context,
_signal_queue.enqueue(context);
/* wake up client */
Nova::sm_ctrl(_blocking_semaphore.pt_sel(), Nova::SEMAPHORE_UP);
Nova::sm_ctrl(_blocking_semaphore.tid(), Nova::SEMAPHORE_UP);
}
}

View File

@ -39,7 +39,7 @@ namespace Genode {
/* assemble parent capability from object ID and portal */
return reinterpret_cap_cast<Parent>(Native_capability(Nova::PT_SEL_PARENT,
cap.unique_id()));
cap.local_name()));
}
}

View File

@ -14,7 +14,7 @@
#ifndef _INCLUDE__BASE__NATIVE_TYPES_H_
#define _INCLUDE__BASE__NATIVE_TYPES_H_
#include <util/string.h>
#include <base/native_capability.h>
namespace Okl4 { extern "C" {
#include <l4/types.h>
@ -78,63 +78,15 @@ namespace Genode {
*/
typedef struct { } Native_utcb;
/*
* On OKL4, the local_name member of a capability is global to the whole
* system. Therefore, capabilities are to be created at a central place
* that prevents id clashes.
*/
class Native_capability
struct Thread_id_checker
{
protected:
Okl4::L4_ThreadId_t _tid;
long _local_name;
protected:
Native_capability(void* ptr) : _local_name((long)ptr) {}
public:
/**
* Default constructor
*/
Native_capability() : _local_name(0) {
_tid = Okl4::L4_nilthread; }
long local_name() const { return _local_name; }
Okl4::L4_ThreadId_t dst() const { return _tid; }
void* local() const { return (void*)_local_name; }
bool valid() const { return !Okl4::L4_IsNilThread(_tid); }
/********************************************************
** Functions to be used by the Pistachio backend only **
********************************************************/
/**
* Constructor
*
* Creates a L4 capability manually. This must not be called from
* generic code.
*/
Native_capability(Okl4::L4_ThreadId_t tid, long local_name)
: _tid(tid), _local_name(local_name) { }
/**
* Access raw capability data
*/
Okl4::L4_ThreadId_t tid() const { return _tid; };
/**
* Copy this capability to another pd.
*/
void copy_to(void* dst) {
memcpy(dst, this, sizeof(Native_capability)); }
static bool valid(Okl4::L4_ThreadId_t tid) {
return !Okl4::L4_IsNilThread(tid); }
static Okl4::L4_ThreadId_t invalid() { return Okl4::L4_nilthread; }
};
typedef Native_capability_tpl<Okl4::L4_ThreadId_t,
Thread_id_checker> Native_capability;
typedef Okl4::L4_ThreadId_t Native_connection_state;
}

View File

@ -14,10 +14,16 @@
#ifndef _INCLUDE__BASE__NATIVE_TYPES_H_
#define _INCLUDE__BASE__NATIVE_TYPES_H_
#include <util/string.h>
#include <base/native_capability.h>
namespace Pistachio {
#include <l4/types.h>
struct Thread_id_checker
{
static bool valid(L4_ThreadId_t tid) { return !L4_IsNilThread(tid); }
static L4_ThreadId_t invalid() { return L4_nilthread; }
};
}
namespace Genode {
@ -59,66 +65,8 @@ namespace Genode {
*/
typedef struct { } Native_utcb;
/*
* On Pistachio, the local_name member of a capability is global to the
* whole system. Therefore, capabilities are to be created at a central
* place that prevents id clashes.
*/
class Native_capability
{
protected:
Pistachio::L4_ThreadId_t _tid;
long _local_name;
protected:
Native_capability(void* ptr) : _local_name((long)ptr) {}
public:
/**
* Default constructor
*/
Native_capability() : _local_name (0)
{
using namespace Pistachio;
_tid = L4_nilthread;
}
long local_name() const { return _local_name; }
Pistachio::L4_ThreadId_t dst() const { return _tid; }
void* local() const { return (void*)_local_name; }
bool valid() const { return !Pistachio::L4_IsNilThread(_tid); }
/********************************************************
** Functions to be used by the Pistachio backend only **
********************************************************/
/**
* Constructor
*
* Creates a L4 capability manually. This must not be called from
* generic code.
*/
Native_capability(Pistachio::L4_ThreadId_t tid, long local_name)
: _tid(tid), _local_name(local_name) { }
/**
* Access raw capability data
*/
Pistachio::L4_ThreadId_t tid() const { return _tid; };
/**
* Copy this capability to another pd.
*/
void copy_to(void* dst) {
memcpy(dst, this, sizeof(Native_capability)); }
};
typedef Native_capability_tpl<Pistachio::L4_ThreadId_t,
Pistachio::Thread_id_checker> Native_capability;
typedef Pistachio::L4_ThreadId_t Native_connection_state;
}

View File

@ -0,0 +1,98 @@
/*
* \brief Native capability template.
* \author Stefan Kalkowski
* \date 2011-03-07
*
* This file is a generic variant of the Native_capability, which is
* suitable many platforms such as Fiasco, Pistachio, OKL4, Linux, Codezero,
* and some more.
*/
/*
* Copyright (C) 2012 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__BASE__NATIVE_CAPABILITY_H_
#define _INCLUDE__BASE__NATIVE_CAPABILITY_H_
#include <util/string.h>
namespace Genode {
template <typename ID, typename T>
class Native_capability_tpl
{
private:
ID _tid;
long _local_name;
protected:
/**
* Constructor for a local capability.
*
* A local capability just encapsulates a pointer to some
* local object. This constructor is only used by a factory
* method for local-capabilities in the generic Capability
* class.
*
* \param ptr address of the local object.
*/
Native_capability_tpl(void* ptr)
: _tid(T::invalid()), _local_name((long)ptr) { }
public:
/**
* Constructor for an invalid capability.
*/
Native_capability_tpl() : _tid(T::invalid()), _local_name(0) { }
/**
* Publicly available constructor.
*
* \param tid kernel-specific thread id
* \param local_name global, unique id of the cap.
*/
Native_capability_tpl(ID tid, long local_name)
: _tid(tid), _local_name(local_name) {}
/**
* \return true when the capability is a valid one, otherwise false.
*/
bool valid() const { return T::valid(_tid); }
/**
* \return the globally unique id.
*/
long local_name() const { return _local_name; }
/**
* \return true if this is a local-capability, otherwise false.
*/
void* local() const { return (void*)_local_name; }
/**
* Copy this capability to another pd.
*/
void copy_to(void* dst) {
memcpy(dst, this, sizeof(Native_capability_tpl)); }
/*****************************************
** Only used by platform-specific code **
*****************************************/
/**
* \return the kernel-specific thread specifier.
*/
ID tid() const { return _tid; }
};
}
#endif /* _INCLUDE__BASE__NATIVE_CAPABILITY_H_ */