summaryrefslogtreecommitdiff
path: root/libcr_ipc/mutex.c
diff options
context:
space:
mode:
authorLuke T. Shumaker <lukeshu@lukeshu.com>2024-09-28 20:50:36 -0600
committerLuke T. Shumaker <lukeshu@lukeshu.com>2024-09-28 20:54:43 -0600
commitf410026b7bc96dbb42fec3839dc5d2e41b12f4a4 (patch)
tree22e831eb47101ee4e3635fcaf2729a81a178823c /libcr_ipc/mutex.c
parentf898850c2b4fef03f0d175ec052b3725bd406496 (diff)
misc
Diffstat (limited to 'libcr_ipc/mutex.c')
-rw-r--r--libcr_ipc/mutex.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/libcr_ipc/mutex.c b/libcr_ipc/mutex.c
new file mode 100644
index 0000000..c5cea96
--- /dev/null
+++ b/libcr_ipc/mutex.c
@@ -0,0 +1,37 @@
+/* libcr_ipc/mutex.c - Simple mutexes for libcr (implementation file)
+ *
+ * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * SPDX-Licence-Identifier: AGPL-3.0-or-later
+ */
+
+#include <libcr_ipc/mutex.h>
+
+void cr_mutex_lock(cr_mutex_t *mu) {
+ assert(mu);
+ if (!mu->tail)
+ mu->tail = &mu->head;
+ if (!mu->locked) {
+ mu->locked = true;
+ return;
+ }
+ struct _cr_mutex_cid_list self = {
+ .val = cr_getcid(),
+ .next = NULL,
+ };
+ *(mu->tail) = &self;
+ mu->tail = &(self.next);
+ cr_pause_and_yield();
+}
+
+void cr_mutex_unlock(cr_mutex_t *mu) {
+ assert(mu);
+ assert(mu->tail);
+ assert(mu->locked);
+ if (mu->head) {
+ cr_unpause(mu->head->val);
+ mu->head = mu->head->next;
+ if (!mu->head)
+ mu->tail = &mu->head;
+ } else
+ mu->locked = false;
+}