diff options
Diffstat (limited to 'libcr_ipc')
-rw-r--r-- | libcr_ipc/include/libcr_ipc/_common.h | 19 | ||||
-rw-r--r-- | libcr_ipc/include/libcr_ipc/chan.h | 137 | ||||
-rw-r--r-- | libcr_ipc/include/libcr_ipc/mutex.h | 9 | ||||
-rw-r--r-- | libcr_ipc/include/libcr_ipc/rpc.h | 22 | ||||
-rw-r--r-- | libcr_ipc/include/libcr_ipc/sema.h | 7 | ||||
-rw-r--r-- | libcr_ipc/mutex.c | 4 | ||||
-rw-r--r-- | libcr_ipc/sema.c | 2 |
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, }; |