diff options
Diffstat (limited to 'libcr_ipc/rpc.c')
-rw-r--r-- | libcr_ipc/rpc.c | 35 |
1 files changed, 18 insertions, 17 deletions
diff --git a/libcr_ipc/rpc.c b/libcr_ipc/rpc.c index 6d9422f..fcf51ba 100644 --- a/libcr_ipc/rpc.c +++ b/libcr_ipc/rpc.c @@ -7,23 +7,26 @@ #include <string.h> /* for memcpy() */ #include <libcr/coroutine.h> /* for cid_t, cr_* */ +#include <libmisc/assert.h> #include <libcr_ipc/rpc.h> struct cr_rpc_requester { - lm_sll_node; cid_t cid; void *req_ptr; /* where to read req from */ void *resp_ptr; /* where to write resp to */ }; - struct cr_rpc_responder { - lm_sll_node; /* before enqueued | after dequeued */ /* -------------------+-------------------- */ cid_t cid; /* responder cid | requester cid */ void *ptr; /* where to write req | where to write resp */ }; +union cr_rpc_waiter { + struct cr_rpc_requester requester; + struct cr_rpc_responder responder; +}; +SLIST_DECLARE_NODE(_cr_rpc_waiter_list, union cr_rpc_waiter); void _cr_rpc_send_req(struct _cr_rpc *ch, void *req_ptr, size_t req_size, void *resp_ptr) { assert(ch); @@ -31,9 +34,8 @@ void _cr_rpc_send_req(struct _cr_rpc *ch, void *req_ptr, size_t req_size, void * assert(resp_ptr); if (ch->waiters.front && ch->waiter_typ != _CR_RPC_REQUESTER) { /* fast-path (still blocks) */ - struct cr_rpc_responder *responder = - lm_sll_node_cast(struct cr_rpc_responder, ch->waiters.front); - lm_sll_pop_from_front(&ch->waiters); + struct cr_rpc_responder *responder = &ch->waiters.front->val.responder; + slist_pop_from_front(&ch->waiters); /* Copy the req to the responder's stack. */ memcpy(responder->ptr, req_ptr, req_size); /* Notify the responder that we have done so. */ @@ -43,12 +45,12 @@ void _cr_rpc_send_req(struct _cr_rpc *ch, void *req_ptr, size_t req_size, void * /* Wait for the responder to set `*resp_ptr`. */ cr_pause_and_yield(); } else { /* blocking slow-path */ - struct cr_rpc_requester self = { + struct _cr_rpc_waiter_list_node self = { .val = { .requester = { .cid = cr_getcid(), .req_ptr = req_ptr, .resp_ptr = resp_ptr, - }; - lm_sll_push_to_rear(&ch->waiters, &self); + }}}; + slist_push_to_rear(&ch->waiters, &self); /* Wait for a responder to both copy our req and sed * `*resp_ptr`. */ cr_pause_and_yield(); @@ -62,22 +64,21 @@ void _cr_rpc_recv_req(struct _cr_rpc *ch, void *req_ptr, size_t req_size, void * assert(ret_requester); if (ch->waiters.front && ch->waiter_typ != _CR_RPC_RESPONDER) { /* non-blocking fast-path */ - struct cr_rpc_requester *requester = - lm_sll_node_cast(struct cr_rpc_requester, ch->waiters.front); - lm_sll_pop_from_front(&ch->waiters); + struct cr_rpc_requester *requester = &ch->waiters.front->val.requester; + slist_pop_from_front(&ch->waiters); memcpy(req_ptr, requester->req_ptr, req_size); *ret_requester = requester->cid; *ret_resp_ptr = requester->resp_ptr; } else { /* blocking slow-path */ - struct cr_rpc_responder self = { + struct _cr_rpc_waiter_list_node self = { .val = { .responder = { .cid = cr_getcid(), .ptr = req_ptr, - }; - lm_sll_push_to_rear(&ch->waiters, &self); + }}}; + slist_push_to_rear(&ch->waiters, &self); ch->waiter_typ = _CR_RPC_RESPONDER; cr_pause_and_yield(); - *ret_requester = self.cid; - *ret_resp_ptr = self.ptr; + *ret_requester = self.val.responder.cid; + *ret_resp_ptr = self.val.responder.ptr; } } |