summaryrefslogtreecommitdiff
path: root/libcr_ipc/sema.c
diff options
context:
space:
mode:
Diffstat (limited to 'libcr_ipc/sema.c')
-rw-r--r--libcr_ipc/sema.c81
1 files changed, 0 insertions, 81 deletions
diff --git a/libcr_ipc/sema.c b/libcr_ipc/sema.c
deleted file mode 100644
index a3efb57..0000000
--- a/libcr_ipc/sema.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/* libcr_ipc/sema.c - Simple semaphores for libcr (implementation file)
- *
- * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
- * SPDX-Licence-Identifier: AGPL-3.0-or-later
- */
-
-#include <assert.h>
-
-#include <libcr_ipc/sema.h>
-
-/** Drain the sema->{head,tail} list. Returns true if cr_getcid() was drained. */
-static inline bool drain(cr_sema_t *sema) {
- assert(!sema->locked);
- cid_t self = cr_getcid();
-
- enum drain_result {
- DRAINING,
- DRAINED_SELF, /* stopped because drained `self` */
- DRAINED_ALL, /* stopped because sema->head == NULL */
- DRAINED_SOME, /* stopped because sema->cnt == 0 */
- } state = DRAINING;
- do {
- sema->locked = true;
- while (state == DRAINING) {
- if (!sema->head) {
- state = DRAINED_ALL;
- } else if (!sema->cnt) {
- state = DRAINED_SOME;
- } else {
- sema->cnt--;
- cid_t cid = sema->head->val;
- if (cid == self)
- state = DRAINED_SELF;
- else
- cr_unpause(sema->head->val);
- sema->head = sema->head->next;
- if (!sema->head)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wdiscarded-qualifiers"
- sema->tail = &sema->head;
-#pragma GCC diagnostic pop
- }
- }
- sema->locked = false;
- /* 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 && 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(cr_sema_t *sema) {
- sema->cnt++;
- if (!sema->locked)
- drain(sema);
-}
-
-void cr_sema_wait(cr_sema_t *sema) {
- struct _cr_ipc_cid_list self = {
- .val = cr_getcid(),
- .next = NULL,
- };
-
- sema->locked = true;
- if (!sema->tail)
- sema->head = &self;
- else
- *(sema->tail) = &self;
- sema->tail = &(self.next);
- sema->locked = false;
-
- 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);
- else
- cr_pause_and_yield();
-}