From 47878bd3e1aae7727eda7a3032f1c22d94003281 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Sun, 13 Mar 2016 22:55:48 +0100 Subject: [PATCH] Remove 'Ipc_istream' and 'Ipc_ostream' from API Fixes #610 --- repos/base-fiasco/include/base/ipc_msgbuf.h | 7 +- repos/base-fiasco/src/base/ipc/ipc.cc | 117 ++-- repos/base-foc/include/base/ipc_msgbuf.h | 4 +- repos/base-foc/src/base/ipc/ipc.cc | 128 ++--- repos/base-foc/src/base/server/server.cc | 13 +- repos/base-foc/src/core/platform_thread.cc | 5 +- repos/base-hw/include/base/ipc_msgbuf.h | 4 +- repos/base-hw/src/base/ipc/ipc.cc | 119 ++-- repos/base-hw/src/base/server/server.cc | 7 +- repos/base-linux/include/base/ipc_msgbuf.h | 4 +- repos/base-linux/src/base/ipc/ipc.cc | 126 ++--- repos/base-nova/include/base/ipc_msgbuf.h | 4 +- repos/base-nova/src/base/ipc/ipc.cc | 96 ++-- repos/base-nova/src/base/server/server.cc | 9 +- repos/base-okl4/include/base/ipc_msgbuf.h | 4 +- repos/base-okl4/src/base/ipc/ipc.cc | 122 ++-- .../base-pistachio/include/base/ipc_msgbuf.h | 7 +- repos/base-pistachio/src/base/ipc/ipc.cc | 124 ++--- repos/base-sel4/src/base/ipc/ipc.cc | 94 ++-- repos/base-sel4/src/base/server/server.cc | 7 +- repos/base/include/base/ipc.h | 522 ++++-------------- repos/base/include/base/rpc_client.h | 11 +- repos/base/include/base/rpc_server.h | 51 +- repos/base/src/base/ipc/ipc_marshal_cap.cc | 10 +- repos/base/src/base/server/common.cc | 13 +- repos/base/src/base/server/server.cc | 7 +- repos/base/src/core/pager_object.cc | 5 +- 27 files changed, 544 insertions(+), 1076 deletions(-) diff --git a/repos/base-fiasco/include/base/ipc_msgbuf.h b/repos/base-fiasco/include/base/ipc_msgbuf.h index 3a1fdf3bf..08d553ec0 100644 --- a/repos/base-fiasco/include/base/ipc_msgbuf.h +++ b/repos/base-fiasco/include/base/ipc_msgbuf.h @@ -44,7 +44,12 @@ namespace Genode { /** * Return address of message buffer */ - inline void *addr() { return &rcv_fpage; }; + inline void *msg_start() { return &rcv_fpage; }; + + /** + * Return pointer of message data payload + */ + inline void *data() { return buf; }; }; diff --git a/repos/base-fiasco/src/base/ipc/ipc.cc b/repos/base-fiasco/src/base/ipc/ipc.cc index fffc92148..85c19f553 100644 --- a/repos/base-fiasco/src/base/ipc/ipc.cc +++ b/repos/base-fiasco/src/base/ipc/ipc.cc @@ -29,35 +29,6 @@ namespace Fiasco { using namespace Genode; -/***************** - ** Ipc_ostream ** - *****************/ - -Ipc_ostream::Ipc_ostream(Native_capability dst, Msgbuf_base *snd_msg) : - Ipc_marshaller(&snd_msg->buf[0], snd_msg->size()), - _snd_msg(snd_msg), _dst(dst) -{ - _write_offset = sizeof(umword_t); -} - - -/***************** - ** Ipc_istream ** - *****************/ - -Ipc_istream::Ipc_istream(Msgbuf_base *rcv_msg): - Ipc_unmarshaller(&rcv_msg->buf[0], rcv_msg->size()), - Native_capability(Fiasco::l4_myself(), 0), - _rcv_msg(rcv_msg) -{ - using namespace Fiasco; - _read_offset = sizeof(umword_t); -} - - -Ipc_istream::~Ipc_istream() { } - - /**************** ** Ipc_client ** ****************/ @@ -69,16 +40,16 @@ void Ipc_client::_call() l4_msgdope_t ipc_result; long rec_badge; - _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); + _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(Ipc_ostream::_dst.dst(), - _write_offset <= 2*sizeof(umword_t) ? L4_IPC_SHORT_MSG : _snd_msg->addr(), - Ipc_ostream::_dst.local_name(), - *reinterpret_cast(&_snd_msg->buf[sizeof(umword_t)]), - _rcv_msg->addr(), + l4_ipc_call(_dst.dst(), + _write_offset <= 2*sizeof(umword_t) ? L4_IPC_SHORT_MSG : _snd_msg.msg_start(), + _dst.local_name(), + *reinterpret_cast(&_snd_msg.buf[sizeof(umword_t)]), + _rcv_msg.msg_start(), reinterpret_cast(&rec_badge), - reinterpret_cast(&_rcv_msg->buf[sizeof(umword_t)]), + reinterpret_cast(&_rcv_msg.buf[sizeof(umword_t)]), L4_IPC_NEVER, &ipc_result); if (L4_IPC_IS_ERROR(ipc_result)) { @@ -103,10 +74,13 @@ void Ipc_client::_call() } -Ipc_client::Ipc_client(Native_capability const &srv, Msgbuf_base *snd_msg, - Msgbuf_base *rcv_msg, unsigned short): - Ipc_istream(rcv_msg), Ipc_ostream(srv, snd_msg), _result(0) -{ } +Ipc_client::Ipc_client(Native_capability const &dst, + Msgbuf_base &snd_msg, Msgbuf_base &rcv_msg, unsigned short) +: + Ipc_marshaller(snd_msg), Ipc_unmarshaller(rcv_msg), _result(0), _dst(dst) +{ + _read_offset = _write_offset = sizeof(umword_t); +} /**************** @@ -126,7 +100,7 @@ void Ipc_server::_prepare_next_reply_wait() } -void Ipc_server::_wait() +void Ipc_server::wait() { /* wait for new server request */ try { @@ -142,11 +116,11 @@ void Ipc_server::_wait() * client. The server does not bother. */ do { - _rcv_msg->size_dope = L4_IPC_DOPE(_rcv_msg->size()>>2, 0); + _rcv_msg.size_dope = L4_IPC_DOPE(_rcv_msg.size()>>2, 0); - l4_ipc_wait(&_rcv_cs.caller, _rcv_msg->addr(), - reinterpret_cast(&_rcv_msg->buf[0]), - reinterpret_cast(&_rcv_msg->buf[sizeof(umword_t)]), + l4_ipc_wait(&_rcv_cs.caller, _rcv_msg.msg_start(), + reinterpret_cast(&_rcv_msg.buf[0]), + reinterpret_cast(&_rcv_msg.buf[sizeof(umword_t)]), L4_IPC_NEVER, &result); if (L4_IPC_IS_ERROR(result)) @@ -160,22 +134,23 @@ void Ipc_server::_wait() } catch (Blocking_canceled) { } /* define destination of next reply */ - Ipc_ostream::_dst = Native_capability(_rcv_cs.caller, badge()); + _caller = Native_capability(_rcv_cs.caller, 0); + _badge = reinterpret_cast(&_rcv_msg.buf)[0]; _prepare_next_reply_wait(); } -void Ipc_server::_reply() +void Ipc_server::reply() { using namespace Fiasco; - _snd_msg->send_dope = L4_IPC_DOPE((_write_offset + sizeof(umword_t) - 1)>>2, 0); + _snd_msg.send_dope = L4_IPC_DOPE((_write_offset + sizeof(umword_t) - 1)>>2, 0); l4_msgdope_t result; - l4_ipc_send(Ipc_ostream::_dst.dst(), _snd_msg->addr(), - Ipc_ostream::_dst.local_name(), - *reinterpret_cast(&_snd_msg->buf[sizeof(umword_t)]), + l4_ipc_send(_caller.dst(), _snd_msg.msg_start(), + _caller.local_name(), + *reinterpret_cast(&_snd_msg.buf[sizeof(umword_t)]), L4_IPC_SEND_TIMEOUT_0, &result); if (L4_IPC_IS_ERROR(result)) @@ -185,7 +160,7 @@ void Ipc_server::_reply() } -void Ipc_server::_reply_wait() +void Ipc_server::reply_wait() { using namespace Fiasco; @@ -193,8 +168,8 @@ void Ipc_server::_reply_wait() l4_msgdope_t ipc_result; - _snd_msg->send_dope = L4_IPC_DOPE((_write_offset + sizeof(umword_t) - 1)>>2, 0); - _rcv_msg->size_dope = L4_IPC_DOPE(_rcv_msg->size()>>2, 0); + _snd_msg.send_dope = L4_IPC_DOPE((_write_offset + sizeof(umword_t) - 1)>>2, 0); + _rcv_msg.size_dope = L4_IPC_DOPE(_rcv_msg.size()>>2, 0); /* * Use short IPC for reply if possible. @@ -202,13 +177,13 @@ void Ipc_server::_reply_wait() * an integer as RPC result. */ l4_ipc_reply_and_wait( - Ipc_ostream::_dst.dst(), - _write_offset <= 2*sizeof(umword_t) ? L4_IPC_SHORT_MSG : _snd_msg->addr(), - Ipc_ostream::_dst.local_name(), - *reinterpret_cast(&_snd_msg->buf[sizeof(umword_t)]), - &_rcv_cs.caller, _rcv_msg->addr(), - reinterpret_cast(&_rcv_msg->buf[0]), - reinterpret_cast(&_rcv_msg->buf[sizeof(umword_t)]), + _caller.dst(), + _write_offset <= 2*sizeof(umword_t) ? L4_IPC_SHORT_MSG : _snd_msg.msg_start(), + _caller.local_name(), + *reinterpret_cast(&_snd_msg.buf[sizeof(umword_t)]), + &_rcv_cs.caller, _rcv_msg.msg_start(), + reinterpret_cast(&_rcv_msg.buf[0]), + reinterpret_cast(&_rcv_msg.buf[sizeof(umword_t)]), L4_IPC_SEND_TIMEOUT_0, &ipc_result); if (L4_IPC_IS_ERROR(ipc_result)) { @@ -222,24 +197,28 @@ void Ipc_server::_reply_wait() * the user but want to wait for the next proper incoming * message. So let's just wait now. */ - _wait(); + wait(); } - } else _wait(); + } else wait(); /* define destination of next reply */ - Ipc_ostream::_dst = Native_capability(_rcv_cs.caller, badge()); + _caller = Native_capability(_rcv_cs.caller, 0); + _badge = reinterpret_cast(_rcv_msg.buf)[0]; _prepare_next_reply_wait(); } Ipc_server::Ipc_server(Native_connection_state &cs, - Msgbuf_base *snd_msg, Msgbuf_base *rcv_msg) + Msgbuf_base &snd_msg, Msgbuf_base &rcv_msg) : - Ipc_istream(rcv_msg), - Ipc_ostream(Native_capability(), snd_msg), _reply_needed(false), _rcv_cs(cs) -{ } + Ipc_marshaller(snd_msg), Ipc_unmarshaller(rcv_msg), + Native_capability(Fiasco::l4_myself(), 0), + _reply_needed(false), _rcv_cs(cs) +{ + _read_offset = _write_offset = sizeof(umword_t); +} Ipc_server::~Ipc_server() { } diff --git a/repos/base-foc/include/base/ipc_msgbuf.h b/repos/base-foc/include/base/ipc_msgbuf.h index f582d2ec7..7550d7d2c 100644 --- a/repos/base-foc/include/base/ipc_msgbuf.h +++ b/repos/base-foc/include/base/ipc_msgbuf.h @@ -88,9 +88,9 @@ namespace Genode { inline size_t size() const { return _size; }; /** - * Return address of message buffer + * Return pointer of message data payload */ - inline void *addr() { return &_msg_start[0]; }; + inline void *data() { return &_msg_start[0]; }; /** * Reset portal capability selector payload diff --git a/repos/base-foc/src/base/ipc/ipc.cc b/repos/base-foc/src/base/ipc/ipc.cc index 845f20699..0ff0da525 100644 --- a/repos/base-foc/src/base/ipc/ipc.cc +++ b/repos/base-foc/src/base/ipc/ipc.cc @@ -47,21 +47,21 @@ using namespace Fiasco; ** IPC marshalling support ** *****************************/ -void Ipc_ostream::_marshal_capability(Native_capability const &cap) +void Ipc_marshaller::insert(Native_capability const &cap) { if (cap.valid()) { if (!l4_msgtag_label(l4_task_cap_valid(L4_BASE_TASK_CAP, cap.dst()))) { - _write_to_buf(0); + insert(0UL); return; } } /* transfer capability id */ - _write_to_buf(cap.local_name()); + insert(cap.local_name()); /* only transfer kernel-capability if it's a valid one */ if (cap.valid()) - _snd_msg->snd_append_cap_sel(cap.dst()); + _snd_msg.snd_append_cap_sel(cap.dst()); ASSERT(!cap.valid() || l4_msgtag_label(l4_task_cap_valid(L4_BASE_TASK_CAP, cap.dst())), @@ -69,12 +69,12 @@ void Ipc_ostream::_marshal_capability(Native_capability const &cap) } -void Ipc_istream::_unmarshal_capability(Native_capability &cap) +void Ipc_unmarshaller::extract(Native_capability &cap) { long value = 0; /* extract capability id from message buffer */ - _read_from_buf(value); + extract(value); /* if id is zero an invalid capability was transfered */ if (!value) { @@ -83,7 +83,7 @@ void Ipc_istream::_unmarshal_capability(Native_capability &cap) } /* try to insert received capability in the map and return it */ - cap = Native_capability(cap_map()->insert_map(value, _rcv_msg->rcv_cap_sel())); + cap = Native_capability(cap_map()->insert_map(value, _rcv_msg.rcv_cap_sel())); } @@ -117,7 +117,7 @@ static inline bool ipc_error(l4_msgtag_t tag, bool print) /** * Copy message registers from UTCB to destination message buffer */ -static void copy_utcb_to_msgbuf(l4_msgtag_t tag, Msgbuf_base *rcv_msg) +static void copy_utcb_to_msgbuf(l4_msgtag_t tag, Msgbuf_base &rcv_msg) { unsigned num_msg_words = l4_msgtag_words(tag); unsigned num_cap_sel = l4_msgtag_items(tag); @@ -125,11 +125,11 @@ static void copy_utcb_to_msgbuf(l4_msgtag_t tag, Msgbuf_base *rcv_msg) return; /* look up and validate destination message buffer to receive the payload */ - l4_mword_t *msg_buf = (l4_mword_t *)rcv_msg->buf; - if (num_msg_words*sizeof(l4_mword_t) > rcv_msg->size()) { + l4_mword_t *msg_buf = (l4_mword_t *)rcv_msg.buf; + if (num_msg_words*sizeof(l4_mword_t) > rcv_msg.size()) { if (DEBUG_MSG) outstring("receive message buffer too small"); - num_msg_words = rcv_msg->size()/sizeof(l4_mword_t); + num_msg_words = rcv_msg.size()/sizeof(l4_mword_t); } /* read message payload into destination message buffer */ @@ -138,19 +138,19 @@ static void copy_utcb_to_msgbuf(l4_msgtag_t tag, Msgbuf_base *rcv_msg) for (unsigned i = 0; i < num_msg_words; i++) *dst++ = *src++; - rcv_msg->rcv_reset(); + rcv_msg.rcv_reset(); } /** * Copy message registers from message buffer to UTCB and create message tag. */ -static l4_msgtag_t copy_msgbuf_to_utcb(Msgbuf_base *snd_msg, unsigned offset, +static l4_msgtag_t copy_msgbuf_to_utcb(Msgbuf_base &snd_msg, unsigned offset, Native_capability dst) { - l4_mword_t *msg_buf = (l4_mword_t *)snd_msg->buf; + l4_mword_t *msg_buf = (l4_mword_t *)snd_msg.buf; unsigned num_msg_words = offset/sizeof(l4_mword_t); - unsigned num_cap_sel = snd_msg->snd_cap_sel_cnt(); + unsigned num_cap_sel = snd_msg.snd_cap_sel_cnt(); if (num_msg_words + 2 * num_cap_sel > L4_UTCB_GENERIC_DATA_SIZE) { if (DEBUG_MSG) @@ -169,47 +169,17 @@ static l4_msgtag_t copy_msgbuf_to_utcb(Msgbuf_base *snd_msg, unsigned offset, for (unsigned i = 0; i < num_cap_sel; i++) { unsigned idx = num_msg_words + 2*i; l4_utcb_mr()->mr[idx] = L4_ITEM_MAP/* | L4_ITEM_CONT*/; - l4_utcb_mr()->mr[idx + 1] = l4_obj_fpage(snd_msg->snd_cap_sel(i), + l4_utcb_mr()->mr[idx + 1] = l4_obj_fpage(snd_msg.snd_cap_sel(i), 0, L4_FPAGE_RWX).raw; } /* we have consumed capability selectors, reset message buffer */ - snd_msg->snd_reset(); + snd_msg.snd_reset(); return l4_msgtag(0, num_msg_words, num_cap_sel, 0); } -/***************** - ** Ipc_ostream ** - *****************/ - -Ipc_ostream::Ipc_ostream(Native_capability dst, Msgbuf_base *snd_msg) -: - Ipc_marshaller(&snd_msg->buf[0], snd_msg->size()), - _snd_msg(snd_msg), _dst(dst) -{ - _write_offset = sizeof(l4_mword_t); -} - - -/***************** - ** Ipc_istream ** - *****************/ - -Ipc_istream::Ipc_istream(Msgbuf_base *rcv_msg) -: - Ipc_unmarshaller(&rcv_msg->buf[0], rcv_msg->size()), - Native_capability((Cap_index*)Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_BADGE]), - _rcv_msg(rcv_msg) -{ - _read_offset = sizeof(l4_mword_t); -} - - -Ipc_istream::~Ipc_istream() { } - - /**************** ** Ipc_client ** ****************/ @@ -219,7 +189,7 @@ void Ipc_client::_call() /* copy call message to the UTCBs message registers */ l4_msgtag_t tag = copy_msgbuf_to_utcb(_snd_msg, _write_offset, _dst); - addr_t rcv_cap_sel = _rcv_msg->rcv_cap_sel_base(); + addr_t rcv_cap_sel = _rcv_msg.rcv_cap_sel_base(); for (int i = 0; i < Msgbuf_base::MAX_CAP_ARGS; i++) { l4_utcb_br()->br[i] = rcv_cap_sel | L4_RCV_ITEM_SINGLE_CAP; rcv_cap_sel += L4_CAP_SIZE; @@ -238,9 +208,13 @@ void Ipc_client::_call() } -Ipc_client::Ipc_client(Native_capability const &srv, Msgbuf_base *snd_msg, - Msgbuf_base *rcv_msg, unsigned short) -: Ipc_istream(rcv_msg), Ipc_ostream(srv, snd_msg), _result(0) { } +Ipc_client::Ipc_client(Native_capability const &dst, + Msgbuf_base &snd_msg, Msgbuf_base &rcv_msg, unsigned short) +: + Ipc_marshaller(snd_msg), Ipc_unmarshaller(rcv_msg), _result(0), _dst(dst) +{ + _read_offset = _write_offset = sizeof(l4_mword_t); +} /**************** @@ -260,12 +234,11 @@ void Ipc_server::_prepare_next_reply_wait() } -void Ipc_server::_wait() +void Ipc_server::wait() { /* wait for new server request */ try { - l4_umword_t label = 0; - addr_t rcv_cap_sel = _rcv_msg->rcv_cap_sel_base(); + addr_t rcv_cap_sel = _rcv_msg.rcv_cap_sel_base(); for (int i = 0; i < Msgbuf_base::MAX_CAP_ARGS; i++) { l4_utcb_br()->br[i] = rcv_cap_sel | L4_RCV_ITEM_SINGLE_CAP; rcv_cap_sel += L4_CAP_SIZE; @@ -274,12 +247,11 @@ void Ipc_server::_wait() l4_msgtag_t tag; do { + l4_umword_t label = 0; tag = l4_ipc_wait(l4_utcb(), &label, L4_IPC_NEVER); + _rcv_msg.label(label); } while (ipc_error(tag, DEBUG_MSG)); - /* copy received label into message buffer */ - _rcv_msg->label(label); - /* copy message from the UTCBs message registers to the receive buffer */ copy_utcb_to_msgbuf(tag, _rcv_msg); @@ -288,26 +260,24 @@ void Ipc_server::_wait() } catch (Blocking_canceled) { } - /* we only have an unknown implicit reply capability */ - /* _dst = ???; */ + _badge = *reinterpret_cast(_rcv_msg.data()); _prepare_next_reply_wait(); } -void Ipc_server::_reply() +void Ipc_server::reply() { - l4_msgtag_t tag = copy_msgbuf_to_utcb(_snd_msg, _write_offset, _dst); + l4_msgtag_t tag = copy_msgbuf_to_utcb(_snd_msg, _write_offset, Native_capability()); tag = l4_ipc_send(L4_SYSF_REPLY, l4_utcb(), tag, L4_IPC_SEND_TIMEOUT_0); ipc_error(tag, DEBUG_MSG); } -void Ipc_server::_reply_wait() +void Ipc_server::reply_wait() { if (_reply_needed) { - l4_umword_t label; - addr_t rcv_cap_sel = _rcv_msg->rcv_cap_sel_base(); + addr_t rcv_cap_sel = _rcv_msg.rcv_cap_sel_base(); for (int i = 0; i < Msgbuf_base::MAX_CAP_ARGS; i++) { l4_utcb_br()->br[i] = rcv_cap_sel | L4_RCV_ITEM_SINGLE_CAP; rcv_cap_sel += L4_CAP_SIZE; @@ -315,8 +285,11 @@ void Ipc_server::_reply_wait() l4_utcb_br()->bdr &= ~L4_BDR_OFFSET_MASK; - l4_msgtag_t tag = copy_msgbuf_to_utcb(_snd_msg, _write_offset, _dst); + l4_umword_t label = 0; + + l4_msgtag_t tag = copy_msgbuf_to_utcb(_snd_msg, _write_offset, Native_capability()); tag = l4_ipc_reply_and_wait(l4_utcb(), tag, &label, L4_IPC_SEND_TIMEOUT_0); + _rcv_msg.label(label); if (ipc_error(tag, false)) { /* * The error conditions could be a message cut (which @@ -326,31 +299,30 @@ void Ipc_server::_reply_wait() * the user but want to wait for the next proper incoming * message. So let's just wait now. */ - _wait(); + wait(); } else { - /* copy received label into message buffer */ - _rcv_msg->label(label); - /* copy request message from the UTCBs message registers */ copy_utcb_to_msgbuf(tag, _rcv_msg); } } else - _wait(); + wait(); + + _badge = *reinterpret_cast(_rcv_msg.data()); - /* reply capability is implicit in fiasco.oc and unknown to us */ - /* _dst = ???; */ _prepare_next_reply_wait(); } Ipc_server::Ipc_server(Native_connection_state &cs, - Msgbuf_base *snd_msg, - Msgbuf_base *rcv_msg) -: Ipc_istream(rcv_msg), - Ipc_ostream(Native_capability(), snd_msg), - _reply_needed(false), _rcv_cs(cs) -{ } + Msgbuf_base &snd_msg, Msgbuf_base &rcv_msg) +: + Ipc_marshaller(snd_msg), Ipc_unmarshaller(rcv_msg), + Native_capability((Cap_index*)Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_BADGE]), + _reply_needed(false), _rcv_cs(cs) +{ + _read_offset = _write_offset = sizeof(l4_mword_t); +} Ipc_server::~Ipc_server() { } diff --git a/repos/base-foc/src/base/server/server.cc b/repos/base-foc/src/base/server/server.cc index df33abafd..5fcb191b1 100644 --- a/repos/base-foc/src/base/server/server.cc +++ b/repos/base-foc/src/base/server/server.cc @@ -45,7 +45,7 @@ Untyped_capability Rpc_entrypoint::_manage(Rpc_object_base *obj) void Rpc_entrypoint::entry() { Native_connection_state cs; - Ipc_server srv(cs, &_snd_buf, &_rcv_buf); + Ipc_server srv(cs, _snd_buf, _rcv_buf); _ipc_server = &srv; _cap = srv; _cap_valid.unlock(); @@ -63,17 +63,12 @@ void Rpc_entrypoint::entry() int opcode = 0; - srv >> IPC_REPLY_WAIT >> opcode; + srv.reply_wait(); + srv.extract(opcode); /* set default return value */ srv.ret(Ipc_client::ERR_INVALID_OBJECT); - /* check whether capability's label fits global id */ - if (((unsigned long)srv.badge()) != _rcv_buf.label()) { - PWRN("somebody tries to fake us!"); - continue; - } - apply(srv.badge(), [&] (Rpc_object_base *obj) { if (!obj) return; @@ -84,7 +79,7 @@ void Rpc_entrypoint::entry() } /* answer exit call, thereby wake up '~Rpc_entrypoint' */ - srv << IPC_REPLY; + srv.reply(); /* defer the destruction of 'Ipc_server' until '~Rpc_entrypoint' is ready */ _delay_exit.lock(); diff --git a/repos/base-foc/src/core/platform_thread.cc b/repos/base-foc/src/core/platform_thread.cc index 938d3c31f..c364d2252 100644 --- a/repos/base-foc/src/core/platform_thread.cc +++ b/repos/base-foc/src/core/platform_thread.cc @@ -129,8 +129,9 @@ void Platform_thread::resume() /* Send a message to the exception handler, to unblock the client */ Msgbuf<16> snd, rcv; - Ipc_client ipc_client(_pager_obj->cap(), &snd, &rcv); - ipc_client << _pager_obj << IPC_CALL; + Ipc_client ipc_client(_pager_obj->cap(), snd, rcv); + ipc_client.insert(_pager_obj); + ipc_client.call(); } diff --git a/repos/base-hw/include/base/ipc_msgbuf.h b/repos/base-hw/include/base/ipc_msgbuf.h index e9b370dc1..1f9d3eaf8 100644 --- a/repos/base-hw/include/base/ipc_msgbuf.h +++ b/repos/base-hw/include/base/ipc_msgbuf.h @@ -69,9 +69,9 @@ class Genode::Msgbuf_base size_t size() const { return _size; } /** - * Return address of message buffer + * Return pointer of message data payload */ - void *addr() { return &buf[0]; } + void *data() { return &buf[0]; } /** * Reset capability buffer. diff --git a/repos/base-hw/src/base/ipc/ipc.cc b/repos/base-hw/src/base/ipc/ipc.cc index 18969f2d0..df8c7c4b9 100644 --- a/repos/base-hw/src/base/ipc/ipc.cc +++ b/repos/base-hw/src/base/ipc/ipc.cc @@ -1,6 +1,7 @@ /* * \brief Implementation of the Genode IPC-framework * \author Martin Stein + * \author Norman Feske * \date 2012-02-12 */ @@ -50,44 +51,12 @@ enum ** IPC marshalling support ** *****************************/ -void Ipc_ostream::_marshal_capability(Native_capability const &cap) { - _snd_msg->cap_add(cap); } +void Ipc_marshaller::insert(Native_capability const &cap) { + _snd_msg.cap_add(cap); } -void Ipc_istream::_unmarshal_capability(Native_capability &cap) { - cap = _rcv_msg->cap_get(); } - - -/***************** - ** Ipc_ostream ** - *****************/ - -Ipc_ostream::Ipc_ostream(Native_capability dst, Msgbuf_base *snd_msg) -: - Ipc_marshaller(&snd_msg->buf[0], snd_msg->size()), - _snd_msg(snd_msg), _dst(dst) -{ - _write_offset = align_natural(RPC_OBJECT_ID_SIZE); - _snd_msg->reset(); -} - - -/***************** - ** Ipc_istream ** - *****************/ - -Ipc_istream::Ipc_istream(Msgbuf_base *rcv_msg) -: - Ipc_unmarshaller(&rcv_msg->buf[0], rcv_msg->size()), - Native_capability(Thread_base::myself() ? Thread_base::myself()->native_thread().cap - : Hw::_main_thread_cap), - _rcv_msg(rcv_msg) -{ - _read_offset = align_natural(RPC_OBJECT_ID_SIZE); -} - - -Ipc_istream::~Ipc_istream() { } +void Ipc_unmarshaller::extract(Native_capability &cap) { + cap = _rcv_msg.cap_get(); } /**************** @@ -100,16 +69,16 @@ void Ipc_client::_call() [&] () { /* send request and receive corresponding reply */ - Thread_base::myself()->utcb()->copy_from(*_snd_msg, _write_offset); + Thread_base::myself()->utcb()->copy_from(_snd_msg, _write_offset); - switch (Kernel::send_request_msg(Ipc_ostream::dst().dst(), - _rcv_msg->cap_rcv_window())) { + switch (Kernel::send_request_msg(_dst.dst(), + _rcv_msg.cap_rcv_window())) { case -1: throw Blocking_canceled(); case -2: throw Allocator::Out_of_memory(); default: - _rcv_msg->reset(); - _snd_msg->reset(); - Thread_base::myself()->utcb()->copy_to(*_rcv_msg); + _rcv_msg.reset(); + _snd_msg.reset(); + Thread_base::myself()->utcb()->copy_to(_rcv_msg); /* reset unmarshaller */ _write_offset = _read_offset = @@ -121,26 +90,24 @@ void Ipc_client::_call() } -Ipc_client::Ipc_client(Native_capability const &srv, Msgbuf_base *snd_msg, - Msgbuf_base *rcv_msg, unsigned short rcv_caps) -: Ipc_istream(rcv_msg), Ipc_ostream(srv, snd_msg), _result(0) { - rcv_msg->cap_rcv_window(rcv_caps); } +Ipc_client::Ipc_client(Native_capability const &dst, + Msgbuf_base &snd_msg, Msgbuf_base &rcv_msg, + unsigned short rcv_caps) +: + Ipc_marshaller(snd_msg), Ipc_unmarshaller(rcv_msg), _result(0), _dst(dst) +{ + _read_offset = align_natural(RPC_OBJECT_ID_SIZE); + _write_offset = align_natural(RPC_OBJECT_ID_SIZE); + _snd_msg.reset(); + + _rcv_msg.cap_rcv_window(rcv_caps); +} /**************** ** Ipc_server ** ****************/ -Ipc_server::Ipc_server(Native_connection_state &cs, - Msgbuf_base *snd_msg, - Msgbuf_base *rcv_msg) -: - Ipc_istream(rcv_msg), - Ipc_ostream(Native_capability(), snd_msg), - _reply_needed(false), _rcv_cs(cs) -{ } - - void Ipc_server::_prepare_next_reply_wait() { /* now we have a request to reply */ @@ -155,7 +122,7 @@ void Ipc_server::_prepare_next_reply_wait() } -void Ipc_server::_wait() +void Ipc_server::wait() { retry( [&] () { @@ -165,8 +132,9 @@ void Ipc_server::_wait() case -1: throw Blocking_canceled(); case -2: throw Allocator::Out_of_memory(); default: - _rcv_msg->reset(); - Thread_base::myself()->utcb()->copy_to(*_rcv_msg); + _rcv_msg.reset(); + Thread_base::myself()->utcb()->copy_to(_rcv_msg); + _badge = *reinterpret_cast(_rcv_msg.data()); /* update server state */ _prepare_next_reply_wait(); @@ -177,33 +145,34 @@ void Ipc_server::_wait() } -void Ipc_server::_reply() +void Ipc_server::reply() { - Thread_base::myself()->utcb()->copy_from(*_snd_msg, _write_offset); - _snd_msg->reset(); + Thread_base::myself()->utcb()->copy_from(_snd_msg, _write_offset); + _snd_msg.reset(); Kernel::send_reply_msg(0, false); } -void Ipc_server::_reply_wait() +void Ipc_server::reply_wait() { /* if there is no reply, wait for request */ if (!_reply_needed) { - _wait(); + wait(); return; } retry( [&] () { /* send reply and receive next request */ - Thread_base::myself()->utcb()->copy_from(*_snd_msg, _write_offset); + Thread_base::myself()->utcb()->copy_from(_snd_msg, _write_offset); switch (Kernel::send_reply_msg(Msgbuf_base::MAX_CAP_ARGS, true)) { case -1: throw Blocking_canceled(); case -2: throw Allocator::Out_of_memory(); default: - _rcv_msg->reset(); - _snd_msg->reset(); - Thread_base::myself()->utcb()->copy_to(*_rcv_msg); + _rcv_msg.reset(); + _snd_msg.reset(); + Thread_base::myself()->utcb()->copy_to(_rcv_msg); + _badge = *reinterpret_cast(_rcv_msg.data()); /* update server state */ _prepare_next_reply_wait(); @@ -214,4 +183,18 @@ void Ipc_server::_reply_wait() } +Ipc_server::Ipc_server(Native_connection_state &cs, + Msgbuf_base &snd_msg, Msgbuf_base &rcv_msg) +: + Ipc_marshaller(snd_msg), Ipc_unmarshaller(rcv_msg), + Native_capability(Thread_base::myself() ? Thread_base::myself()->native_thread().cap + : Hw::_main_thread_cap), + _reply_needed(false), _rcv_cs(cs) +{ + _read_offset = align_natural(RPC_OBJECT_ID_SIZE); + _write_offset = align_natural(RPC_OBJECT_ID_SIZE); + _snd_msg.reset(); +} + + Ipc_server::~Ipc_server() { } diff --git a/repos/base-hw/src/base/server/server.cc b/repos/base-hw/src/base/server/server.cc index f8794745e..ca65bfeae 100644 --- a/repos/base-hw/src/base/server/server.cc +++ b/repos/base-hw/src/base/server/server.cc @@ -43,7 +43,7 @@ Untyped_capability Rpc_entrypoint::_manage(Rpc_object_base *obj) void Rpc_entrypoint::entry() { Native_connection_state cs; - Ipc_server srv(cs, &_snd_buf, &_rcv_buf); + Ipc_server srv(cs, _snd_buf, _rcv_buf); _ipc_server = &srv; _cap = srv; _cap_valid.unlock(); @@ -61,7 +61,8 @@ void Rpc_entrypoint::entry() int opcode = 0; - srv >> IPC_REPLY_WAIT >> opcode; + srv.reply_wait(); + srv.extract(opcode); /* set default return value */ srv.ret(Ipc_client::ERR_INVALID_OBJECT); @@ -77,7 +78,7 @@ void Rpc_entrypoint::entry() } /* answer exit call, thereby wake up '~Rpc_entrypoint' */ - srv << IPC_REPLY; + srv.reply(); /* defer the destruction of 'Ipc_server' until '~Rpc_entrypoint' is ready */ _delay_exit.lock(); diff --git a/repos/base-linux/include/base/ipc_msgbuf.h b/repos/base-linux/include/base/ipc_msgbuf.h index 052108bc6..8a048430f 100644 --- a/repos/base-linux/include/base/ipc_msgbuf.h +++ b/repos/base-linux/include/base/ipc_msgbuf.h @@ -62,9 +62,9 @@ namespace Genode { inline Genode::size_t size() const { return _size; }; /** - * Return address of message buffer + * Return pointer of message data payload */ - inline void *addr() { return &_msg_start[0]; }; + inline void *data() { return &_msg_start[0]; }; void reset_caps() { _used_caps = 0; _read_cap_index = 0; } diff --git a/repos/base-linux/src/base/ipc/ipc.cc b/repos/base-linux/src/base/ipc/ipc.cc index 7e0074c8f..68dfa3540 100644 --- a/repos/base-linux/src/base/ipc/ipc.cc +++ b/repos/base-linux/src/base/ipc/ipc.cc @@ -52,22 +52,22 @@ using namespace Genode; ** IPC marshalling support ** *****************************/ -void Ipc_ostream::_marshal_capability(Native_capability const &cap) +void Ipc_marshaller::insert(Native_capability const &cap) { if (cap.valid()) { - _write_to_buf(cap.local_name()); + insert(cap.local_name()); - _snd_msg->append_cap(cap.dst().socket); + _snd_msg.append_cap(cap.dst().socket); } else { - _write_to_buf(-1L); + insert(-1L); } } -void Ipc_istream::_unmarshal_capability(Native_capability &cap) +void Ipc_unmarshaller::extract(Native_capability &cap) { long local_name = 0; - _read_from_buf(local_name); + extract(local_name); if (local_name == -1) { @@ -77,7 +77,7 @@ void Ipc_istream::_unmarshal_capability(Native_capability &cap) } else { /* construct valid capability */ - int const socket = _rcv_msg->read_cap(); + int const socket = _rcv_msg.read_cap(); cap = Native_capability(Cap_dst_policy::Dst(socket), local_name); } } @@ -439,83 +439,31 @@ static inline void lx_reply(int reply_socket, } -/***************** - ** Ipc_ostream ** - *****************/ - -/* - * XXX This class will be removed soon. - */ - -void Ipc_ostream::_prepare_next_send() -{ - PRAW("unexpected call to %s (%p)", __PRETTY_FUNCTION__, this); -} - - -Ipc_ostream::Ipc_ostream(Native_capability dst, Msgbuf_base *snd_msg): - Ipc_marshaller(snd_msg->buf, snd_msg->size()), _snd_msg(snd_msg), _dst(dst) -{ } - - -/***************** - ** Ipc_istream ** - *****************/ - -/* - * XXX This class will be removed soon. - */ - -void Ipc_istream::_prepare_next_receive() -{ - PRAW("unexpected call to %s (%p)", __PRETTY_FUNCTION__, this); -} - - -Ipc_istream::Ipc_istream(Msgbuf_base *rcv_msg) -: - Ipc_unmarshaller(rcv_msg->buf, rcv_msg->size()), - Native_capability(Dst(-1), 0), - _rcv_msg(rcv_msg) -{ } - - -Ipc_istream::~Ipc_istream() { } - - /**************** ** Ipc_client ** ****************/ -void Ipc_client::_prepare_next_call() +void Ipc_client::_call() +{ + lx_call(_dst.dst().socket, _snd_msg, _write_offset, _rcv_msg); +} + + +Ipc_client::Ipc_client(Native_capability const &dst, + Msgbuf_base &snd_msg, Msgbuf_base &rcv_msg, unsigned short) +: + Ipc_marshaller(snd_msg), Ipc_unmarshaller(rcv_msg), _result(0), _dst(dst) { /* prepare next request in buffer */ - long const local_name = Ipc_ostream::_dst.local_name(); - - _write_offset = 0; - _write_to_buf(local_name); + long const local_name = _dst.local_name(); /* prepare response buffer */ _read_offset = sizeof(long); + _write_offset = 0; - _snd_msg->reset_caps(); -} + insert(local_name); - -void Ipc_client::_call() -{ - if (Ipc_ostream::_dst.valid()) - lx_call(Ipc_ostream::_dst.dst().socket, *_snd_msg, _write_offset, *_rcv_msg); - - _prepare_next_call(); -} - - -Ipc_client::Ipc_client(Native_capability const &srv, Msgbuf_base *snd_msg, - Msgbuf_base *rcv_msg, unsigned short) -: Ipc_istream(rcv_msg), Ipc_ostream(srv, snd_msg), _result(0) -{ - _prepare_next_call(); + _snd_msg.reset_caps(); } @@ -530,18 +478,18 @@ void Ipc_server::_prepare_next_reply_wait() /* prepare next reply */ _write_offset = 0; - long local_name = Ipc_ostream::_dst.local_name(); - _write_to_buf(local_name); /* XXX unused, needed by de/marshaller */ + long local_name = _caller.local_name(); + insert(local_name); /* XXX unused, needed by de/marshaller */ /* leave space for exc code at the beginning of the msgbuf */ _write_offset += align_natural(sizeof(int)); /* reset capability slots of send message buffer */ - _snd_msg->reset_caps(); + _snd_msg.reset_caps(); } -void Ipc_server::_wait() +void Ipc_server::wait() { _reply_needed = true; @@ -555,7 +503,7 @@ void Ipc_server::_wait() } try { - int const reply_socket = lx_wait(_rcv_cs, *_rcv_msg); + int const reply_socket = lx_wait(_rcv_cs, _rcv_msg); /* * Remember reply capability @@ -566,38 +514,40 @@ void Ipc_server::_wait() */ enum { DUMMY_LOCAL_NAME = -1 }; typedef Native_capability::Dst Dst; - Ipc_ostream::_dst = Native_capability(Dst(reply_socket), DUMMY_LOCAL_NAME); + _caller = Native_capability(Dst(reply_socket), DUMMY_LOCAL_NAME); + _badge = reinterpret_cast(_rcv_msg.data())[0]; _prepare_next_reply_wait(); } catch (Blocking_canceled) { } } -void Ipc_server::_reply() +void Ipc_server::reply() { try { - lx_reply(Ipc_ostream::_dst.dst().socket, *_snd_msg, _write_offset); } + lx_reply(_caller.dst().socket, _snd_msg, _write_offset); } catch (Ipc_error) { } _prepare_next_reply_wait(); } -void Ipc_server::_reply_wait() +void Ipc_server::reply_wait() { /* when first called, there was no request yet */ if (_reply_needed) - lx_reply(Ipc_ostream::_dst.dst().socket, *_snd_msg, _write_offset); + lx_reply(_caller.dst().socket, _snd_msg, _write_offset); - _wait(); + wait(); } Ipc_server::Ipc_server(Native_connection_state &cs, - Msgbuf_base *snd_msg, Msgbuf_base *rcv_msg) + Msgbuf_base &snd_msg, Msgbuf_base &rcv_msg) : - Ipc_istream(rcv_msg), - Ipc_ostream(Native_capability(), snd_msg), _reply_needed(false), _rcv_cs(cs) + Ipc_marshaller(snd_msg), Ipc_unmarshaller(rcv_msg), + Native_capability(Dst(-1), 0), + _reply_needed(false), _rcv_cs(cs) { Thread_base *thread = Thread_base::myself(); @@ -619,7 +569,7 @@ Ipc_server::Ipc_server(Native_connection_state &cs, thread->native_thread().is_ipc_server = true; } - /* override capability initialization performed by 'Ipc_istream' */ + /* override capability initialization */ *static_cast(this) = Native_capability(Native_capability::Dst(_rcv_cs.client_sd), 0); diff --git a/repos/base-nova/include/base/ipc_msgbuf.h b/repos/base-nova/include/base/ipc_msgbuf.h index bf0ea51c2..8dde43ddd 100644 --- a/repos/base-nova/include/base/ipc_msgbuf.h +++ b/repos/base-nova/include/base/ipc_msgbuf.h @@ -125,9 +125,9 @@ namespace Genode { inline size_t size() const { return _size; } /** - * Return address of message buffer + * Return pointer of message data payload */ - inline void *addr() { return &_msg_start[0]; } + inline void *data() { return &_msg_start[0]; } /** * Reset portal capability selector payload diff --git a/repos/base-nova/src/base/ipc/ipc.cc b/repos/base-nova/src/base/ipc/ipc.cc index 73a2c3b43..9c8aeb6a9 100644 --- a/repos/base-nova/src/base/ipc/ipc.cc +++ b/repos/base-nova/src/base/ipc/ipc.cc @@ -28,15 +28,15 @@ using namespace Nova; ** IPC marshalling support ** *****************************/ -void Ipc_ostream::_marshal_capability(Native_capability const &cap) +void Ipc_marshaller::insert(Native_capability const &cap) { - _snd_msg->snd_append_pt_sel(cap); + _snd_msg.snd_append_pt_sel(cap); } -void Ipc_istream::_unmarshal_capability(Native_capability &cap) +void Ipc_unmarshaller::extract(Native_capability &cap) { - _rcv_msg->rcv_pt_sel(cap); + _rcv_msg.rcv_pt_sel(cap); } @@ -47,17 +47,17 @@ void Ipc_istream::_unmarshal_capability(Native_capability &cap) /** * Copy message registers from UTCB to destination message buffer */ -static void copy_utcb_to_msgbuf(Nova::Utcb *utcb, Msgbuf_base *rcv_msg) +static void copy_utcb_to_msgbuf(Nova::Utcb *utcb, Msgbuf_base &rcv_msg) { size_t num_msg_words = utcb->msg_words(); if (num_msg_words == 0) return; /* look up and validate destination message buffer to receive the payload */ - mword_t *msg_buf = (mword_t *)rcv_msg->buf; - if (num_msg_words*sizeof(mword_t) > rcv_msg->size()) { + mword_t *msg_buf = (mword_t *)rcv_msg.buf; + if (num_msg_words*sizeof(mword_t) > rcv_msg.size()) { PERR("receive message buffer too small msg size=%zx, buf size=%zd", - num_msg_words*sizeof(mword_t), rcv_msg->size()); - num_msg_words = rcv_msg->size()/sizeof(mword_t); + num_msg_words*sizeof(mword_t), rcv_msg.size()); + num_msg_words = rcv_msg.size()/sizeof(mword_t); } /* read message payload into destination message buffer */ @@ -71,11 +71,11 @@ static void copy_utcb_to_msgbuf(Nova::Utcb *utcb, Msgbuf_base *rcv_msg) /** * Copy message payload to UTCB message registers */ -static bool copy_msgbuf_to_utcb(Nova::Utcb *utcb, Msgbuf_base *snd_msg, +static bool copy_msgbuf_to_utcb(Nova::Utcb *utcb, Msgbuf_base &snd_msg, unsigned num_msg_words, mword_t local_name) { /* look up address and size of message payload */ - mword_t *msg_buf = (mword_t *)snd_msg->buf; + mword_t *msg_buf = (mword_t *)snd_msg.buf; /* * XXX determine correct number of message registers @@ -97,9 +97,9 @@ static bool copy_msgbuf_to_utcb(Nova::Utcb *utcb, Msgbuf_base *snd_msg, utcb->set_msg_word(num_msg_words); /* append portal capability selectors */ - for (unsigned i = 0; i < snd_msg->snd_pt_sel_cnt(); i++) { + for (unsigned i = 0; i < snd_msg.snd_pt_sel_cnt(); i++) { bool trans_map = true; - Nova::Obj_crd crd = snd_msg->snd_pt_sel(i, trans_map); + Nova::Obj_crd crd = snd_msg.snd_pt_sel(i, trans_map); if (crd.base() == ~0UL) continue; if (!utcb->append_item(crd, i, false, false, trans_map)) @@ -107,39 +107,12 @@ static bool copy_msgbuf_to_utcb(Nova::Utcb *utcb, Msgbuf_base *snd_msg, } /* we have consumed portal capability selectors, reset message buffer */ - snd_msg->snd_reset(); + snd_msg.snd_reset(); return true; } -/***************** - ** Ipc_ostream ** - *****************/ - -Ipc_ostream::Ipc_ostream(Native_capability dst, Msgbuf_base *snd_msg) -: - Ipc_marshaller(&snd_msg->buf[0], snd_msg->size()), - _snd_msg(snd_msg), _dst(dst) -{ - _write_offset = sizeof(mword_t); -} - - -/***************** - ** Ipc_istream ** - *****************/ - -Ipc_istream::Ipc_istream(Msgbuf_base *rcv_msg) -: Ipc_unmarshaller(&rcv_msg->buf[0], rcv_msg->size()), _rcv_msg(rcv_msg) -{ - _read_offset = sizeof(mword_t); -} - - -Ipc_istream::~Ipc_istream() { } - - /**************** ** Ipc_client ** ****************/ @@ -149,18 +122,18 @@ void Ipc_client::_call() Nova::Utcb *utcb = (Nova::Utcb *)Thread_base::myself()->utcb(); if (!copy_msgbuf_to_utcb(utcb, _snd_msg, _write_offset/sizeof(mword_t), - Ipc_ostream::_dst.local_name())) { + _dst.local_name())) { PERR("could not setup IPC"); return; } /* if we can't setup receive window, die in order to recognize the issue */ - if (!_rcv_msg->prepare_rcv_window(utcb, Ipc_ostream::_dst.rcv_window())) + if (!_rcv_msg.prepare_rcv_window(utcb, _dst.rcv_window())) /* printf doesn't work here since for IPC also rcv_prepare* is used */ nova_die(); /* establish the mapping via a portal traversal */ - uint8_t res = Nova::call(Ipc_ostream::_dst.local_name()); + uint8_t res = Nova::call(_dst.local_name()); if (res != Nova::NOVA_OK) { /* If an error occurred, reset word&item count (not done by kernel). */ utcb->set_msg_word(0); @@ -168,17 +141,19 @@ void Ipc_client::_call() ret(ERR_INVALID_OBJECT); } - _rcv_msg->post_ipc(utcb, Ipc_ostream::_dst.rcv_window()); + _rcv_msg.post_ipc(utcb, _dst.rcv_window()); copy_utcb_to_msgbuf(utcb, _rcv_msg); - _snd_msg->snd_reset(); + _snd_msg.snd_reset(); _write_offset = _read_offset = sizeof(mword_t); } -Ipc_client::Ipc_client(Native_capability const &srv, Msgbuf_base *snd_msg, - Msgbuf_base *rcv_msg, unsigned short const rcv_caps) -: Ipc_istream(rcv_msg), Ipc_ostream(srv, snd_msg), _result(0) +Ipc_client::Ipc_client(Native_capability const &dst, + Msgbuf_base &snd_msg, Msgbuf_base &rcv_msg, + unsigned short const rcv_caps) +: + Ipc_marshaller(snd_msg), Ipc_unmarshaller(rcv_msg), _result(0), _dst(dst) { if (rcv_caps == ~0) /* use default values for rcv_wnd */ @@ -188,7 +163,9 @@ Ipc_client::Ipc_client(Native_capability const &srv, Msgbuf_base *snd_msg, unsigned short log2_max = rcv_caps ? log2(rcv_caps) : 0; if ((1U << log2_max) < rcv_caps) log2_max ++; - rcv_msg->rcv_wnd(log2_max); + rcv_msg.rcv_wnd(log2_max); + + _read_offset = _write_offset = sizeof(mword_t); } @@ -196,7 +173,7 @@ Ipc_client::Ipc_client(Native_capability const &srv, Msgbuf_base *snd_msg, ** Ipc_server ** ****************/ -void Ipc_server::_wait() +void Ipc_server::wait() { /* * This function is only called by the portal dispatcher of server @@ -207,7 +184,7 @@ void Ipc_server::_wait() Nova::Utcb *utcb = (Nova::Utcb *)Thread_base::myself()->utcb(); - _rcv_msg->post_ipc(utcb); + _rcv_msg.post_ipc(utcb); copy_utcb_to_msgbuf(utcb, _rcv_msg); /* reset unmarshaller */ @@ -216,25 +193,26 @@ void Ipc_server::_wait() } -void Ipc_server::_reply() +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), - Ipc_ostream::_dst.local_name()); + copy_msgbuf_to_utcb(utcb, _snd_msg, _write_offset/sizeof(mword_t), 0); Nova::reply(Thread_base::myself()->stack_top()); } -void Ipc_server::_reply_wait() { } +void Ipc_server::reply_wait() { } Ipc_server::Ipc_server(Native_connection_state &cs, - Msgbuf_base *snd_msg, Msgbuf_base *rcv_msg) + Msgbuf_base &snd_msg, Msgbuf_base &rcv_msg) : - Ipc_istream(rcv_msg), Ipc_ostream(Native_capability(), snd_msg), _rcv_cs(cs) -{ } + Ipc_marshaller(snd_msg), Ipc_unmarshaller(rcv_msg), _rcv_cs(cs) +{ + _read_offset = _write_offset = sizeof(mword_t); +} Ipc_server::~Ipc_server() { } diff --git a/repos/base-nova/src/base/server/server.cc b/repos/base-nova/src/base/server/server.cc index 87c2ec832..3f6a49b9e 100644 --- a/repos/base-nova/src/base/server/server.cc +++ b/repos/base-nova/src/base/server/server.cc @@ -122,8 +122,9 @@ void Rpc_entrypoint::_activation_entry() int opcode = 0; Native_connection_state cs; - Ipc_server srv(cs, &ep->_snd_buf, &ep->_rcv_buf); - srv >> IPC_WAIT >> opcode; + Ipc_server srv(cs, ep->_snd_buf, ep->_rcv_buf); + srv.wait(); + srv.extract(opcode); /* set default return value */ srv.ret(Ipc_client::ERR_INVALID_OBJECT); @@ -132,7 +133,7 @@ void Rpc_entrypoint::_activation_entry() if (ep->_cap.local_name() == id_pt) { if (!ep->_rcv_buf.prepare_rcv_window((Nova::Utcb *)ep->utcb())) PWRN("out of capability selectors for handling server requests"); - srv << IPC_REPLY; + srv.reply(); } { @@ -157,7 +158,7 @@ void Rpc_entrypoint::_activation_entry() if (!ep->_rcv_buf.prepare_rcv_window((Nova::Utcb *)ep->utcb())) PWRN("out of capability selectors for handling server requests"); - srv << IPC_REPLY; + srv.reply(); } diff --git a/repos/base-okl4/include/base/ipc_msgbuf.h b/repos/base-okl4/include/base/ipc_msgbuf.h index dcdd2f76a..54cc6d829 100644 --- a/repos/base-okl4/include/base/ipc_msgbuf.h +++ b/repos/base-okl4/include/base/ipc_msgbuf.h @@ -45,9 +45,9 @@ namespace Genode { inline size_t size() const { return _size; }; /** - * Return address of message buffer + * Return pointer of message data payload */ - inline void *addr() { return &_msg_start[0]; }; + inline void *data() { return &_msg_start[0]; }; }; diff --git a/repos/base-okl4/src/base/ipc/ipc.cc b/repos/base-okl4/src/base/ipc/ipc.cc index 1a2e127a0..8aa82fdca 100644 --- a/repos/base-okl4/src/base/ipc/ipc.cc +++ b/repos/base-okl4/src/base/ipc/ipc.cc @@ -51,17 +51,17 @@ static void kdb_emergency_print(const char *s) /** * Copy message registers from UTCB to destination message buffer */ -static void copy_utcb_to_msgbuf(L4_MsgTag_t rcv_tag, Msgbuf_base *rcv_msg) +static void copy_utcb_to_msgbuf(L4_MsgTag_t rcv_tag, Msgbuf_base &rcv_msg) { int num_msg_words = (int)L4_UntypedWords(rcv_tag); if (num_msg_words <= 0) return; /* look up and validate destination message buffer to receive the payload */ - L4_Word_t *msg_buf = (L4_Word_t *)rcv_msg->buf; - if (num_msg_words*sizeof(L4_Word_t) > rcv_msg->size()) { + L4_Word_t *msg_buf = (L4_Word_t *)rcv_msg.buf; + if (num_msg_words*sizeof(L4_Word_t) > rcv_msg.size()) { PERR("receive message buffer too small msg size=%zd, buf size=%zd", - num_msg_words*sizeof(L4_Word_t), rcv_msg->size()); - num_msg_words = rcv_msg->size()/sizeof(L4_Word_t); + num_msg_words*sizeof(L4_Word_t), rcv_msg.size()); + num_msg_words = rcv_msg.size()/sizeof(L4_Word_t); } /* read message payload into destination message buffer */ @@ -77,11 +77,11 @@ static void copy_utcb_to_msgbuf(L4_MsgTag_t rcv_tag, Msgbuf_base *rcv_msg) * 1 is used for the local name. All subsequent message registers hold the * message payload. */ -static void copy_msgbuf_to_utcb(Msgbuf_base *snd_msg, unsigned num_msg_words, +static void copy_msgbuf_to_utcb(Msgbuf_base &snd_msg, unsigned num_msg_words, L4_Word_t local_name) { /* look up address and size of message payload */ - L4_Word_t *msg_buf = (L4_Word_t *)snd_msg->buf; + L4_Word_t *msg_buf = (L4_Word_t *)snd_msg.buf; num_msg_words += 1; @@ -99,51 +99,6 @@ static void copy_msgbuf_to_utcb(Msgbuf_base *snd_msg, unsigned num_msg_words, } -/***************** - ** Ipc_ostream ** - *****************/ - -Ipc_ostream::Ipc_ostream(Native_capability dst, Msgbuf_base *snd_msg) -: - Ipc_marshaller(&snd_msg->buf[0], snd_msg->size()), - _snd_msg(snd_msg), _dst(dst) -{ - _write_offset = sizeof(umword_t); -} - - -/***************** - ** Ipc_istream ** - *****************/ - -/** - * Return the global thread ID of the calling thread - * - * On OKL4 we cannot use 'L4_Myself()' to determine our own thread's - * identity. By convention, each thread stores its global ID in a - * defined entry of its UTCB. - */ -static inline Okl4::L4_ThreadId_t thread_get_my_global_id() -{ - Okl4::L4_ThreadId_t myself; - myself.raw = Okl4::__L4_TCR_ThreadWord(UTCB_TCR_THREAD_WORD_MYSELF); - return myself; -} - - -Ipc_istream::Ipc_istream(Msgbuf_base *rcv_msg) -: - Ipc_unmarshaller(&rcv_msg->buf[0], rcv_msg->size()), - Native_capability(thread_get_my_global_id(), 0), - _rcv_msg(rcv_msg) -{ - _read_offset = sizeof(umword_t); -} - - -Ipc_istream::~Ipc_istream() { } - - /**************** ** Ipc_client ** ****************/ @@ -152,10 +107,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), - Ipc_ostream::_dst.local_name()); + _dst.local_name()); L4_Accept(L4_UntypedWordsAcceptor); - L4_MsgTag_t rcv_tag = L4_Call(Ipc_ostream::_dst.dst()); + L4_MsgTag_t rcv_tag = L4_Call(_dst.dst()); enum { ERROR_MASK = 0xe, ERROR_CANCELED = 3 << 1 }; if (L4_IpcFailed(rcv_tag) && @@ -175,9 +130,13 @@ void Ipc_client::_call() } -Ipc_client::Ipc_client(Native_capability const &srv, Msgbuf_base *snd_msg, - Msgbuf_base *rcv_msg, unsigned short) -: Ipc_istream(rcv_msg), Ipc_ostream(srv, snd_msg), _result(0) { } +Ipc_client::Ipc_client(Native_capability const &dst, + Msgbuf_base &snd_msg, Msgbuf_base &rcv_msg, unsigned short) +: + Ipc_marshaller(snd_msg), Ipc_unmarshaller(rcv_msg), _result(0), _dst(dst) +{ + _write_offset = _read_offset = sizeof(umword_t); +} /**************** @@ -197,7 +156,7 @@ void Ipc_server::_prepare_next_reply_wait() } -void Ipc_server::_wait() +void Ipc_server::wait() { /* wait for new server request */ try { @@ -218,20 +177,21 @@ void Ipc_server::_wait() } catch (Blocking_canceled) { } /* define destination of next reply */ - Ipc_ostream::_dst = Native_capability(_rcv_cs.caller, badge()); + _caller = Native_capability(_rcv_cs.caller, badge()); + _badge = reinterpret_cast(_rcv_msg.data())[0]; _prepare_next_reply_wait(); } -void Ipc_server::_reply() +void Ipc_server::reply() { /* copy reply to the UTCBs message registers */ copy_msgbuf_to_utcb(_snd_msg, _write_offset/sizeof(L4_Word_t), - Ipc_ostream::_dst.local_name()); + _caller.local_name()); /* perform non-blocking IPC send operation */ - L4_MsgTag_t rcv_tag = L4_Reply(Ipc_ostream::_dst.dst()); + L4_MsgTag_t rcv_tag = L4_Reply(_caller.dst()); if (L4_IpcFailed(rcv_tag)) PERR("ipc error in _reply - gets ignored"); @@ -240,15 +200,15 @@ void Ipc_server::_reply() } -void Ipc_server::_reply_wait() +void Ipc_server::reply_wait() { if (_reply_needed) { /* copy reply to the UTCBs message registers */ copy_msgbuf_to_utcb(_snd_msg, _write_offset/sizeof(L4_Word_t), - Ipc_ostream::_dst.local_name()); + _caller.local_name()); - L4_MsgTag_t rcv_tag = L4_ReplyWait(Ipc_ostream::_dst.dst(), &_rcv_cs.caller); + L4_MsgTag_t rcv_tag = L4_ReplyWait(_caller.dst(), &_rcv_cs.caller); /* * TODO: Check for IPC error @@ -258,22 +218,40 @@ void Ipc_server::_reply_wait() copy_utcb_to_msgbuf(rcv_tag, _rcv_msg); /* define destination of next reply */ - Ipc_ostream::_dst = Native_capability(_rcv_cs.caller, badge()); + _caller = Native_capability(_rcv_cs.caller, badge()); + _badge = reinterpret_cast(_rcv_msg.data())[0]; _prepare_next_reply_wait(); } else - _wait(); + wait(); +} + + +/** + * Return the global thread ID of the calling thread + * + * On OKL4 we cannot use 'L4_Myself()' to determine our own thread's + * identity. By convention, each thread stores its global ID in a + * defined entry of its UTCB. + */ +static inline Okl4::L4_ThreadId_t thread_get_my_global_id() +{ + Okl4::L4_ThreadId_t myself; + myself.raw = Okl4::__L4_TCR_ThreadWord(UTCB_TCR_THREAD_WORD_MYSELF); + return myself; } Ipc_server::Ipc_server(Native_connection_state &cs, - Msgbuf_base *snd_msg, Msgbuf_base *rcv_msg) + Msgbuf_base &snd_msg, Msgbuf_base &rcv_msg) : - Ipc_istream(rcv_msg), - Ipc_ostream(Native_capability(), snd_msg), + Ipc_marshaller(snd_msg), + Ipc_unmarshaller(rcv_msg), + Native_capability(thread_get_my_global_id(), 0), _reply_needed(false), _rcv_cs(cs) -{ } - +{ + _read_offset = _write_offset = sizeof(umword_t); +} Ipc_server::~Ipc_server() { } diff --git a/repos/base-pistachio/include/base/ipc_msgbuf.h b/repos/base-pistachio/include/base/ipc_msgbuf.h index 2a51b03f5..70a7a72b2 100644 --- a/repos/base-pistachio/include/base/ipc_msgbuf.h +++ b/repos/base-pistachio/include/base/ipc_msgbuf.h @@ -32,8 +32,7 @@ namespace Genode { * Begin of message buffer layout */ Pistachio::L4_Fpage_t rcv_fpage; - /* Send message */ - /* Recv message */ + char buf[]; /** @@ -42,9 +41,9 @@ namespace Genode { inline size_t size() const { return _size; }; /** - * Return address of message buffer + * Return pointer of message data payload */ - inline void *addr() { return &_msg_start[0]; }; + inline void *data() { return &_msg_start[0]; }; }; diff --git a/repos/base-pistachio/src/base/ipc/ipc.cc b/repos/base-pistachio/src/base/ipc/ipc.cc index ce5ab0551..f1b62495d 100644 --- a/repos/base-pistachio/src/base/ipc/ipc.cc +++ b/repos/base-pistachio/src/base/ipc/ipc.cc @@ -47,23 +47,6 @@ using namespace Pistachio; #endif -/***************** - ** Ipc_ostream ** - *****************/ - -Ipc_ostream::Ipc_ostream(Native_capability dst, Msgbuf_base *snd_msg) : - Ipc_marshaller(&snd_msg->buf[0], snd_msg->size()), - _snd_msg(snd_msg), _dst(dst) -{ - _write_offset = sizeof(umword_t); - IPCDEBUG("Ipc_ostream constructed.\n"); -} - - -/***************** - ** Ipc_istream ** - *****************/ - /** * Assert that we got 1 untyped word and 2 typed words */ @@ -101,37 +84,21 @@ static inline void check_ipc_result(L4_MsgTag_t result, L4_Word_t error_code) } -Ipc_istream::Ipc_istream(Msgbuf_base *rcv_msg) : - Ipc_unmarshaller(&rcv_msg->buf[0], rcv_msg->size()), - Native_capability(Pistachio::L4_Myself(), 0), - _rcv_msg(rcv_msg) -{ - IPCDEBUG("Ipc_istream constructed.\n"); - _read_offset = sizeof(umword_t); -} - - -Ipc_istream::~Ipc_istream() { } - - /**************** ** Ipc_client ** ****************/ 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 = Ipc_ostream::_dst.local_name(); - - IPCDEBUG("Destination local_name = 0x%x\n", local_name); + L4_StringItem_t sitem = L4_StringItem(_write_offset, _snd_msg.buf); + L4_Word_t const local_name = _dst.local_name(); L4_MsgBuffer_t msgbuf; /* prepare message buffer */ L4_Clear (&msgbuf); - L4_Append (&msgbuf, L4_StringItem (_rcv_msg->size(), _rcv_msg->buf)); + L4_Append (&msgbuf, L4_StringItem (_rcv_msg.size(), _rcv_msg.buf)); L4_Accept(L4_UntypedWordsAcceptor); L4_Accept(L4_StringItemsAcceptor, &msgbuf); @@ -141,21 +108,20 @@ void Ipc_client::_call() L4_Append(&msg, sitem); L4_Load(&msg); - L4_MsgTag_t result = L4_Call(Ipc_ostream::_dst.dst()); + L4_MsgTag_t result = L4_Call(_dst.dst()); _write_offset = _read_offset = sizeof(umword_t); check_ipc_result(result, L4_ErrorCode()); - - IPCDEBUG("Call done.\n"); } -Ipc_client::Ipc_client(Native_capability const &srv, Msgbuf_base *snd_msg, - Msgbuf_base *rcv_msg, unsigned short) : - Ipc_istream(rcv_msg), Ipc_ostream(srv, snd_msg), _result(0) +Ipc_client::Ipc_client(Native_capability const &dst, + Msgbuf_base &snd_msg, Msgbuf_base &rcv_msg, unsigned short) +: + Ipc_marshaller(snd_msg), Ipc_unmarshaller(rcv_msg), _result(0), _dst(dst) { - IPCDEBUG("Ipc_client constructed.\n"); + _read_offset = _write_offset = sizeof(umword_t); } @@ -176,7 +142,7 @@ void Ipc_server::_prepare_next_reply_wait() } -void Ipc_server::_wait() +void Ipc_server::wait() { /* wait for new server request */ try { @@ -184,14 +150,12 @@ void Ipc_server::_wait() L4_MsgTag_t result; L4_MsgBuffer_t msgbuf; - IPCDEBUG("_wait.\n"); - do { IPCDEBUG("_wait loop start (more than once means IpcError)\n"); L4_Clear (&msgbuf); - L4_Append (&msgbuf, L4_StringItem (_rcv_msg->size(), _rcv_msg->buf)); + L4_Append (&msgbuf, L4_StringItem (_rcv_msg.size(), _rcv_msg.buf)); L4_Accept(L4_UntypedWordsAcceptor); L4_Accept(L4_StringItemsAcceptor, &msgbuf); @@ -200,46 +164,38 @@ void Ipc_server::_wait() } while (L4_IpcFailed(result)); - IPCDEBUG("Got something from 0x%x.\n", _rcv_cs.caller); L4_Msg_t msg; L4_Store(result, &msg); check_ipc_result(result, L4_ErrorCode()); - /* get the local name */ - L4_Word_t local_name = L4_Get(&msg,0); + /* remember badge of invoked object */ + _badge = L4_Get(&msg, 0); - /* - * Store local_name where badge() looks for it. - * XXX Check this... - */ - *((long *)_rcv_msg->buf) = local_name; _read_offset = sizeof(umword_t); - IPCDEBUG("_wait successful\n"); - } catch (Blocking_canceled) { } /* define destination of next reply */ - Ipc_ostream::_dst = Native_capability(_rcv_cs.caller, badge()); + _caller = Native_capability(_rcv_cs.caller, badge()); _prepare_next_reply_wait(); } -void Ipc_server::_reply() +void Ipc_server::reply() { L4_Msg_t msg; - L4_StringItem_t sitem = L4_StringItem(_write_offset, _snd_msg->buf); - L4_Word_t local_name = Ipc_ostream::_dst.local_name(); + L4_StringItem_t sitem = L4_StringItem(_write_offset, _snd_msg.buf); + L4_Word_t const local_name = _caller.local_name(); L4_Clear(&msg); L4_Append(&msg, local_name); L4_Append(&msg, sitem); L4_Load(&msg); - L4_MsgTag_t result = L4_Reply(Ipc_ostream::_dst.dst()); + L4_MsgTag_t result = L4_Reply(_caller.dst()); if (L4_IpcFailed(result)) PERR("ipc error in _reply, ignored"); @@ -247,17 +203,14 @@ void Ipc_server::_reply() } -void Ipc_server::_reply_wait() +void Ipc_server::reply_wait() { - IPCDEBUG("Starting to _reply_wait. (with %u bytes of data)\n", - _reply_needed ? _write_offset : 0); - if (_reply_needed) { /* prepare massage */ L4_Msg_t msg; - L4_StringItem_t sitem = L4_StringItem(_write_offset, _snd_msg->buf); - L4_Word_t local_name = Ipc_ostream::_dst.local_name(); + L4_StringItem_t sitem = L4_StringItem(_write_offset, _snd_msg.buf); + L4_Word_t const local_name = _caller.local_name(); L4_Clear(&msg); L4_Append(&msg, local_name); @@ -267,13 +220,12 @@ void Ipc_server::_reply_wait() /* Prepare message buffer */ L4_MsgBuffer_t msgbuf; L4_Clear(&msgbuf); - L4_Append(&msgbuf, L4_StringItem (_rcv_msg->size(), _rcv_msg->buf)); + L4_Append(&msgbuf, L4_StringItem (_rcv_msg.size(), _rcv_msg.buf)); L4_Accept(L4_UntypedWordsAcceptor); L4_Accept(L4_StringItemsAcceptor, &msgbuf); - L4_MsgTag_t result = L4_Ipc(Ipc_ostream::_dst.dst(), L4_anythread, + L4_MsgTag_t result = L4_Ipc(_caller.dst(), L4_anythread, L4_Timeouts(L4_ZeroTime, L4_Never), &_rcv_cs.caller); - IPCDEBUG("Got something from 0x%x.\n", L4_ThreadNo(L4_GlobalId(_rcv_cs.caller))); /* error handling - check whether send or receive failed */ if (L4_IpcFailed(result)) { @@ -283,7 +235,7 @@ void Ipc_server::_reply_wait() PERR("IPC %s error %02lx, offset %08lx -> _wait() instead.", phase ? "receive" : "send", error, errcode >> 4); - _wait(); + wait(); return; } @@ -298,36 +250,32 @@ void Ipc_server::_reply_wait() * the error to the user. */ IPCDEBUG("Bad IPC content -> _wait() instead.\n"); - _wait(); + wait(); return; } - /* get the local name */ - local_name = L4_Get(&msg, 0); - - /* - * Store local_name where badge() looks for it. - * XXX Check this... - */ - *((long *)_rcv_msg->buf) = local_name; - IPCDEBUG("local_name = 0x%lx\n", badge()); + /* remember badge of invoked object */ + _badge = L4_Get(&msg, 0); /* define destination of next reply */ - Ipc_ostream::_dst = Native_capability(_rcv_cs.caller, badge()); + _caller = Native_capability(_rcv_cs.caller, badge()); _prepare_next_reply_wait(); } else - _wait(); + wait(); } Ipc_server::Ipc_server(Native_connection_state &cs, - Msgbuf_base *snd_msg, Msgbuf_base *rcv_msg) : - Ipc_istream(rcv_msg), - Ipc_ostream(Native_capability(), snd_msg), + Msgbuf_base &snd_msg, Msgbuf_base &rcv_msg) +: + Ipc_marshaller(snd_msg), Ipc_unmarshaller(rcv_msg), + Native_capability(Pistachio::L4_Myself(), 0), _reply_needed(false), _rcv_cs(cs) -{ } +{ + _read_offset = _write_offset = sizeof(umword_t); +} Ipc_server::~Ipc_server() { } diff --git a/repos/base-sel4/src/base/ipc/ipc.cc b/repos/base-sel4/src/base/ipc/ipc.cc index 0a54b79d2..b0295e2e3 100644 --- a/repos/base-sel4/src/base/ipc/ipc.cc +++ b/repos/base-sel4/src/base/ipc/ipc.cc @@ -121,8 +121,7 @@ static seL4_MessageInfo_t new_seL4_message(Msgbuf_base &msg, /** * Convert seL4 message into Genode::Msgbuf_base */ -static void decode_seL4_message(umword_t badge, - seL4_MessageInfo_t const &msg_info, +static void decode_seL4_message(seL4_MessageInfo_t const &msg_info, Msgbuf_base &dst_msg) { /* @@ -249,11 +248,6 @@ static void decode_seL4_message(umword_t badge, umword_t *dst = (umword_t *)dst_msg.data(); for (size_t i = 0; i < seL4_MessageInfo_get_length(msg_info); i++) *dst++ = seL4_GetMR(MR_IDX_DATA + i); - - /* - * Store RPC object key of invoked object to be picked up by server.cc - */ - *(long *)dst_msg.data() = badge; } @@ -261,54 +255,25 @@ static void decode_seL4_message(umword_t badge, ** IPC marshalling support ** *****************************/ -void Ipc_ostream::_marshal_capability(Native_capability const &cap) +void Ipc_marshaller::insert(Native_capability const &cap) { - _snd_msg->append_cap(cap); + _snd_msg.append_cap(cap); } -void Ipc_istream::_unmarshal_capability(Native_capability &cap) +void Ipc_unmarshaller::extract(Native_capability &cap) { - cap = _rcv_msg->extract_cap(); + cap = _rcv_msg.extract_cap(); } -/***************** - ** Ipc_ostream ** - *****************/ - -Ipc_ostream::Ipc_ostream(Native_capability dst, Msgbuf_base *snd_msg) -: - Ipc_marshaller((char *)snd_msg->data(), snd_msg->size()), - _snd_msg(snd_msg), _dst(dst) -{ - _write_offset = sizeof(umword_t); -} - - -/***************** - ** Ipc_istream ** - *****************/ - -Ipc_istream::Ipc_istream(Msgbuf_base *rcv_msg) -: - Ipc_unmarshaller((char *)rcv_msg->data(), rcv_msg->size()), - _rcv_msg(rcv_msg) -{ - _read_offset = sizeof(umword_t); -} - - -Ipc_istream::~Ipc_istream() { } - - /**************** ** Ipc_client ** ****************/ void Ipc_client::_call() { - if (!Ipc_ostream::_dst.valid()) { + if (!_dst.valid()) { PERR("Trying to invoke an invalid capability, stop."); kernel_debugger_panic("IPC destination is invalid"); } @@ -317,23 +282,27 @@ void Ipc_client::_call() rcv_sel() = Capability_space::alloc_rcv_sel(); seL4_MessageInfo_t const request_msg_info = - new_seL4_message(*_snd_msg, _write_offset); + new_seL4_message(_snd_msg, _write_offset); unsigned const dst_sel = Capability_space::ipc_cap_data(_dst).sel.value(); seL4_MessageInfo_t const reply_msg_info = seL4_Call(dst_sel, request_msg_info); - decode_seL4_message(0, reply_msg_info, *_rcv_msg); + decode_seL4_message(reply_msg_info, _rcv_msg); _write_offset = _read_offset = sizeof(umword_t); } -Ipc_client::Ipc_client(Native_capability const &srv, Msgbuf_base *snd_msg, - Msgbuf_base *rcv_msg, unsigned short) -: Ipc_istream(rcv_msg), Ipc_ostream(srv, snd_msg), _result(0) -{ } +Ipc_client::Ipc_client(Native_capability const &dst, + Msgbuf_base &snd_msg, Msgbuf_base &rcv_msg, + unsigned short) +: + Ipc_marshaller(snd_msg), Ipc_unmarshaller(rcv_msg), _result(0), _dst(dst) +{ + _read_offset = _write_offset = sizeof(umword_t); +} /**************** @@ -351,46 +320,45 @@ void Ipc_server::_prepare_next_reply_wait() /* receive buffer offset */ _read_offset = sizeof(umword_t); - _rcv_msg->reset_read_cap_index(); - _snd_msg->reset_caps(); + _rcv_msg.reset_read_cap_index(); + _snd_msg.reset_caps(); } -void Ipc_server::_wait() +void Ipc_server::wait() { - seL4_Word badge = Rpc_obj_key::INVALID; seL4_MessageInfo_t const msg_info = - seL4_Recv(Thread_base::myself()->native_thread().ep_sel, &badge); + seL4_Recv(Thread_base::myself()->native_thread().ep_sel, + (seL4_Word *)&_badge); - decode_seL4_message(badge, msg_info, *_rcv_msg); + decode_seL4_message(msg_info, _rcv_msg); _prepare_next_reply_wait(); } -void Ipc_server::_reply() +void Ipc_server::reply() { ASSERT(false); } -void Ipc_server::_reply_wait() +void Ipc_server::reply_wait() { if (!_reply_needed) { - _wait(); + wait(); } else { - seL4_Word badge = Rpc_obj_key::INVALID; seL4_MessageInfo_t const reply_msg_info = - new_seL4_message(*_snd_msg, _write_offset); + new_seL4_message(_snd_msg, _write_offset); seL4_MessageInfo_t const request_msg_info = seL4_ReplyRecv(Thread_base::myself()->native_thread().ep_sel, - reply_msg_info, &badge); + reply_msg_info, (seL4_Word *)&_badge); - decode_seL4_message(badge, request_msg_info, *_rcv_msg); + decode_seL4_message(request_msg_info, _rcv_msg); } _prepare_next_reply_wait(); @@ -398,13 +366,15 @@ void Ipc_server::_reply_wait() Ipc_server::Ipc_server(Native_connection_state &cs, - Msgbuf_base *snd_msg, Msgbuf_base *rcv_msg) + Msgbuf_base &snd_msg, Msgbuf_base &rcv_msg) : - Ipc_istream(rcv_msg), Ipc_ostream(Native_capability(), snd_msg), + Ipc_marshaller(snd_msg), Ipc_unmarshaller(rcv_msg), _reply_needed(false), _rcv_cs(cs) { *static_cast(this) = Native_capability(Capability_space::create_ep_cap(*Thread_base::myself())); + + _read_offset = _write_offset = sizeof(umword_t); } diff --git a/repos/base-sel4/src/base/server/server.cc b/repos/base-sel4/src/base/server/server.cc index b482b5bd9..7e497bfa4 100644 --- a/repos/base-sel4/src/base/server/server.cc +++ b/repos/base-sel4/src/base/server/server.cc @@ -46,7 +46,7 @@ Untyped_capability Rpc_entrypoint::_manage(Rpc_object_base *obj) void Rpc_entrypoint::entry() { Native_connection_state cs; - Ipc_server srv(cs, &_snd_buf, &_rcv_buf); + Ipc_server srv(cs, _snd_buf, _rcv_buf); _ipc_server = &srv; _cap = srv; _cap_valid.unlock(); @@ -64,7 +64,8 @@ void Rpc_entrypoint::entry() int opcode = 0; - srv >> IPC_REPLY_WAIT >> opcode; + srv.reply_wait(); + srv.extract(opcode); /* set default return value */ srv.ret(Ipc_client::ERR_INVALID_OBJECT); @@ -81,7 +82,7 @@ void Rpc_entrypoint::entry() } /* answer exit call, thereby wake up '~Rpc_entrypoint' */ - srv << IPC_REPLY; + srv.reply(); /* defer the destruction of 'Ipc_server' until '~Rpc_entrypoint' is ready */ _delay_exit.lock(); diff --git a/repos/base/include/base/ipc.h b/repos/base/include/base/ipc.h index a64acf62f..b5d29f5a8 100644 --- a/repos/base/include/base/ipc.h +++ b/repos/base/include/base/ipc.h @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -33,16 +34,9 @@ namespace Genode { class Native_connection_state; - enum Ipc_istream_wait { IPC_WAIT }; - enum Ipc_client_call { IPC_CALL }; - enum Ipc_server_reply { IPC_REPLY }; - enum Ipc_server_reply_wait { IPC_REPLY_WAIT }; - class Ipc_error; class Ipc_marshaller; class Ipc_unmarshaller; - class Ipc_ostream; - class Ipc_istream; class Ipc_client; class Ipc_server; } @@ -61,71 +55,68 @@ class Genode::Ipc_marshaller { protected: - char *_sndbuf; - size_t _sndbuf_size; - unsigned _write_offset; + Msgbuf_base &_snd_msg; + unsigned _write_offset = 0; - protected: + private: + + char *_snd_buf = (char *)_snd_msg.data(); + size_t const _snd_buf_size = _snd_msg.size(); + + public: /** * Write value to send buffer */ template - void _write_to_buf(T const &value) + void insert(T const &value) { /* check buffer range */ - if (_write_offset + sizeof(T) >= _sndbuf_size) return; + if (_write_offset + sizeof(T) >= _snd_buf_size) return; /* write integer to buffer */ - *reinterpret_cast(&_sndbuf[_write_offset]) = value; + *reinterpret_cast(&_snd_buf[_write_offset]) = value; /* increment write pointer to next dword-aligned value */ _write_offset += align_natural(sizeof(T)); } + template + void insert(Rpc_in_buffer const &b) + { + size_t const size = b.size(); + insert(size); + insert(b.base(), size); + } + /** * Write bytes to send buffer */ - void _write_to_buf(char const *src_addr, unsigned num_bytes) + void insert(char const *src_addr, unsigned num_bytes) { /* check buffer range */ - if (_write_offset + num_bytes >= _sndbuf_size) return; + if (_write_offset + num_bytes >= _snd_buf_size) return; /* copy buffer */ - memcpy(&_sndbuf[_write_offset], src_addr, num_bytes); + memcpy(&_snd_buf[_write_offset], src_addr, num_bytes); /* increment write pointer to next dword-aligned value */ _write_offset += align_natural(num_bytes); } /** - * Write 'Rpc_in_buffer' to send buffer + * Insert capability to message buffer */ - void _write_buffer_to_buf(Rpc_in_buffer_base const &b) + void insert(Native_capability const &cap); + + template + void insert(Capability const &typed_cap) { - size_t size = b.size(); - _write_to_buf(size); - _write_to_buf(b.base(), size); + Native_capability untyped_cap = typed_cap; + insert(untyped_cap); } - /** - * Write array to send buffer - */ - template - void _write_to_buf(T const (&array)[N]) - { - /* check buffer range */ - if (_write_offset + sizeof(array) >= _sndbuf_size) - PERR("send buffer overrun"); - - memcpy(&_sndbuf[_write_offset], array, sizeof(array)); - _write_offset += align_natural(sizeof(array)); - } - - public: - - Ipc_marshaller(char *sndbuf, size_t sndbuf_size) - : _sndbuf(sndbuf), _sndbuf_size(sndbuf_size), _write_offset(0) { } + Ipc_marshaller(Msgbuf_base &snd_msg) : _snd_msg(snd_msg) { } }; @@ -136,36 +127,33 @@ class Genode::Ipc_unmarshaller { protected: - char *_rcvbuf; - size_t _rcvbuf_size; - unsigned _read_offset; + Msgbuf_base &_rcv_msg; + unsigned _read_offset = 0; - protected: + private: - /** - * Read value of type T from buffer - */ - template - void _read_from_buf(T &value) + char *_rcv_buf = (char *)_rcv_msg.data(); + size_t const _rcv_buf_size = _rcv_msg.size(); + + public: + + template + void extract(Capability &typed_cap) { - /* check receive buffer range */ - if (_read_offset + sizeof(T) >= _rcvbuf_size) return; - - /* return value from receive buffer */ - value = *reinterpret_cast(&_rcvbuf[_read_offset]); - - /* increment read pointer to next dword-aligned value */ - _read_offset += align_natural(sizeof(T)); + Native_capability untyped_cap; + extract(untyped_cap); + typed_cap = reinterpret_cap_cast(untyped_cap); } /** * Read 'Rpc_in_buffer' from receive buffer */ - void _read_bytebuf_from_buf(Rpc_in_buffer_base &b) + template + void extract(Rpc_in_buffer &b) { size_t size = 0; - _read_from_buf(size); - b = Rpc_in_buffer_base(0, 0); + extract(size); + b = Rpc_in_buffer(0, 0); /* * Check receive buffer range @@ -173,241 +161,62 @@ class Genode::Ipc_unmarshaller * Note: The addr of the Rpc_in_buffer_base is a null pointer when this * condition triggers. */ - if (_read_offset + size >= _rcvbuf_size) { + if (_read_offset + size >= _rcv_buf_size) { PERR("message buffer overrun"); return; } - b = Rpc_in_buffer_base(&_rcvbuf[_read_offset], size); + b = Rpc_in_buffer(&_rcv_buf[_read_offset], size); _read_offset += align_natural(size); } - /** - * Read array from receive buffer - */ - template - void _read_from_buf(T (&array)[N]) - { - if (_read_offset + sizeof(array) >= _rcvbuf_size) { - PERR("receive buffer overrun"); - return; - } - - memcpy(array, &_rcvbuf[_read_offset], sizeof(array)); - _read_offset += align_natural(sizeof(array)); - } - - /** - * Read long value at specified byte index of receive buffer - */ - long _long_at_idx(int idx) { return *(long *)(&_rcvbuf[idx]); } - - public: - - Ipc_unmarshaller(char *rcvbuf, size_t rcvbuf_size) - : _rcvbuf(rcvbuf), _rcvbuf_size(rcvbuf_size), _read_offset(0) { } -}; - - -/** - * Stream for sending information via a capability to an endpoint - */ -class Genode::Ipc_ostream : public Ipc_marshaller -{ - protected: - - Msgbuf_base *_snd_msg; /* send message buffer */ - Native_capability _dst; - - /** - * Reset marshaller and write badge at the beginning of the message - */ - void _prepare_next_send(); - - /** - * Insert capability to message buffer - */ - void _marshal_capability(Native_capability const &cap); - - public: - - /** - * Constructor - */ - Ipc_ostream(Native_capability dst, Msgbuf_base *snd_msg); - - /** - * Return true if Ipc_ostream is ready for send - */ - bool ready_for_send() const { return _dst.valid(); } - - /** - * Insert value into send buffer - */ - template - Ipc_ostream &operator << (T const &value) - { - _write_to_buf(value); - return *this; - } - - /** - * Insert byte buffer to send buffer - */ - Ipc_ostream &operator << (Rpc_in_buffer_base const &b) - { - _write_buffer_to_buf(b); - return *this; - } - - /** - * Insert capability to send buffer - */ - Ipc_ostream &operator << (Native_capability const &cap) - { - _marshal_capability(cap); - return *this; - } - - /** - * Insert typed capability to send buffer - */ - template - Ipc_ostream &operator << (Capability const &typed_cap) - { - _marshal_capability(typed_cap); - return *this; - } - - /** - * Return current 'IPC_SEND' destination - * - * This method is typically needed by a server than sends replies - * in a different order as the incoming calls. - */ - Native_capability dst() const { return _dst; } - - /** - * Set destination for the next 'IPC_SEND' - */ - void dst(Native_capability const &dst) { _dst = dst; } -}; - - -/** - * Stream for receiving information - */ -class Genode::Ipc_istream : public Ipc_unmarshaller, public Native_capability -{ - private: - - /** - * Prevent 'Ipc_istream' objects from being copied - * - * Copying an 'Ipc_istream' object would result in a duplicated - * (and possibly inconsistent) connection state both the original - * and the copied object. - */ - Ipc_istream(const Ipc_istream &); - - protected: - - Msgbuf_base *_rcv_msg; - /** * Obtain capability from message buffer */ - void _unmarshal_capability(Native_capability &cap); - - protected: + void extract(Native_capability &cap); /** - * Reset unmarshaller + * Read value of type T from buffer */ - void _prepare_next_receive(); + template + void extract(T &value) + { + /* check receive buffer range */ + if (_read_offset + sizeof(T) >= _rcv_buf_size) return; + + /* return value from receive buffer */ + value = *reinterpret_cast(&_rcv_buf[_read_offset]); + + /* increment read pointer to next dword-aligned value */ + _read_offset += align_natural(sizeof(T)); + } + public: - explicit Ipc_istream(Msgbuf_base *rcv_msg); - - ~Ipc_istream(); - - /** - * Read badge that was supplied with the message - */ - long badge() { return _long_at_idx(0); } - - /** - * Read values from receive buffer - */ - template - Ipc_istream &operator >> (T &value) - { - _read_from_buf(value); - return *this; - } - - /** - * Read byte buffer from receive buffer - */ - Ipc_istream &operator >> (Rpc_in_buffer_base &b) - { - _read_bytebuf_from_buf(b); - return *this; - } - - /** - * Read byte buffer from receive buffer - */ - template - Ipc_istream &operator >> (Rpc_in_buffer &b) - { - _read_bytebuf_from_buf(b); - return *this; - } - - /** - * Read capability from receive buffer - */ - Ipc_istream &operator >> (Native_capability &cap) - { - _unmarshal_capability(cap); - return *this; - } - - /** - * Read typed capability from receive buffer - */ - template - Ipc_istream &operator >> (Capability &typed_cap) - { - _unmarshal_capability(typed_cap); - return *this; - } + Ipc_unmarshaller(Msgbuf_base &rcv_msg) : _rcv_msg(rcv_msg) { } }; -class Genode::Ipc_client: public Ipc_istream, public Ipc_ostream +class Genode::Ipc_client : public Ipc_marshaller, public Ipc_unmarshaller, + public Noncopyable { protected: - int _result; /* result of most recent call */ + int _result = 0; /* result of most recent call */ - void _prepare_next_call(); - - /** - * Send RPC message and wait for result - */ - void _call(); + Native_capability _dst; /** * Set return value if call to server failed */ void ret(int retval) { - *reinterpret_cast(&_rcvbuf[sizeof(umword_t)]) = retval; + reinterpret_cast(_rcv_msg.data())[1] = retval; } + void _call(); + public: enum { ERR_INVALID_OBJECT = -70000, }; @@ -415,119 +224,41 @@ class Genode::Ipc_client: public Ipc_istream, public Ipc_ostream /** * Constructor */ - Ipc_client(Native_capability const &srv, Msgbuf_base *snd_msg, - Msgbuf_base *rcv_msg, unsigned short rcv_caps = ~0); + Ipc_client(Native_capability const &dst, + Msgbuf_base &snd_msg, Msgbuf_base &rcv_msg, + unsigned short rcv_caps = ~0); /** - * Operator that issues an IPC call + * Send RPC message and wait for result * * \throw Ipc_error - * \throw Blocking_canceled */ - Ipc_client &operator << (Ipc_client_call) + void call() { _call(); - _read_from_buf(_result); + extract(_result); if (_result == ERR_INVALID_OBJECT) throw Ipc_error(); - return *this; - } - - template - Ipc_client &operator << (T const &value) - { - _write_to_buf(value); - return *this; - } - - Ipc_client &operator << (Rpc_in_buffer_base const &b) - { - _write_buffer_to_buf(b); - return *this; - } - - template - Ipc_client &operator << (Rpc_in_buffer const &b) - { - _write_buffer_to_buf(b); - return *this; - } - - Ipc_client &operator << (Native_capability const &cap) - { - _marshal_capability(cap); - return *this; - } - - template - Ipc_client &operator << (Capability const &typed_cap) - { - _marshal_capability(typed_cap); - return *this; - } - - Ipc_client &operator >> (Native_capability &cap) - { - _unmarshal_capability(cap); - return *this; - } - - template - Ipc_client &operator >> (Capability &typed_cap) - { - _unmarshal_capability(typed_cap); - return *this; - } - - template - Ipc_client &operator >> (T &value) - { - _read_from_buf(value); - return *this; - } - - Ipc_client &operator >> (Rpc_in_buffer_base &b) - { - _read_bytebuf_from_buf(b); - return *this; } int result() const { return _result; } }; -class Genode::Ipc_server : public Ipc_istream, public Ipc_ostream +class Genode::Ipc_server : public Ipc_marshaller, public Ipc_unmarshaller, + public Noncopyable, public Native_capability { protected: bool _reply_needed; /* false for the first reply_wait */ + Native_capability _caller; + Native_connection_state &_rcv_cs; void _prepare_next_reply_wait(); - /** - * Wait for incoming call - * - * In constrast to 'Ipc_istream::_wait()', this method stores the - * next reply destination from into 'dst' of the 'Ipc_ostream'. - */ - void _wait(); - - /** - * Send reply to destination - * - * In contrast to 'Ipc_ostream::_send()', this method prepares - * the 'Ipc_server' to send another subsequent reply without the - * calling '_wait()' in between. This is needed when a server - * answers calls out of order. - */ - void _reply(); - - /** - * Send result of previous RPC request and wait for new one - */ - void _reply_wait(); + unsigned long _badge; public: @@ -535,81 +266,48 @@ class Genode::Ipc_server : public Ipc_istream, public Ipc_ostream * Constructor */ Ipc_server(Native_connection_state &, - Msgbuf_base *snd_msg, Msgbuf_base *rcv_msg); + Msgbuf_base &snd_msg, Msgbuf_base &rcv_msg); ~Ipc_server(); + /** + * Wait for incoming call + */ + void wait(); + + /** + * Send reply to destination + */ + void reply(); + + /** + * Send result of previous RPC request and wait for new one + */ + void reply_wait(); + /** * Set return value of server call */ void ret(int retval) { - *reinterpret_cast(&_sndbuf[sizeof(umword_t)]) = retval; + reinterpret_cast(_snd_msg.data())[1] = retval; } + /** + * Read badge that was supplied with the message + */ + unsigned long badge() const { return _badge; } + /** * Set reply destination */ - void dst(Native_capability const &reply_dst) + void caller(Native_capability const &caller) { - Ipc_ostream::dst(reply_dst); - _reply_needed = reply_dst.valid(); + _caller = caller; + _reply_needed = caller.valid(); } - using Ipc_ostream::dst; - - /** - * Block for an incoming message filling the receive buffer - */ - Ipc_server &operator >> (Ipc_istream_wait) - { - _wait(); - return *this; - } - - /** - * Issue the sending of the message buffer - */ - Ipc_server &operator << (Ipc_server_reply) - { - _reply(); - return *this; - } - - /** - * Reply current request and wait for a new one - */ - Ipc_server &operator >> (Ipc_server_reply_wait) - { - _reply_wait(); - return *this; - } - - /** - * Write value to send buffer - * - * This operator is only used by test programs - */ - template - Ipc_server &operator << (T const &value) - { - _write_to_buf(value); - return *this; - } - - /** - * Read value from receive buffer - * - * This operator should only be used by the server framework for - * reading the function offset. The server-side processing of the - * payload is done using 'Ipc_istream' and 'Ipc_ostream'. - */ - template - Ipc_server &operator >> (T &value) - { - _read_from_buf(value); - return *this; - } + Native_capability caller() const { return _caller; } }; #endif /* _INCLUDE__BASE__IPC_H_ */ diff --git a/repos/base/include/base/rpc_client.h b/repos/base/include/base/rpc_client.h index f5082e906..c40abb293 100644 --- a/repos/base/include/base/rpc_client.h +++ b/repos/base/include/base/rpc_client.h @@ -61,7 +61,7 @@ namespace Genode { _marshal_args(Ipc_client &ipc_client, ATL &args) const { if (Trait::Rpc_direction::Type::IN) - ipc_client << args.get(); + ipc_client.insert(args.get()); _marshal_args(ipc_client, args._2); } @@ -73,7 +73,7 @@ namespace Genode { _unmarshal_result(Ipc_client &ipc_client, T &arg, Meta::Overload_selector) const { - ipc_client >> arg; + ipc_client.extract(arg); } @@ -124,14 +124,14 @@ namespace Genode { Msgbuf call_buf; Msgbuf reply_buf; - Ipc_client ipc_client(*this, &call_buf, &reply_buf, CAP_BY_VALUE); + Ipc_client ipc_client(*this, call_buf, reply_buf, CAP_BY_VALUE); /* determine opcode of RPC function */ typedef typename RPC_INTERFACE::Rpc_functions Rpc_functions; Rpc_opcode opcode = static_cast(Meta::Index_of::Value); /* marshal opcode and RPC input arguments */ - ipc_client << opcode; + ipc_client.insert(opcode); _marshal_args(ipc_client, args); { @@ -139,7 +139,8 @@ namespace Genode { } /* perform RPC, unmarshal return value */ - ipc_client << IPC_CALL >> ret; + ipc_client.call(); + ipc_client.extract(ret); { Trace::Rpc_returned trace_event(IF::name(), reply_buf); diff --git a/repos/base/include/base/rpc_server.h b/repos/base/include/base/rpc_server.h index 90d8959ea..afe41b052 100644 --- a/repos/base/include/base/rpc_server.h +++ b/repos/base/include/base/rpc_server.h @@ -60,26 +60,26 @@ class Genode::Rpc_dispatcher : public RPC_INTERFACE protected: template - void _read_args(Ipc_istream &is, ARG_LIST &args) + void _read_args(Ipc_unmarshaller &msg, ARG_LIST &args) { if (Trait::Rpc_direction::Type::IN) - is >> args._1; + msg.extract(args._1); - _read_args(is, args._2); + _read_args(msg, args._2); } - void _read_args(Ipc_istream &, Meta::Empty) { } + void _read_args(Ipc_unmarshaller &, Meta::Empty) { } template - void _write_results(Ipc_ostream &os, ARG_LIST &args) + void _write_results(Ipc_marshaller &msg, ARG_LIST &args) { if (Trait::Rpc_direction::Type::OUT) - os << args._1; + msg.insert(args._1); - _write_results(os, args._2); + _write_results(msg, args._2); } - void _write_results(Ipc_ostream &, Meta::Empty) { } + void _write_results(Ipc_marshaller &, Meta::Empty) { } template Rpc_exception_code _do_serve(typename RPC_FUNCTION::Server_args &args, @@ -104,7 +104,8 @@ class Genode::Rpc_dispatcher : public RPC_INTERFACE } template - Rpc_exception_code _do_dispatch(Rpc_opcode opcode, Ipc_istream &is, Ipc_ostream &os, + Rpc_exception_code _do_dispatch(Rpc_opcode opcode, + Ipc_unmarshaller &in, Ipc_marshaller &out, Meta::Overload_selector) { using namespace Meta; @@ -115,8 +116,8 @@ class Genode::Rpc_dispatcher : public RPC_INTERFACE typename This_rpc_function::Server_args args{}; - /* read arguments from istream */ - _read_args(is, args); + /* read arguments from incoming message */ + _read_args(in, args); { Trace::Rpc_dispatch trace_event(This_rpc_function::name()); @@ -132,23 +133,23 @@ class Genode::Rpc_dispatcher : public RPC_INTERFACE typename This_rpc_function::Ret_type ret { }; Rpc_exception_code exc; exc = _do_serve(args, ret, Overload_selector()); - os << ret; + out.insert(ret); { Trace::Rpc_reply trace_event(This_rpc_function::name()); } - /* write results to ostream 'os' */ - _write_results(os, args); + /* write results to outgoing message */ + _write_results(out, args); return exc; } typedef typename RPC_FUNCTIONS_TO_CHECK::Tail Tail; - return _do_dispatch(opcode, is, os, Overload_selector()); + return _do_dispatch(opcode, in, out, Overload_selector()); } - int _do_dispatch(int opcode, Ipc_istream &, Ipc_ostream &, + int _do_dispatch(int opcode, Ipc_unmarshaller &, Ipc_marshaller &, Meta::Overload_selector) { PERR("invalid opcode %d\n", opcode); @@ -158,7 +159,8 @@ class Genode::Rpc_dispatcher : public RPC_INTERFACE /** * Handle corner case of having an RPC interface with no RPC functions */ - Rpc_exception_code _do_dispatch(int opcode, Ipc_istream &, Ipc_ostream &, + Rpc_exception_code _do_dispatch(int opcode, + Ipc_unmarshaller &, Ipc_marshaller &, Meta::Overload_selector >) { return 0; @@ -173,9 +175,10 @@ class Genode::Rpc_dispatcher : public RPC_INTERFACE public: - Rpc_exception_code dispatch(int opcode, Ipc_istream &is, Ipc_ostream &os) + Rpc_exception_code dispatch(int opcode, + Ipc_unmarshaller &in, Ipc_marshaller &out) { - return _do_dispatch(opcode, is, os, + return _do_dispatch(opcode, in, out, Meta::Overload_selector()); } }; @@ -191,10 +194,10 @@ class Genode::Rpc_object_base : public Object_pool::Entry * Interface to be implemented by a derived class * * \param op opcode of invoked method - * \param is Ipc_input stream with method arguments - * \param os Ipc_output stream for storing method results + * \param in incoming message with method arguments + * \param out outgoing message for storing method results */ - virtual int dispatch(int op, Ipc_istream &is, Ipc_ostream &os) = 0; + virtual int dispatch(int op, Ipc_unmarshaller &in, Ipc_marshaller &out) = 0; }; @@ -212,9 +215,9 @@ struct Genode::Rpc_object : Rpc_object_base, Rpc_dispatcher::dispatch(opcode, is, os); + return Rpc_dispatcher::dispatch(opcode, in, out); } Capability const cap() const diff --git a/repos/base/src/base/ipc/ipc_marshal_cap.cc b/repos/base/src/base/ipc/ipc_marshal_cap.cc index 3d62b3b03..f3292a2cc 100644 --- a/repos/base/src/base/ipc/ipc_marshal_cap.cc +++ b/repos/base/src/base/ipc/ipc_marshal_cap.cc @@ -19,16 +19,18 @@ using namespace Genode; /** * Marshalling of capabilities as plain data representation */ -void Ipc_ostream::_marshal_capability(Native_capability const &cap) +void Ipc_marshaller::insert(Native_capability const &cap) { - _write_to_buf(cap); + insert((char const *)&cap, sizeof(Native_capability)); } /** * Unmarshalling of capabilities as plain data representation */ -void Ipc_istream::_unmarshal_capability(Native_capability &cap) +void Ipc_unmarshaller::extract(Native_capability &cap) { - _read_from_buf(cap); + struct Raw { char buf[sizeof(Native_capability)]; } raw; + extract(raw); + (Raw &)(cap) = raw; } diff --git a/repos/base/src/base/server/common.cc b/repos/base/src/base/server/common.cc index 99971baa6..f918c26dd 100644 --- a/repos/base/src/base/server/common.cc +++ b/repos/base/src/base/server/common.cc @@ -38,14 +38,14 @@ void Rpc_entrypoint::_block_until_cap_valid() Untyped_capability Rpc_entrypoint::reply_dst() { - return _ipc_server ? _ipc_server->dst() : Untyped_capability(); + return _ipc_server ? _ipc_server->caller() : Untyped_capability(); } void Rpc_entrypoint::omit_reply() { /* set current destination to an invalid capability */ - if (_ipc_server) _ipc_server->dst(Untyped_capability()); + if (_ipc_server) _ipc_server->caller(Untyped_capability()); } @@ -55,15 +55,16 @@ void Rpc_entrypoint::reply_signal_info(Untyped_capability reply_cap, if (!_ipc_server) return; /* backup reply capability of current request */ - Untyped_capability last_reply_cap = _ipc_server->dst(); + Untyped_capability last_reply_cap = _ipc_server->caller(); /* direct ipc server to the specified reply destination */ _ipc_server->ret(0); - _ipc_server->dst(reply_cap); - *_ipc_server << Signal_source::Signal(imprint, cnt) << IPC_REPLY; + _ipc_server->caller(reply_cap); + _ipc_server->insert(Signal_source::Signal(imprint, cnt)); + _ipc_server->reply(); /* restore reply capability of the original request */ - _ipc_server->dst(last_reply_cap); + _ipc_server->caller(last_reply_cap); } diff --git a/repos/base/src/base/server/server.cc b/repos/base/src/base/server/server.cc index 1325a9f63..8e974cdae 100644 --- a/repos/base/src/base/server/server.cc +++ b/repos/base/src/base/server/server.cc @@ -48,7 +48,7 @@ void Rpc_entrypoint::entry() using Pool = Object_pool; Native_connection_state cs; - Ipc_server srv(cs, &_snd_buf, &_rcv_buf); + Ipc_server srv(cs, _snd_buf, _rcv_buf); _ipc_server = &srv; _cap = srv; _cap_valid.unlock(); @@ -66,7 +66,8 @@ void Rpc_entrypoint::entry() int opcode = 0; - srv >> IPC_REPLY_WAIT >> opcode; + srv.reply_wait(); + srv.extract(opcode); /* set default return value */ srv.ret(Ipc_client::ERR_INVALID_OBJECT); @@ -81,7 +82,7 @@ void Rpc_entrypoint::entry() } /* answer exit call, thereby wake up '~Rpc_entrypoint' */ - srv << IPC_REPLY; + srv.reply(); /* defer the destruction of 'Ipc_server' until '~Rpc_entrypoint' is ready */ _delay_exit.lock(); diff --git a/repos/base/src/core/pager_object.cc b/repos/base/src/core/pager_object.cc index c145e8a5e..fd11e2cf3 100644 --- a/repos/base/src/core/pager_object.cc +++ b/repos/base/src/core/pager_object.cc @@ -22,8 +22,9 @@ void Pager_object::wake_up() /* notify pager to wake up faulter */ Msgbuf<16> snd, rcv; Native_capability pager = cap(); - Ipc_client ipc_client(pager, &snd, &rcv); - ipc_client << this << IPC_CALL; + Ipc_client ipc_client(pager, snd, rcv); + ipc_client.insert(this); + ipc_client.call(); }