diff options
Diffstat (limited to 'libcr_ipc/sema.c')
-rw-r--r-- | libcr_ipc/sema.c | 34 |
1 files changed, 9 insertions, 25 deletions
diff --git a/libcr_ipc/sema.c b/libcr_ipc/sema.c index a8b5ec4..5f489aa 100644 --- a/libcr_ipc/sema.c +++ b/libcr_ipc/sema.c @@ -6,27 +6,11 @@ #include <assert.h> -#include "coroutine_sema.h" - -struct cid_list { - cid_t val; - struct cid_list *next; -}; - -/* head->next->next->tail */ - -struct _cr_sema { - int cnt; - - struct cid_list *head, **tail; - /* locked indicates that a call from within a coroutine is is - * messing with ->{head,tail}, so a signal handler can't read - * it. */ - bool locked; -}; +#include <libcr/coroutine.h> +#include <libcr_ipc/sema.h> /** Drain the sema->{head,tail} list. Returns true if cr_getcid() was drained. */ -static inline bool drain(volatile cr_sema_t *sema) { +static inline bool drain(cr_sema_t *sema) { assert(!sema->locked); cid_t self = cr_getcid(); @@ -59,21 +43,21 @@ static inline bool drain(volatile cr_sema_t *sema) { /* If there are still coroutines in sema->head, check * that sema->cnt wasn't incremented between `if * (!sema->cnt)` and `sema->locked = false`. */ - } while (state == DRAINED_SOME && cnt); + } while (state == DRAINED_SOME && sema->cnt); /* If state == DRAINED_SELF, then we better have been the last * item in the list! */ assert(state != DRAINED_SELF || !sema->head); return state == DRAINED_SELF; } -void cr_sema_signal(volatile cr_sema_t *sema) { +void cr_sema_signal(cr_sema_t *sema) { sema->cnt++; if (!sema->locked) - drain(); + drain(sema); } -void cr_sema_wait(volatile cr_sema_t *sema) { - struct cid_list self = { +void cr_sema_wait(cr_sema_t *sema) { + struct _cr_sema_cid_list self = { .val = cr_getcid(), .next = NULL, }; @@ -86,7 +70,7 @@ void cr_sema_wait(volatile cr_sema_t *sema) { sema->tail = &(self.next); sema->locked = false; - if (drain()) + if (drain(sema)) /* DRAINED_SELF: (1) No need to pause+yield, (2) we * better have been the last item in the list! */ assert(!self.next); |