diff options
Diffstat (limited to 'libcr_ipc')
-rw-r--r-- | libcr_ipc/chan.c | 38 | ||||
-rw-r--r-- | libcr_ipc/include/libcr_ipc/chan.h | 8 | ||||
-rw-r--r-- | libcr_ipc/include/libcr_ipc/mutex.h | 8 | ||||
-rw-r--r-- | libcr_ipc/include/libcr_ipc/rpc.h | 6 | ||||
-rw-r--r-- | libcr_ipc/include/libcr_ipc/rwmutex.h | 12 | ||||
-rw-r--r-- | libcr_ipc/include/libcr_ipc/sema.h | 10 | ||||
-rw-r--r-- | libcr_ipc/mutex.c | 12 | ||||
-rw-r--r-- | libcr_ipc/rpc.c | 34 | ||||
-rw-r--r-- | libcr_ipc/rwmutex.c | 45 | ||||
-rw-r--r-- | libcr_ipc/sema.c | 25 |
10 files changed, 101 insertions, 97 deletions
diff --git a/libcr_ipc/chan.c b/libcr_ipc/chan.c index 6ccfa44..6cbe890 100644 --- a/libcr_ipc/chan.c +++ b/libcr_ipc/chan.c @@ -16,17 +16,17 @@ /* base channels **************************************************************/ struct cr_chan_waiter { - lm_dll_node; cid_t cid; void *val_ptr; void (*dequeue)(void *, size_t); void *dequeue_arg1; size_t dequeue_arg2; }; +DLIST_DECLARE_NODE(_cr_chan_waiter_list, struct cr_chan_waiter); void cr_chan_dequeue(void *_ch, size_t) { struct _cr_chan *ch = _ch; - lm_dll_pop_from_front(&ch->waiters); + dlist_pop_from_front(&ch->waiters); } void _cr_chan_xfer(enum _cr_chan_waiter_typ self_typ, struct _cr_chan *ch, void *val_ptr, size_t val_size) { @@ -35,23 +35,23 @@ void _cr_chan_xfer(enum _cr_chan_waiter_typ self_typ, struct _cr_chan *ch, void if (ch->waiters.front && ch->waiter_typ != self_typ) { /* non-blocking fast-path */ /* Copy. */ - struct cr_chan_waiter *front = lm_dll_node_cast(struct cr_chan_waiter, ch->waiters.front); + struct _cr_chan_waiter_list_node *front = ch->waiters.front; if (self_typ == _CR_CHAN_SENDER) - memcpy(front->val_ptr, val_ptr, val_size); + memcpy(front->val.val_ptr, val_ptr, val_size); else - memcpy(val_ptr, front->val_ptr, val_size); - cr_unpause(front->cid); - front->dequeue(front->dequeue_arg1, - front->dequeue_arg2); + memcpy(val_ptr, front->val.val_ptr, val_size); + cr_unpause(front->val.cid); + front->val.dequeue(front->val.dequeue_arg1, + front->val.dequeue_arg2); cr_yield(); } else { /* blocking slow-path */ - struct cr_chan_waiter self = { + struct _cr_chan_waiter_list_node self = { .val = { .cid = cr_getcid(), .val_ptr = val_ptr, .dequeue = cr_chan_dequeue, .dequeue_arg1 = ch, - }; - lm_dll_push_to_rear(&ch->waiters, &self); + }}; + dlist_push_to_rear(&ch->waiters, &self); ch->waiter_typ = self_typ; cr_pause_and_yield(); } @@ -66,9 +66,9 @@ enum cr_select_class { }; struct cr_select_waiters { - size_t cnt; - struct cr_select_arg *args; - struct cr_chan_waiter *nodes; + size_t cnt; + struct cr_select_arg *args; + struct _cr_chan_waiter_list_node *nodes; }; static inline enum cr_select_class cr_select_getclass(struct cr_select_arg arg) { @@ -93,8 +93,8 @@ static inline enum cr_select_class cr_select_getclass(struct cr_select_arg arg) void cr_select_dequeue(void *_waiters, size_t idx) { struct cr_select_waiters *waiters = _waiters; for (size_t i = 0; i < waiters->cnt; i++) - lm_dll_remove(&(waiters->args[i].ch->waiters), - &(waiters->nodes[i])); + dlist_remove(&(waiters->args[i].ch->waiters), + &(waiters->nodes[i])); waiters->cnt = idx; } @@ -153,14 +153,14 @@ size_t cr_select_v(size_t arg_cnt, struct cr_select_arg arg_vec[]) { .nodes = alloca(sizeof(struct cr_chan_waiter) * arg_cnt), }; for (size_t i = 0; i < arg_cnt; i++) { - waiters.nodes[i] = (struct cr_chan_waiter){ + waiters.nodes[i] = (struct _cr_chan_waiter_list_node){ .val = { .cid = cr_getcid(), .val_ptr = arg_vec[i].val_ptr, .dequeue = cr_select_dequeue, .dequeue_arg1 = &waiters, .dequeue_arg2 = i, - }; - lm_dll_push_to_rear(&arg_vec[i].ch->waiters, &waiters.nodes[i]); + }}; + dlist_push_to_rear(&arg_vec[i].ch->waiters, &waiters.nodes[i]); } cr_pause_and_yield(); return waiters.cnt; diff --git a/libcr_ipc/include/libcr_ipc/chan.h b/libcr_ipc/include/libcr_ipc/chan.h index 5282725..5a87643 100644 --- a/libcr_ipc/include/libcr_ipc/chan.h +++ b/libcr_ipc/include/libcr_ipc/chan.h @@ -10,7 +10,7 @@ #include <stdbool.h> /* for bool */ #include <stddef.h> /* for size_t */ -#include <libmisc/linkedlist.h> /* for lm_dll_root */ +#include <libmisc/linkedlist.h> /* for DLIST_DECLARE() */ /* base channels **************************************************************/ @@ -106,9 +106,11 @@ enum _cr_chan_waiter_typ { _CR_CHAN_RECVER, }; +DLIST_DECLARE(_cr_chan_waiter_list); + struct _cr_chan { - enum _cr_chan_waiter_typ waiter_typ; - lm_dll_root waiters; + enum _cr_chan_waiter_typ waiter_typ; + struct _cr_chan_waiter_list waiters; }; void _cr_chan_xfer(enum _cr_chan_waiter_typ self_typ, struct _cr_chan *ch, void *val_ptr, size_t val_size); diff --git a/libcr_ipc/include/libcr_ipc/mutex.h b/libcr_ipc/include/libcr_ipc/mutex.h index 0f3c9c2..e5f43c8 100644 --- a/libcr_ipc/include/libcr_ipc/mutex.h +++ b/libcr_ipc/include/libcr_ipc/mutex.h @@ -9,9 +9,11 @@ #include <stdbool.h> /* for bool */ -#include <libmisc/linkedlist.h> +#include <libmisc/linkedlist.h> /* for SLIST_DECLARE() */ #include <libmisc/private.h> +SLIST_DECLARE(_cr_mutex_waiter_list); + /** * A cr_mutex_t is a fair mutex. * @@ -22,8 +24,8 @@ */ typedef struct { BEGIN_PRIVATE(LIBCR_IPC_MUTEX_H); - bool locked; - lm_sll_root waiters; + bool locked; + struct _cr_mutex_waiter_list waiters; END_PRIVATE(LIBCR_IPC_MUTEX_H); } cr_mutex_t; diff --git a/libcr_ipc/include/libcr_ipc/rpc.h b/libcr_ipc/include/libcr_ipc/rpc.h index ff75034..ecf48cf 100644 --- a/libcr_ipc/include/libcr_ipc/rpc.h +++ b/libcr_ipc/include/libcr_ipc/rpc.h @@ -9,7 +9,7 @@ #include <stdbool.h> /* for bool */ -#include <libmisc/linkedlist.h> /* for lm_sll_root */ +#include <libmisc/linkedlist.h> /* for SLIST_DECLARE() */ /** * CR_RPC_DECLARE(NAME, REQ_T, RESP_T) declares the following types: @@ -132,9 +132,11 @@ enum _cr_rpc_waiter_typ { _CR_RPC_RESPONDER, }; +SLIST_DECLARE(_cr_rpc_waiter_list); + struct _cr_rpc { enum _cr_rpc_waiter_typ waiter_typ; - lm_sll_root waiters; + struct _cr_rpc_waiter_list waiters; }; void _cr_rpc_send_req(struct _cr_rpc *ch, void *req_ptr, size_t req_size, void *resp_ptr); diff --git a/libcr_ipc/include/libcr_ipc/rwmutex.h b/libcr_ipc/include/libcr_ipc/rwmutex.h index d48abe9..8ccae63 100644 --- a/libcr_ipc/include/libcr_ipc/rwmutex.h +++ b/libcr_ipc/include/libcr_ipc/rwmutex.h @@ -9,9 +9,11 @@ #include <stdbool.h> -#include <libmisc/linkedlist.h> +#include <libmisc/linkedlist.h> /* for SLIST_DECLARE() */ #include <libmisc/private.h> +SLIST_DECLARE(_cr_rwmutex_waiter_list); + /** * A cr_rwmutex_t is a fair read/write mutex. * @@ -25,10 +27,10 @@ */ typedef struct { BEGIN_PRIVATE(LIBCR_IPC_RWMUTEX_H); - unsigned nreaders; - bool locked; - bool unpausing; - lm_sll_root waiters; + unsigned nreaders; + bool locked; + bool unpausing; + struct _cr_rwmutex_waiter_list waiters; END_PRIVATE(LIBCR_IPC_RWMUTEX_H); } cr_rwmutex_t; diff --git a/libcr_ipc/include/libcr_ipc/sema.h b/libcr_ipc/include/libcr_ipc/sema.h index cc387f4..8b5ac5b 100644 --- a/libcr_ipc/include/libcr_ipc/sema.h +++ b/libcr_ipc/include/libcr_ipc/sema.h @@ -9,9 +9,11 @@ #include <stdbool.h> -#include <libmisc/linkedlist.h> +#include <libmisc/linkedlist.h> /* for SLIST_DECLARE() */ #include <libmisc/private.h> +SLIST_DECLARE(_cr_sema_waiter_list); + /** * A cr_sema_t is a fair unbounded[1] counting semaphore. * @@ -19,9 +21,9 @@ */ typedef struct { BEGIN_PRIVATE(LIBCR_IPC_SEMA_H); - unsigned int cnt; - bool unpausing; - lm_sll_root waiters; + unsigned int cnt; + bool unpausing; + struct _cr_sema_waiter_list waiters; END_PRIVATE(LIBCR_IPC_SEMA_H); } cr_sema_t; diff --git a/libcr_ipc/mutex.c b/libcr_ipc/mutex.c index 4a87a58..1b4e626 100644 --- a/libcr_ipc/mutex.c +++ b/libcr_ipc/mutex.c @@ -11,9 +11,9 @@ #include <libcr_ipc/mutex.h> struct cr_mutex_waiter { - lm_sll_node; cid_t cid; }; +SLIST_DECLARE_NODE(_cr_mutex_waiter_list, struct cr_mutex_waiter); void cr_mutex_lock(cr_mutex_t *mu) { assert(mu); @@ -22,10 +22,10 @@ void cr_mutex_lock(cr_mutex_t *mu) { if (!mu->locked) /* non-blocking fast-path */ mu->locked = true; else { /* blocking slow-path */ - struct cr_mutex_waiter self = { + struct _cr_mutex_waiter_list_node self = { .val = { .cid = cr_getcid(), - }; - lm_sll_push_to_rear(&mu->waiters, &self); + }}; + slist_push_to_rear(&mu->waiters, &self); cr_pause_and_yield(); } assert(mu->locked); @@ -37,8 +37,8 @@ void cr_mutex_unlock(cr_mutex_t *mu) { assert(mu->locked); if (mu->waiters.front) { - cr_unpause(lm_sll_node_cast(struct cr_mutex_waiter, mu->waiters.front)->cid); - lm_sll_pop_from_front(&mu->waiters); + cr_unpause(mu->waiters.front->val.cid); + slist_pop_from_front(&mu->waiters); } else mu->locked = false; } diff --git a/libcr_ipc/rpc.c b/libcr_ipc/rpc.c index 227f03b..fcf51ba 100644 --- a/libcr_ipc/rpc.c +++ b/libcr_ipc/rpc.c @@ -12,19 +12,21 @@ #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); @@ -32,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. */ @@ -44,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(); @@ -63,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; } } diff --git a/libcr_ipc/rwmutex.c b/libcr_ipc/rwmutex.c index 0da92df..191b7fe 100644 --- a/libcr_ipc/rwmutex.c +++ b/libcr_ipc/rwmutex.c @@ -11,26 +11,26 @@ #include <libcr_ipc/rwmutex.h> struct cr_rwmutex_waiter { - lm_sll_node; bool is_reader; cid_t cid; }; +SLIST_DECLARE_NODE(_cr_rwmutex_waiter_list, struct cr_rwmutex_waiter); void cr_rwmutex_lock(cr_rwmutex_t *mu) { assert(mu); cr_assert_in_coroutine(); - struct cr_rwmutex_waiter self = { + struct _cr_rwmutex_waiter_list_node self = { .val = { .is_reader = false, .cid = cr_getcid(), - }; - lm_sll_push_to_rear(&mu->waiters, &self); - if (mu->waiters.front != &self.lm_sll_node || mu->locked) + }}; + slist_push_to_rear(&mu->waiters, &self); + if (mu->waiters.front != &self || mu->locked) cr_pause_and_yield(); - assert(mu->waiters.front == &self.lm_sll_node); + assert(mu->waiters.front == &self); /* We now hold the lock (and are mu->waiters.front). */ - lm_sll_pop_from_front(&mu->waiters); + slist_pop_from_front(&mu->waiters); assert(mu->nreaders == 0); mu->locked = true; mu->unpausing = false; @@ -40,24 +40,23 @@ void cr_rwmutex_rlock(cr_rwmutex_t *mu) { assert(mu); cr_assert_in_coroutine(); - struct cr_rwmutex_waiter self = { + struct _cr_rwmutex_waiter_list_node self = { .val = { .is_reader = true, .cid = cr_getcid(), - }; - lm_sll_push_to_rear(&mu->waiters, &self); - if (mu->waiters.front != &self.lm_sll_node || (mu->locked && mu->nreaders == 0)) + }}; + slist_push_to_rear(&mu->waiters, &self); + if (mu->waiters.front != &self || (mu->locked && mu->nreaders == 0)) cr_pause_and_yield(); - assert(mu->waiters.front == &self.lm_sll_node); + assert(mu->waiters.front == &self); /* We now hold the lock (and are mu->waiters.front). */ - lm_sll_pop_from_front(&mu->waiters); + slist_pop_from_front(&mu->waiters); mu->nreaders++; mu->locked = true; - struct cr_rwmutex_waiter *waiter = - lm_sll_node_cast(struct cr_rwmutex_waiter, mu->waiters.front); - if (waiter && waiter->is_reader) { + struct _cr_rwmutex_waiter_list_node *waiter = mu->waiters.front; + if (waiter && waiter->val.is_reader) { assert(mu->unpausing); - cr_unpause(waiter->cid); + cr_unpause(waiter->val.cid); } else { mu->unpausing = false; } @@ -71,10 +70,9 @@ void cr_rwmutex_unlock(cr_rwmutex_t *mu) { assert(mu->nreaders == 0); assert(!mu->unpausing); if (mu->waiters.front) { - struct cr_rwmutex_waiter *waiter = - lm_sll_node_cast(struct cr_rwmutex_waiter, mu->waiters.front); + struct _cr_rwmutex_waiter_list_node *waiter = mu->waiters.front; mu->unpausing = true; - cr_unpause(waiter->cid); + cr_unpause(waiter->val.cid); } else { mu->locked = false; } @@ -89,11 +87,10 @@ void cr_rwmutex_runlock(cr_rwmutex_t *mu) { mu->nreaders--; if (mu->nreaders == 0 && !mu->unpausing) { if (mu->waiters.front) { - struct cr_rwmutex_waiter *waiter = - lm_sll_node_cast(struct cr_rwmutex_waiter, mu->waiters.front); - assert(!waiter->is_reader); + struct _cr_rwmutex_waiter_list_node *waiter = mu->waiters.front; + assert(!waiter->val.is_reader); mu->unpausing = true; - cr_unpause(waiter->cid); + cr_unpause(waiter->val.cid); } else { mu->locked = false; } diff --git a/libcr_ipc/sema.c b/libcr_ipc/sema.c index 212d421..f2ac9b6 100644 --- a/libcr_ipc/sema.c +++ b/libcr_ipc/sema.c @@ -11,9 +11,9 @@ #include <libcr_ipc/sema.h> struct cr_sema_waiter { - lm_sll_node; - cid_t cid; + cid_t cid; }; +SLIST_DECLARE_NODE(_cr_sema_waiter_list, struct cr_sema_waiter); void cr_sema_signal(cr_sema_t *sema) { assert(sema); @@ -22,8 +22,7 @@ void cr_sema_signal(cr_sema_t *sema) { bool saved = cr_save_and_disable_interrupts(); sema->cnt++; if (sema->waiters.front && !sema->unpausing) { - cr_unpause( - lm_sll_node_cast(struct cr_sema_waiter, sema->waiters.front)->cid); + cr_unpause(sema->waiters.front->val.cid); sema->unpausing = true; } cr_restore_interrupts(saved); @@ -35,8 +34,7 @@ void cr_sema_signal_from_intrhandler(cr_sema_t *sema) { sema->cnt++; if (sema->waiters.front && !sema->unpausing) { - cr_unpause_from_intrhandler( - lm_sll_node_cast(struct cr_sema_waiter, sema->waiters.front)->cid); + cr_unpause_from_intrhandler(sema->waiters.front->val.cid); sema->unpausing = true; } } @@ -47,18 +45,17 @@ void cr_sema_wait(cr_sema_t *sema) { bool saved = cr_save_and_disable_interrupts(); - struct cr_sema_waiter self = { + struct _cr_sema_waiter_list_node self = { .val = { .cid = cr_getcid(), - }; - lm_sll_push_to_rear(&sema->waiters, &self); - if (sema->waiters.front != &self.lm_sll_node || !sema->cnt) + }}; + slist_push_to_rear(&sema->waiters, &self); + if (sema->waiters.front != &self || !sema->cnt) cr_pause_and_yield(); - assert(sema->waiters.front == &self.lm_sll_node && sema->cnt); - lm_sll_pop_from_front(&sema->waiters); + assert(sema->waiters.front == &self && sema->cnt); + slist_pop_from_front(&sema->waiters); sema->cnt--; if (sema->cnt && sema->waiters.front) - cr_unpause( - lm_sll_node_cast(struct cr_sema_waiter, sema->waiters.front)->cid); + cr_unpause(sema->waiters.front->val.cid); else sema->unpausing = false; cr_restore_interrupts(saved); |