diff options
author | Luke T. Shumaker <lukeshu@lukeshu.com> | 2025-04-15 08:42:24 -0600 |
---|---|---|
committer | Luke T. Shumaker <lukeshu@lukeshu.com> | 2025-04-15 08:42:24 -0600 |
commit | 802ed1e3cd0252cafd1be2aada0addf4d3f7eb2e (patch) | |
tree | 70f49ed30f0f9839709a093c6af54661eeaad4ee /libcr_ipc/rwmutex.c | |
parent | 0450e14b3a86e4448537c03253eeebf509f8909e (diff) | |
parent | 32a1b710b40ce9d53cd0a7bc0c183da87e07f397 (diff) |
Merge branch 'lukeshu/generics'
Diffstat (limited to 'libcr_ipc/rwmutex.c')
-rw-r--r-- | libcr_ipc/rwmutex.c | 46 |
1 files changed, 22 insertions, 24 deletions
diff --git a/libcr_ipc/rwmutex.c b/libcr_ipc/rwmutex.c index 4c5da81..191b7fe 100644 --- a/libcr_ipc/rwmutex.c +++ b/libcr_ipc/rwmutex.c @@ -5,31 +5,32 @@ */ #include <libcr/coroutine.h> /* for cid_t, cr_* */ +#include <libmisc/assert.h> #define IMPLEMENTATION_FOR_LIBCR_IPC_RWMUTEX_H YES #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; @@ -39,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; } @@ -70,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; } @@ -88,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; } |