summaryrefslogtreecommitdiff
path: root/libcr_ipc
diff options
context:
space:
mode:
Diffstat (limited to 'libcr_ipc')
-rw-r--r--libcr_ipc/CMakeLists.txt1
-rw-r--r--libcr_ipc/include/libcr_ipc/mutex.h46
-rw-r--r--libcr_ipc/include/libcr_ipc/sema.h6
-rw-r--r--libcr_ipc/mutex.c37
-rw-r--r--libcr_ipc/sema.c3
5 files changed, 90 insertions, 3 deletions
diff --git a/libcr_ipc/CMakeLists.txt b/libcr_ipc/CMakeLists.txt
index 3388fcd..957b638 100644
--- a/libcr_ipc/CMakeLists.txt
+++ b/libcr_ipc/CMakeLists.txt
@@ -7,6 +7,7 @@ add_library(libcr_ipc INTERFACE)
target_include_directories(libcr_ipc SYSTEM INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
target_sources(libcr_ipc INTERFACE
sema.c
+ mutex.c
)
target_link_libraries(libcr_ipc INTERFACE
libcr
diff --git a/libcr_ipc/include/libcr_ipc/mutex.h b/libcr_ipc/include/libcr_ipc/mutex.h
new file mode 100644
index 0000000..38ebde0
--- /dev/null
+++ b/libcr_ipc/include/libcr_ipc/mutex.h
@@ -0,0 +1,46 @@
+/* libcr_ipc/mutex.h - Simple mutexes for libcr (header file)
+ *
+ * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * SPDX-Licence-Identifier: AGPL-3.0-or-later
+ */
+
+#ifndef _COROUTINE_MUTEX_H_
+#define _COROUTINE_MUTEX_H_
+
+#include <stdbool.h> /* for bool */
+
+#include <libcr/coroutine.h> /* for cid_t */
+
+struct _cr_mutex_cid_list {
+ cid_t val;
+ struct _cr_mutex_cid_list *next;
+};
+
+/**
+ * A cr_mutex_t is a fair mutex.
+ */
+typedef struct {
+ bool locked;
+ struct _cr_mutex_cid_list *head, **tail;
+} cr_mutex_t;
+
+/**
+ * Lock the mutex. Blocks if it is already locked.
+ *
+ * @blocks maybe
+ * @yields maybe
+ * @run_in coroutine
+ */
+void cr_mutex_lock(cr_mutex_t *);
+
+/**
+ * Unlock the mutex. Unblocks a coroutine that is blocked on
+ * cr_mutex_lock().
+ *
+ * @blocks never
+ * @yields never
+ * @may_run_in coroutine
+ */
+void cr_mutex_unluck(cr_mutex_t *);
+
+#endif /* _COROUTINE_MUTEX_H_ */
diff --git a/libcr_ipc/include/libcr_ipc/sema.h b/libcr_ipc/include/libcr_ipc/sema.h
index a2a176d..454eb5d 100644
--- a/libcr_ipc/include/libcr_ipc/sema.h
+++ b/libcr_ipc/include/libcr_ipc/sema.h
@@ -1,4 +1,4 @@
-/* coroutine_sema.h - Simple semaphores for coroutine.{h,c}
+/* libcr_ipc/sema.h - Simple semaphores for libcr (header file)
*
* Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
* SPDX-Licence-Identifier: AGPL-3.0-or-later
@@ -7,6 +7,10 @@
#ifndef _COROUTINE_SEMA_H_
#define _COROUTINE_SEMA_H_
+#include <stdbool.h> /* for bool */
+
+#include <libcr/coroutine.h> /* for cid_t */
+
struct _cr_sema_cid_list {
cid_t val;
struct _cr_sema_cid_list *next;
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;
+}
diff --git a/libcr_ipc/sema.c b/libcr_ipc/sema.c
index a3b2ca0..9645a41 100644
--- a/libcr_ipc/sema.c
+++ b/libcr_ipc/sema.c
@@ -1,4 +1,4 @@
-/* coroutine_sema.h - Simple semaphores for coroutine.{h,c}
+/* 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
@@ -6,7 +6,6 @@
#include <assert.h>
-#include <libcr/coroutine.h>
#include <libcr_ipc/sema.h>
/** Drain the sema->{head,tail} list. Returns true if cr_getcid() was drained. */