Replace 'Native_capability::copy_to' by accessor

The 'copy_to' function turned out to be not flexible enough to
accommodate the Noux fork mechanism. This patch removes the function,
adds an accessor for the capability destination and a compound type
'Native_capability::Raw' to be used wherever plain capability
information must be communicated.
This commit is contained in:
Norman Feske 2012-03-26 14:32:16 +02:00
parent 22084dbfa5
commit d6e30c19de
18 changed files with 119 additions and 87 deletions

View File

@ -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.dst();
_rcv_cs = Ipc_ostream::_dst.dst();
_wait();
_rcv_cs = L4_ANYTHREAD;
@ -144,7 +144,7 @@ void Ipc_server::_wait()
try { Ipc_istream::_wait(); } catch (Blocking_canceled) { }
/* define destination of next reply */
_dst = Native_capability(l4_get_sender(), badge());
Ipc_ostream::_dst = Native_capability(l4_get_sender(), badge());
_prepare_next_reply_wait();
}

View File

@ -120,9 +120,9 @@ void Ipc_client::_call()
_snd_msg->send_dope = L4_IPC_DOPE((_write_offset + 2*sizeof(umword_t) - 1)>>2, 0);
_rcv_msg->size_dope = L4_IPC_DOPE(_rcv_msg->size()>>2, 0);
l4_ipc_call(_dst.dst(),
l4_ipc_call(Ipc_ostream::_dst.dst(),
_write_offset <= 2*sizeof(umword_t) ? L4_IPC_SHORT_MSG : _snd_msg->addr(),
_dst.local_name(),
Ipc_ostream::_dst.local_name(),
*reinterpret_cast<l4_umword_t *>(&_snd_msg->buf[sizeof(umword_t)]),
_rcv_msg->addr(),
reinterpret_cast<l4_umword_t *>(&rec_badge),
@ -180,7 +180,7 @@ void Ipc_server::_wait()
try { Ipc_istream::_wait(); } catch (Blocking_canceled) { }
/* define destination of next reply */
_dst = Native_capability(_rcv_cs, badge());
Ipc_ostream::_dst = Native_capability(_rcv_cs, badge());
_prepare_next_reply_wait();
}
@ -193,7 +193,8 @@ void Ipc_server::_reply()
_snd_msg->send_dope = L4_IPC_DOPE((_write_offset + sizeof(umword_t) - 1)>>2, 0);
l4_msgdope_t result;
l4_ipc_send(_dst.dst(), _snd_msg->addr(), _dst.local_name(),
l4_ipc_send(Ipc_ostream::_dst.dst(), _snd_msg->addr(),
Ipc_ostream::_dst.local_name(),
*reinterpret_cast<l4_umword_t *>(&_snd_msg->buf[sizeof(umword_t)]),
L4_IPC_SEND_TIMEOUT_0, &result);
@ -221,9 +222,9 @@ void Ipc_server::_reply_wait()
* an integer as RPC result.
*/
l4_ipc_reply_and_wait(
_dst.dst(),
Ipc_ostream::_dst.dst(),
_write_offset <= 2*sizeof(umword_t) ? L4_IPC_SHORT_MSG : _snd_msg->addr(),
_dst.local_name(),
Ipc_ostream::_dst.local_name(),
*reinterpret_cast<l4_umword_t *>(&_snd_msg->buf[sizeof(umword_t)]),
&_rcv_cs, _rcv_msg->addr(),
reinterpret_cast<l4_umword_t *>(&_rcv_msg->buf[0]),
@ -247,7 +248,7 @@ void Ipc_server::_reply_wait()
} else _wait();
/* define destination of next reply */
_dst = Native_capability(_rcv_cs, badge());
Ipc_ostream::_dst = Native_capability(_rcv_cs, badge());
_prepare_next_reply_wait();
}

View File

@ -105,7 +105,6 @@ Pager_capability Pager_entrypoint::manage(Pager_object *obj)
/* return invalid capability if no activation is present */
if (!_activation) return Pager_capability();
Native_thread_id tid = _activation->cap().dst();
Native_capability cap(_activation->cap().dst(), obj->badge());
/* add server object to object pool */

View File

@ -53,17 +53,21 @@ namespace Genode {
*/
class Native_capability
{
public:
typedef Fiasco::l4_cap_idx_t Dst;
struct Raw
{
Dst dst;
long local_name;
};
private:
Cap_index* _idx;
void* _ptr;
inline Native_thread_id _cap_sel() const
{
return _idx ? Native_thread_id(_idx->kcap())
: Native_thread_id();
}
protected:
/**
@ -102,11 +106,10 @@ namespace Genode {
** Interface provided by all platforms **
*******************************************/
int local_name() const { return _idx ? _idx->id() : 0; }
Native_thread dst() const { return _cap_sel(); }
bool valid() const { return (_idx != 0) && _idx->valid(); }
void* local() const { return _ptr; }
void copy_to(void* dst) { *((int*)dst) = local_name(); }
int local_name() const { return _idx ? _idx->id() : 0; }
Dst dst() const { return _idx ? Dst(_idx->kcap()) : Dst(); }
bool valid() const { return (_idx != 0) && _idx->valid(); }
void *local() const { return _ptr; }
};

View File

@ -21,10 +21,22 @@ namespace Genode {
/**
* Return constructed parent capability
*/
Parent_capability parent_cap() {
static Cap_index* i = cap_map()->insert(*((int*)&_parent_cap),
Parent_capability parent_cap()
{
Native_capability::Raw *raw = (Native_capability::Raw *)&_parent_cap;
static Cap_index *i = cap_map()->insert(raw->local_name,
Fiasco::PARENT_CAP);
return reinterpret_cap_cast<Parent>(Native_capability(i)); }
/*
* Update local name after a parent capability got reloaded via
* 'Platform_env::reload_parent_cap()'.
*/
if (i->id() != raw->local_name)
i->id(raw->local_name);
return reinterpret_cap_cast<Parent>(Native_capability(i));
}
}
#endif /* _PLATFORM__MAIN_PARENT_CAP_H_ */

View File

@ -364,7 +364,7 @@ namespace Genode {
/**
* Reload parent capability and reinitialize environment resources
*/
void reload_parent_cap(Capability<Parent>)
void reload_parent_cap(Capability<Parent>::Dst, long)
{
/* not supported on Linux */
}

View File

@ -107,7 +107,7 @@ Ipc_istream::~Ipc_istream() { }
void Ipc_client::_prepare_next_call()
{
/* prepare next request in buffer */
long local_name = _dst.local_name();
long local_name = Ipc_ostream::_dst.local_name();
long tid = Native_capability::dst();
_write_offset = 0;
@ -121,8 +121,8 @@ void Ipc_client::_prepare_next_call()
void Ipc_client::_call()
{
if (_dst.valid()) {
lx_send_to(_rcv_cs, _dst.dst(), "server",
if (Ipc_ostream::_dst.valid()) {
lx_send_to(_rcv_cs, Ipc_ostream::_dst.dst(), "server",
_snd_msg->buf, _write_offset);
lx_recv_from(_rcv_cs, _rcv_msg->buf, _rcv_msg->size());
@ -154,12 +154,12 @@ void Ipc_server::_prepare_next_reply_wait()
long tid;
if (_reply_needed) {
_read_from_buf(tid);
_dst = Native_capability(tid, 0); /* only _tid member is used */
Ipc_ostream::_dst = Native_capability(tid, 0); /* only _tid member is used */
}
/* prepare next reply */
_write_offset = 0;
long local_name = _dst.local_name();
long local_name = Ipc_ostream::_dst.local_name();
_write_to_buf(local_name); /* XXX unused, needed by de/marshaller */
/* leave space for exc code at the beginning of the msgbuf */
@ -183,7 +183,8 @@ void Ipc_server::_wait()
void Ipc_server::_reply()
{
try {
lx_send_to(_rcv_cs, _dst.dst(), "client", _snd_msg->buf, _write_offset);
lx_send_to(_rcv_cs, Ipc_ostream::_dst.dst(), "client",
_snd_msg->buf, _write_offset);
} catch (Ipc_error) { }
_prepare_next_reply_wait();
@ -194,7 +195,8 @@ void Ipc_server::_reply_wait()
{
/* when first called, there was no request yet */
if (_reply_needed)
lx_send_to(_rcv_cs, _dst.dst(), "client", _snd_msg->buf, _write_offset);
lx_send_to(_rcv_cs, Ipc_ostream::_dst.dst(), "client",
_snd_msg->buf, _write_offset);
_wait();
}

View File

@ -128,9 +128,9 @@ Ipc_istream::~Ipc_istream() { }
void Ipc_client::_call()
{
unsigned request_size = _write_offset;
copy_msgbuf_to_utcb(_snd_msg, request_size, _dst.local_name());
copy_msgbuf_to_utcb(_snd_msg, request_size, Ipc_ostream::_dst.local_name());
unsigned reply_size = Kernel::ipc_request(_dst.dst(), request_size);
unsigned reply_size = Kernel::ipc_request(Ipc_ostream::_dst.dst(), request_size);
copy_utcb_to_msgbuf(reply_size, _rcv_msg);
@ -181,7 +181,7 @@ void Ipc_server::_reply_wait()
unsigned reply_size = 0;
if (_reply_needed) {
reply_size = _write_offset;
copy_msgbuf_to_utcb(_snd_msg, reply_size, _dst.local_name());
copy_msgbuf_to_utcb(_snd_msg, reply_size, Ipc_ostream::_dst.local_name());
}
unsigned request_size = Kernel::ipc_serve(reply_size);

View File

@ -134,13 +134,13 @@ void Ipc_client::_call()
Nova::Utcb *utcb = (Nova::Utcb *)Thread_base::myself()->utcb();
copy_msgbuf_to_utcb(utcb, _snd_msg, _write_offset/sizeof(mword_t),
_dst.local_name());
Ipc_ostream::_dst.local_name());
_rcv_msg->rcv_prepare_pt_sel_window(utcb);
/* establish the mapping via a portal traversal */
if (_dst.dst() == 0)
if (Ipc_ostream::_dst.dst() == 0)
PWRN("destination portal is zero");
int res = Nova::call(_dst.dst());
int res = Nova::call(Ipc_ostream::_dst.dst());
if (res)
PERR("call returned %d", res);
@ -185,7 +185,7 @@ void Ipc_server::_reply()
Nova::Utcb *utcb = (Nova::Utcb *)Thread_base::myself()->utcb();
copy_msgbuf_to_utcb(utcb, _snd_msg, _write_offset/sizeof(mword_t),
_dst.local_name());
Ipc_ostream::_dst.local_name());
Nova::reply(Thread_base::myself()->stack_top());
}

View File

@ -183,10 +183,10 @@ void Ipc_client::_call()
{
/* copy call message to the UTCBs message registers */
copy_msgbuf_to_utcb(_snd_msg, _write_offset/sizeof(L4_Word_t),
_dst.local_name());
Ipc_ostream::_dst.local_name());
L4_Accept(L4_UntypedWordsAcceptor);
L4_MsgTag_t rcv_tag = L4_Call(_dst.dst());
L4_MsgTag_t rcv_tag = L4_Call(Ipc_ostream::_dst.dst());
enum { ERROR_MASK = 0xe, ERROR_CANCELED = 3 << 1 };
if (L4_IpcFailed(rcv_tag) &&
@ -231,7 +231,7 @@ void Ipc_server::_wait()
try { Ipc_istream::_wait(); } catch (Blocking_canceled) { }
/* define destination of next reply */
_dst = Native_capability(_rcv_cs, badge());
Ipc_ostream::_dst = Native_capability(_rcv_cs, badge());
_prepare_next_reply_wait();
}
@ -241,10 +241,10 @@ void Ipc_server::_reply()
{
/* copy reply to the UTCBs message registers */
copy_msgbuf_to_utcb(_snd_msg, _write_offset/sizeof(L4_Word_t),
_dst.local_name());
Ipc_ostream::_dst.local_name());
/* perform non-blocking IPC send operation */
L4_MsgTag_t rcv_tag = L4_Reply(_dst.dst());
L4_MsgTag_t rcv_tag = L4_Reply(Ipc_ostream::_dst.dst());
if (L4_IpcFailed(rcv_tag))
PERR("ipc error in _reply - gets ignored");
@ -259,9 +259,9 @@ void Ipc_server::_reply_wait()
/* copy reply to the UTCBs message registers */
copy_msgbuf_to_utcb(_snd_msg, _write_offset/sizeof(L4_Word_t),
_dst.local_name());
Ipc_ostream::_dst.local_name());
L4_MsgTag_t rcv_tag = L4_ReplyWait(_dst.dst(), &_rcv_cs);
L4_MsgTag_t rcv_tag = L4_ReplyWait(Ipc_ostream::_dst.dst(), &_rcv_cs);
/*
* TODO: Check for IPC error
@ -271,7 +271,7 @@ void Ipc_server::_reply_wait()
copy_utcb_to_msgbuf(rcv_tag, _rcv_msg);
/* define destination of next reply */
_dst = Native_capability(_rcv_cs, badge());
Ipc_ostream::_dst = Native_capability(_rcv_cs, badge());
_prepare_next_reply_wait();

View File

@ -1,4 +1,7 @@
SRC_CC = ipc.cc pager.cc
LIBS = cap_copy
SRC_CC = ipc.cc pager.cc
LIBS = cap_copy
# disable warning about array boundaries, caused by L4 headers
CC_WARN = -Wall -Wno-array-bounds
vpath %.cc $(REP_DIR)/src/base/ipc

View File

@ -47,11 +47,11 @@ using namespace Pistachio;
void Ipc_ostream::_send()
{
IPCDEBUG("_send to 0x%08lx.\n", _dst.dst().raw);
IPCDEBUG("_send to 0x%08lx.\n", Ipc_ostream::_dst.dst().raw);
L4_Msg_t msg;
L4_StringItem_t sitem = L4_StringItem(_write_offset, _snd_msg->buf);
L4_Word_t local_name = _dst.local_name();
L4_Word_t local_name = Ipc_ostream::_dst.local_name();
L4_Clear(&msg);
@ -59,7 +59,7 @@ void Ipc_ostream::_send()
L4_Append(&msg, sitem);
L4_Load(&msg);
L4_MsgTag_t result = L4_Send(_dst.dst());
L4_MsgTag_t result = L4_Send(Ipc_ostream::_dst.dst());
/*
* Error indicator
@ -190,7 +190,7 @@ void Ipc_client::_call()
IPCDEBUG("Starting to _call (with %u bytes of data).\n", _write_offset);
L4_Msg_t msg;
L4_StringItem_t sitem = L4_StringItem(_write_offset, _snd_msg->buf);
L4_Word_t local_name = _dst.local_name();
L4_Word_t local_name = Ipc_ostream::_dst.local_name();
IPCDEBUG("Destination local_name = 0x%x\n", local_name);
@ -208,7 +208,7 @@ void Ipc_client::_call()
L4_Append(&msg, sitem);
L4_Load(&msg);
L4_MsgTag_t result = L4_Call(_dst.dst());
L4_MsgTag_t result = L4_Call(Ipc_ostream::_dst.dst());
_write_offset = _read_offset = sizeof(umword_t);
@ -249,7 +249,7 @@ void Ipc_server::_wait()
try { Ipc_istream::_wait(); } catch (Blocking_canceled) { }
/* define destination of next reply */
_dst = Native_capability(_rcv_cs, badge());
Ipc_ostream::_dst = Native_capability(_rcv_cs, badge());
_prepare_next_reply_wait();
}
@ -259,14 +259,14 @@ void Ipc_server::_reply()
{
L4_Msg_t msg;
L4_StringItem_t sitem = L4_StringItem(_write_offset, _snd_msg->buf);
L4_Word_t local_name = _dst.local_name();
L4_Word_t local_name = Ipc_ostream::_dst.local_name();
L4_Clear(&msg);
L4_Append(&msg, local_name);
L4_Append(&msg, sitem);
L4_Load(&msg);
L4_MsgTag_t result = L4_Reply(_dst.dst());
L4_MsgTag_t result = L4_Reply(Ipc_ostream::_dst.dst());
if (L4_IpcFailed(result))
PERR("ipc error in _reply, ignored");
@ -284,7 +284,7 @@ void Ipc_server::_reply_wait()
/* prepare massage */
L4_Msg_t msg;
L4_StringItem_t sitem = L4_StringItem(_write_offset, _snd_msg->buf);
L4_Word_t local_name = _dst.local_name();
L4_Word_t local_name = Ipc_ostream::_dst.local_name();
L4_Clear(&msg);
L4_Append(&msg, local_name);
@ -298,7 +298,8 @@ void Ipc_server::_reply_wait()
L4_Accept(L4_UntypedWordsAcceptor);
L4_Accept(L4_StringItemsAcceptor, &msgbuf);
L4_MsgTag_t result = L4_Ipc(_dst.dst(), L4_anythread, L4_Timeouts(L4_ZeroTime, L4_Never), &_rcv_cs);
L4_MsgTag_t result = L4_Ipc(Ipc_ostream::_dst.dst(), L4_anythread,
L4_Timeouts(L4_ZeroTime, L4_Never), &_rcv_cs);
IPCDEBUG("Got something from 0x%x.\n", L4_ThreadNo(L4_GlobalId(_rcv_cs)));
/* error handling - check whether send or receive failed */
@ -339,7 +340,7 @@ void Ipc_server::_reply_wait()
IPCDEBUG("local_name = 0x%lx\n", badge());
/* define destination of next reply */
_dst = Native_capability(_rcv_cs, badge());
Ipc_ostream::_dst = Native_capability(_rcv_cs, badge());
_prepare_next_reply_wait();

View File

@ -43,11 +43,22 @@ namespace Genode {
template <typename POLICY>
class Native_capability_tpl
{
private:
public:
typedef typename POLICY::Dst Dst;
Dst _tid;
/**
* Compound object used to copy raw capability members
*
* This type is a utility solely used to communicate the
* information about the parent capability from the parent to the
* new process.
*/
struct Raw { Dst dst; long local_name; };
private:
Dst _dst;
long _local_name;
protected:
@ -63,14 +74,14 @@ namespace Genode {
* \param ptr address of the local object
*/
Native_capability_tpl(void* ptr)
: _tid(POLICY::invalid()), _local_name((long)ptr) { }
: _dst(POLICY::invalid()), _local_name((long)ptr) { }
public:
/**
* Constructor for an invalid capability
*/
Native_capability_tpl() : _tid(POLICY::invalid()), _local_name(0) { }
Native_capability_tpl() : _dst(POLICY::invalid()), _local_name(0) { }
/**
* Publicly available constructor
@ -80,12 +91,12 @@ namespace Genode {
* that corresponds to the capability.
*/
Native_capability_tpl(Dst tid, long local_name)
: _tid(tid), _local_name(local_name) { }
: _dst(tid), _local_name(local_name) { }
/**
* Return true when the capability is valid
*/
bool valid() const { return POLICY::valid(_tid); }
bool valid() const { return POLICY::valid(_dst); }
/**
* Return ID used to lookup the 'Rpc_object' by its capability
@ -98,19 +109,9 @@ namespace Genode {
void* local() const { return (void*)_local_name; }
/**
* Copy this capability to another PD
* Return capability destination
*/
void copy_to(void* dst) { POLICY::copy(dst, this); }
/*****************************************
** Only used by platform-specific code **
*****************************************/
/**
* Return the kernel-specific capability destination
*/
Dst dst() const { return _tid; }
Dst dst() const { return _dst; }
};
}

View File

@ -154,7 +154,7 @@ namespace Genode {
* meaningful capabilities obtained via its updated parent
* capability.
*/
void reload_parent_cap(Capability<Parent>);
void reload_parent_cap(Native_capability::Dst, long);
/*******************

View File

@ -15,7 +15,8 @@
#include <base/crt0.h>
void Genode::Platform_env::reload_parent_cap(Capability<Parent> parent_cap)
void Genode::Platform_env::reload_parent_cap(Native_capability::Dst dst,
long local_name)
{
/*
* This function is unused during the normal operation of Genode. It is
@ -35,7 +36,10 @@ void Genode::Platform_env::reload_parent_cap(Capability<Parent> parent_cap)
* Patch new parent capability into the original location as specified by
* the linker script.
*/
*(Capability<Parent> *)(&_parent_cap) = parent_cap;
Native_capability::Raw *raw = (Native_capability::Raw *)(&_parent_cap);
raw->dst = dst;
raw->local_name = local_name;
/*
* Re-initialize 'Platform_env' members

View File

@ -122,7 +122,11 @@ static addr_t _setup_elf(Parent_capability parent_cap,
* data segment
*/
if (!parent_info) {
parent_cap.copy_to(ptr);
Native_capability::Raw *raw = (Native_capability::Raw *)ptr;
raw->dst = parent_cap.dst();
raw->local_name = parent_cap.local_name();
parent_info = true;
}

View File

@ -327,7 +327,7 @@ extern "C" int select(int nfds, fd_set *readfds, fd_set *writefds,
static jmp_buf fork_jmp_buf;
static Genode::Capability<Genode::Parent> new_parent_cap;
static Genode::Capability<Genode::Parent>::Raw new_parent;
extern "C" void stdout_reconnect(); /* provided by 'log_console.cc' */
@ -337,7 +337,8 @@ extern "C" void stdout_reconnect(); /* provided by 'log_console.cc' */
*/
extern "C" void fork_trampoline()
{
static_cast<Genode::Platform_env *>(Genode::env())->reload_parent_cap(new_parent_cap);
static_cast<Genode::Platform_env *>(Genode::env())
->reload_parent_cap(new_parent.dst, new_parent.local_name);
stdout_reconnect();
noux_connection()->reconnect();
@ -364,7 +365,7 @@ extern "C" pid_t fork(void)
/* got here during the normal control flow of the fork call */
sysio()->fork_in.ip = (Genode::addr_t)(&fork_trampoline);
sysio()->fork_in.sp = (Genode::addr_t)(&stack[STACK_SIZE]);
sysio()->fork_in.parent_cap_addr = (Genode::addr_t)(&new_parent_cap);
sysio()->fork_in.parent_cap_addr = (Genode::addr_t)(&new_parent);
if (!noux()->syscall(Noux::Session::SYSCALL_FORK)) {
PERR("fork error %d", sysio()->error.general);

View File

@ -324,8 +324,9 @@ namespace Noux {
void start_forked_main_thread(addr_t ip, addr_t sp, addr_t parent_cap_addr)
{
/* poke parent_cap_addr into child's address space */
Parent_capability const cap = _child.parent_cap();
_resources.rm.poke(parent_cap_addr, &cap, sizeof(cap));
Capability<Parent> const &cap = _child.parent_cap();
Capability<Parent>::Raw raw = { cap.dst(), cap.local_name() };
_resources.rm.poke(parent_cap_addr, &raw, sizeof(raw));
/* start execution of new main thread at supplied trampoline */
_resources.cpu.start_main_thread(ip, sp);