summaryrefslogtreecommitdiff
path: root/libcr_ipc
diff options
context:
space:
mode:
Diffstat (limited to 'libcr_ipc')
-rw-r--r--libcr_ipc/include/libcr_ipc/_common.h19
-rw-r--r--libcr_ipc/include/libcr_ipc/chan.h137
-rw-r--r--libcr_ipc/include/libcr_ipc/mutex.h9
-rw-r--r--libcr_ipc/include/libcr_ipc/rpc.h22
-rw-r--r--libcr_ipc/include/libcr_ipc/sema.h7
-rw-r--r--libcr_ipc/mutex.c4
-rw-r--r--libcr_ipc/sema.c2
7 files changed, 111 insertions, 89 deletions
diff --git a/libcr_ipc/include/libcr_ipc/_common.h b/libcr_ipc/include/libcr_ipc/_common.h
new file mode 100644
index 0000000..5efe964
--- /dev/null
+++ b/libcr_ipc/include/libcr_ipc/_common.h
@@ -0,0 +1,19 @@
+/* libcr_ipc/_common.h - TODO
+ *
+ * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * SPDX-Licence-Identifier: AGPL-3.0-or-later
+ */
+
+#ifndef _COROUTINE__COMMON_H_
+#define _COROUTINE__COMMON_H_
+
+struct _cr_ipc_cid_list {
+ cid_t val;
+ struct _cr_ipc_cid_list *next;
+};
+
+#define _cr_ipc_static_assert_sametype(a, b, msg) \
+ static_assert(_Generic(a, typeof(b): 1, default: 0), msg)
+#define _cr_ipc_str(a) #a
+
+#endif /* _COROUTINE__COMMON_H_ */
diff --git a/libcr_ipc/include/libcr_ipc/chan.h b/libcr_ipc/include/libcr_ipc/chan.h
index 66ea1c4..ca53fc2 100644
--- a/libcr_ipc/include/libcr_ipc/chan.h
+++ b/libcr_ipc/include/libcr_ipc/chan.h
@@ -20,14 +20,14 @@
* cr_chan_t(val_t) returns the type definition for a channel on
* that transports values of type `val_t`.
*/
-#define cr_chan_t(val_t) struct { \
- bool ok_to_write; \
- cid_t reader, *tail_reader; \
- val_t *reader_val; \
- \
- bool ok_to_read; \
- cid_t writer, *tail_writer; \
- val_t *writer_val; \
+#define cr_chan_t(val_t) struct { \
+ bool ok_to_write; \
+ cid_t reader, *tail_reader; \
+ val_t *reader_val; \
+ \
+ bool ok_to_read; \
+ cid_t writer, *tail_writer; \
+ val_t *writer_val; \
}
/* These "functions" are preprocessor macros instead of real C
@@ -37,67 +37,76 @@
/**
* ch_chan_send(*ch, val) sends `val` over `ch`.
*/
-#define cr_chan_send(ch, _val) do { \
- if ((ch)->ok_to_write) { /* non-blocking */ \
- *((ch)->reader_val) = (_val); \
- (ch)->ok_to_write = false; \
- cr_unpause((ch)->reader); \
- } else { /* blocking */ \
- cid_t next = 0; \
- if ((ch)->writer) { \
- *((ch)->tail_writer) = cr_getcid(); \
- (ch)->tail_writer = &next; \
- cr_pause_and_yield(); \
- } else { \
- (ch)->writer = cr_getcid(); \
- (ch)->tail_writer = &next; \
- } \
- assert((ch)->writer == cr_getcid()); \
- (ch)->writer_val = &(_val); \
- (ch)->ok_to_read = true; \
- cr_pause_and_yield(); \
- assert((ch)->ok_to_read == false); \
- if (next) { \
- (ch)->writer = next; \
- cr_unpause(next); \
- } else { \
- (ch)->writer = 0; \
- (ch)->tail_writer = NULL; \
- } \
- } \
+#define cr_chan_send(ch, _val) do { \
+ _cr_ipc_static_assert_sametype(_val, *(ch)->reader_val, \
+ "wrong val type for chan: " \
+ _cr_ipc_str(_val)); \
+ assert(ch); \
+ if ((ch)->ok_to_write) { /* non-blocking */ \
+ *((ch)->reader_val) = (_val); \
+ (ch)->ok_to_write = false; \
+ cr_unpause((ch)->reader); \
+ } else { /* blocking */ \
+ typeof(*(ch)->writer_val) _val_lvalue = _val; \
+ cid_t next = 0; \
+ if ((ch)->writer) { \
+ *((ch)->tail_writer) = cr_getcid(); \
+ (ch)->tail_writer = &next; \
+ cr_pause_and_yield(); \
+ } else { \
+ (ch)->writer = cr_getcid(); \
+ (ch)->tail_writer = &next; \
+ } \
+ assert((ch)->writer == cr_getcid()); \
+ (ch)->writer_val = &_val_lvalue; \
+ (ch)->ok_to_read = true; \
+ cr_pause_and_yield(); \
+ assert((ch)->ok_to_read == false); \
+ if (next) { \
+ (ch)->writer = next; \
+ cr_unpause(next); \
+ } else { \
+ (ch)->writer = 0; \
+ (ch)->tail_writer = NULL; \
+ } \
+ } \
} while (0)
/**
* cr_chan_recv(ch, val_p) reads a value from ch into `*val_p`.
*/
-#define cr_chan_recv(ch, _val_p) do { \
- if ((ch)->ok_to_read) { /* non-blocking */ \
- *(_val_p) = *((ch)->writer_val); \
- (ch)->ok_to_read = false; \
- cr_unpause((ch)->writer; \
- } else { /* blocking */ \
- cid_t next = 0; \
- if ((ch)->reader) { \
- *((ch)->tail_reader) = cr_getcid(); \
- (ch)->tail_reader = &next; \
- cr_pause_and_yield(); \
- } else { \
- (ch)->reader = cr_getcid(); \
- (ch)->tail_reader = &next; \
- } \
- assert((ch)->reader == cr_getcid()); \
- (ch)->reader_val = (_val_p); \
- (ch)->ok_to_write = true; \
- cr_pause_and_yield(); \
- assert((ch)->ok_to_write == false); \
- if (next) { \
- (ch)->reader = next; \
- cr_unpause(next); \
- } else { \
- (ch)->reader = 0; \
- (ch)->tail_reader = NULL; \
- } \
- } \
+#define cr_chan_recv(ch, _val_p) do { \
+ _cr_ipc_static_assert_sametype(_val_p, (ch)->reader_val, \
+ "wrong val_p type for chan: " \
+ _cr_ipc_str(_val_p)); \
+ assert(ch); \
+ if ((ch)->ok_to_read) { /* non-blocking */ \
+ *(_val_p) = *((ch)->writer_val); \
+ (ch)->ok_to_read = false; \
+ cr_unpause((ch)->writer); \
+ } else { /* blocking */ \
+ cid_t next = 0; \
+ if ((ch)->reader) { \
+ *((ch)->tail_reader) = cr_getcid(); \
+ (ch)->tail_reader = &next; \
+ cr_pause_and_yield(); \
+ } else { \
+ (ch)->reader = cr_getcid(); \
+ (ch)->tail_reader = &next; \
+ } \
+ assert((ch)->reader == cr_getcid()); \
+ (ch)->reader_val = (_val_p); \
+ (ch)->ok_to_write = true; \
+ cr_pause_and_yield(); \
+ assert((ch)->ok_to_write == false); \
+ if (next) { \
+ (ch)->reader = next; \
+ cr_unpause(next); \
+ } else { \
+ (ch)->reader = 0; \
+ (ch)->tail_reader = NULL; \
+ } \
+ } \
} while (0)
/**
diff --git a/libcr_ipc/include/libcr_ipc/mutex.h b/libcr_ipc/include/libcr_ipc/mutex.h
index 38ebde0..1a82423 100644
--- a/libcr_ipc/include/libcr_ipc/mutex.h
+++ b/libcr_ipc/include/libcr_ipc/mutex.h
@@ -11,17 +11,14 @@
#include <libcr/coroutine.h> /* for cid_t */
-struct _cr_mutex_cid_list {
- cid_t val;
- struct _cr_mutex_cid_list *next;
-};
+#include <libcr_ipc/_common.h> /* for struct _cr_ipc_list_t */
/**
* A cr_mutex_t is a fair mutex.
*/
typedef struct {
bool locked;
- struct _cr_mutex_cid_list *head, **tail;
+ struct _cr_ipc_cid_list *head, **tail;
} cr_mutex_t;
/**
@@ -41,6 +38,6 @@ void cr_mutex_lock(cr_mutex_t *);
* @yields never
* @may_run_in coroutine
*/
-void cr_mutex_unluck(cr_mutex_t *);
+void cr_mutex_unlock(cr_mutex_t *);
#endif /* _COROUTINE_MUTEX_H_ */
diff --git a/libcr_ipc/include/libcr_ipc/rpc.h b/libcr_ipc/include/libcr_ipc/rpc.h
index 3c42f34..2525ba8 100644
--- a/libcr_ipc/include/libcr_ipc/rpc.h
+++ b/libcr_ipc/include/libcr_ipc/rpc.h
@@ -15,6 +15,8 @@
#include <libcr/coroutine.h>
+#include <libcr_ipc/_common.h> /* for _cr_ipc_* */
+
/**
* cr_rpc_t(req_t, resp_t) returns the type definition for a
* rpc-channel on which the requester submits a value of type `req_t`
@@ -31,10 +33,6 @@
resp_t *resp_p; \
}
-#define _cr_rpc_static_assert_sametype(a, b, msg) \
- static_assert(_Generic(a, typeof(b): 1, default: 0), msg)
-#define _cr_rpc_str(a) #a
-
/* These "functions" are preprocessor macros instead of real C
* functions so that the compiler can do type-checking instead of
* having these functions take `void*`. */
@@ -48,12 +46,12 @@
*/
#define cr_rpc_req(ch, _resp_p, _req) do { \
typeof(_req) _req_lvalue = _req; \
- _cr_rpc_static_assert_sametype(_resp_p, (ch)->resp_p, \
+ _cr_ipc_static_assert_sametype(_resp_p, (ch)->resp_p, \
"wrong resp_p type for rpc chan: " \
- _cr_rpc_str(_resp_p)); \
- _cr_rpc_static_assert_sametype(&_req_lvalue, (ch)->req_p, \
+ _cr_ipc_str(_resp_p)); \
+ _cr_ipc_static_assert_sametype(&_req_lvalue, (ch)->req_p, \
"wrong req type for rpc chan: " \
- _cr_rpc_str(_req)); \
+ _cr_ipc_str(_req)); \
assert(ch); \
assert(_resp_p); \
cid_t next = 0; \
@@ -98,9 +96,9 @@
* Blocking: Maybe.
*/
#define cr_rpc_recv_req(ch, _req_p) do { \
- _cr_rpc_static_assert_sametype(_req_p, (ch)->req_p, \
+ _cr_ipc_static_assert_sametype(_req_p, (ch)->req_p, \
"wrong req_p type for rpc chan: " \
- _cr_rpc_str(_req_p)); \
+ _cr_ipc_str(_req_p)); \
assert(ch); \
assert(_req_p); \
(ch)->responder = cr_getcid(); \
@@ -117,9 +115,9 @@
* Blocking: Never.
*/
#define cr_rpc_send_resp(ch, _resp) do { \
- _cr_rpc_static_assert_sametype(_resp, *(ch)->resp_p, \
+ _cr_ipc_static_assert_sametype(_resp, *(ch)->resp_p, \
"wrong resp type for rpc chan: " \
- _cr_rpc_str(_reps)); \
+ _cr_ipc_str(_reps)); \
assert(ch); \
(ch)->responder = 0; \
*((ch)->resp_p) = (_resp); \
diff --git a/libcr_ipc/include/libcr_ipc/sema.h b/libcr_ipc/include/libcr_ipc/sema.h
index 454eb5d..236e7e5 100644
--- a/libcr_ipc/include/libcr_ipc/sema.h
+++ b/libcr_ipc/include/libcr_ipc/sema.h
@@ -11,10 +11,7 @@
#include <libcr/coroutine.h> /* for cid_t */
-struct _cr_sema_cid_list {
- cid_t val;
- struct _cr_sema_cid_list *next;
-};
+#include <libcr_ipc/_common.h> /* for struct _cr_ipc_list_t */
/**
* A cr_sema_t is a fair unbounded[1] counting semaphore.
@@ -24,7 +21,7 @@ struct _cr_sema_cid_list {
typedef volatile struct {
int cnt;
- struct _cr_sema_cid_list *head, **tail;
+ struct _cr_ipc_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. */
diff --git a/libcr_ipc/mutex.c b/libcr_ipc/mutex.c
index c5cea96..198c738 100644
--- a/libcr_ipc/mutex.c
+++ b/libcr_ipc/mutex.c
@@ -4,6 +4,8 @@
* SPDX-Licence-Identifier: AGPL-3.0-or-later
*/
+#include <assert.h>
+
#include <libcr_ipc/mutex.h>
void cr_mutex_lock(cr_mutex_t *mu) {
@@ -14,7 +16,7 @@ void cr_mutex_lock(cr_mutex_t *mu) {
mu->locked = true;
return;
}
- struct _cr_mutex_cid_list self = {
+ struct _cr_ipc_cid_list self = {
.val = cr_getcid(),
.next = NULL,
};
diff --git a/libcr_ipc/sema.c b/libcr_ipc/sema.c
index 9645a41..a3efb57 100644
--- a/libcr_ipc/sema.c
+++ b/libcr_ipc/sema.c
@@ -59,7 +59,7 @@ void cr_sema_signal(cr_sema_t *sema) {
}
void cr_sema_wait(cr_sema_t *sema) {
- struct _cr_sema_cid_list self = {
+ struct _cr_ipc_cid_list self = {
.val = cr_getcid(),
.next = NULL,
};