summaryrefslogtreecommitdiff
path: root/libcr_ipc
diff options
context:
space:
mode:
authorLuke T. Shumaker <lukeshu@lukeshu.com>2024-11-25 14:39:33 -0700
committerLuke T. Shumaker <lukeshu@lukeshu.com>2024-11-25 14:40:06 -0700
commit9aad7d02fedca1e265c5433060e57c8f9b6e3b01 (patch)
treec5ba11faf17839322ad3c95915e18925f4741c61 /libcr_ipc
parentcce21287a154dea92ae9005aebe8c0b650faa173 (diff)
libcr_ipc: _linkedlist.h: Use inline functions, not macros
Diffstat (limited to 'libcr_ipc')
-rw-r--r--libcr_ipc/include/libcr_ipc/_linkedlist.h168
-rw-r--r--libcr_ipc/include/libcr_ipc/chan.h17
-rw-r--r--libcr_ipc/include/libcr_ipc/mutex.h8
-rw-r--r--libcr_ipc/include/libcr_ipc/rpc.h22
-rw-r--r--libcr_ipc/include/libcr_ipc/sema.h12
5 files changed, 107 insertions, 120 deletions
diff --git a/libcr_ipc/include/libcr_ipc/_linkedlist.h b/libcr_ipc/include/libcr_ipc/_linkedlist.h
index e5aa52a..67bff24 100644
--- a/libcr_ipc/include/libcr_ipc/_linkedlist.h
+++ b/libcr_ipc/include/libcr_ipc/_linkedlist.h
@@ -11,98 +11,90 @@
/* singly linked list *********************************************************/
-/* The `root` type should have a ->front pointer and a ->rear pointer
- * that point to the front and rear nodes respectively; or NULL if the
- * list is empty.
- *
- * The `node` type should have a ->rear pointer that points to the
- * node to the rear of it.
- *
- * ex:
- *
- * typedef struct {
- * MY_NODE *rear;
- * ...node_data...
- * } MY_NODE;
- *
- * typedef struct {
- * MY_NODE *front, *rear;
- * ...root_data...
- * } MY_ROOT;
- */
+typedef struct __cr_ipc_sll_node {
+ struct __cr_ipc_sll_node *rear;
+} _cr_ipc_sll_node;
-#define _cr_ipc_sll_push_to_rear(root, node) do { \
- assert(root); \
- (node)->rear = NULL; \
- if ((root)->rear) \
- (root)->rear->rear = node; \
- else { \
- (root)->front = node; \
- (root)->rear = node; \
- } \
- } while(0)
-
-#define _cr_ipc_sll_pop_from_front(root) do { \
- assert(root); \
- assert((root)->front); \
- (root)->front = (root)->front->rear; \
- if (!((root)->front)) \
- (root)->rear = NULL; \
- } while(0)
+typedef struct {
+ _cr_ipc_sll_node *front, *rear;
+} _cr_ipc_sll_root;
+
+#define _cr_ipc_sll_node_cast(node_typ, node_ptr) \
+ ({ \
+ static_assert(_Generic(node_ptr, _cr_ipc_sll_node *: 1, default: 0), \
+ "typeof("#node_ptr") != _cr_ipc_sll_node *"); \
+ assert(node_ptr); \
+ static_assert(offsetof(node_typ, _cr_ipc_sll_node) == 0); \
+ ((node_typ*)(node_ptr)); \
+ })
+
+static inline void _cr_ipc_sll_push_to_rear(_cr_ipc_sll_root *root, _cr_ipc_sll_node *node) {
+ assert(root);
+ node->rear = NULL;
+ if (root->rear)
+ root->rear->rear = node;
+ else {
+ root->front = node;
+ root->rear = node;
+ }
+}
+
+static inline void _cr_ipc_sll_pop_from_front(_cr_ipc_sll_root *root) {
+ assert(root);
+ assert(root->front);
+ root->front = root->front->rear;
+ if (!root->front)
+ root->rear = NULL;
+}
/* doubly linked list *********************************************************/
-/* The `root` type should have a ->front pointer and a ->rear pointer
- * that point to the front and rear nodes respectively; or NULL if the
- * list is empty.
- *
- * The `node` type should also have a ->front pointer that points to
- * the node in front of it, or NULL if it is the front; and a ->rear
- * pointer that points to the node to the rear of it, or NULL if it is
- * the rear.
- *
- * ex:
- *
- * typedef struct {
- * MY_NODE *front, *rear;
- * ...node_data...
- * } MY_NODE;
- *
- * typedef struct {
- * MY_NODE *front, *rear;
- * ...root_data...
- * } MY_ROOT;
- */
+typedef struct __cr_ipc_dll_node {
+ struct __cr_ipc_dll_node *front, *rear;
+} _cr_ipc_dll_node;
+
+typedef struct {
+ _cr_ipc_dll_node *front, *rear;
+} _cr_ipc_dll_root;
+
+#define _cr_ipc_dll_node_cast(node_typ, node_ptr) \
+ ({ \
+ static_assert(_Generic(node_ptr, _cr_ipc_dll_node *: 1, default: 0), \
+ "typeof("#node_ptr") != _cr_ipc_dll_node *"); \
+ assert(node_ptr); \
+ static_assert(offsetof(node_typ, _cr_ipc_dll_node) == 0); \
+ ((node_typ*)(node_ptr)); \
+ })
+
+static inline void _cr_ipc_dll_push_to_rear(_cr_ipc_dll_root *root, _cr_ipc_dll_node *node) {
+ assert(root);
+ assert(node);
+ node->front = root->rear;
+ node->rear = NULL;
+ if (root->rear)
+ root->rear->rear = node;
+ else
+ root->front = node;
+ root->rear = node;
+}
+
+static inline void _cr_ipc_dll_remove(_cr_ipc_dll_root *root, _cr_ipc_dll_node *node) {
+ assert(root);
+ assert(node);
+ if (node->front)
+ node->front->rear = node->rear;
+ else
+ root->front = node->rear;
+ if (node->rear)
+ node->rear->front = node->front;
+ else
+ root->rear = node->front;
+}
-#define _cr_ipc_dll_push_to_rear(root, node) do { \
- assert(root); \
- assert(node); \
- (node)->front = (root)->rear; \
- (node)->rear = NULL; \
- if ((root)->rear) \
- (root)->rear->rear = node; \
- else \
- (root)->front = node; \
- (root)->rear = node; \
- } while(0)
-
-#define _cr_ipc_dll_remove(root, node) do { \
- assert(root); \
- assert(node); \
- if ((node)->front) \
- (node)->front->rear = (node)->rear; \
- else \
- (root)->front = (node)->rear; \
- if ((node)->rear) \
- (node)->rear->front = (node)->front; \
- else \
- (root)->rear = (node)->front; \
- } while (0)
-
-#define _cr_ipc_dll_pop_from_front(root) do { \
- assert(root); \
- assert((root)->front); \
- _cr_ipc_dll_remove(root, (root)->front); \
- } while(0)
+static inline void _cr_ipc_dll_pop_from_front(_cr_ipc_dll_root *root) {
+ assert(root);
+ assert(root->front);
+ _cr_ipc_dll_remove(root, root->front);
+}
#endif /* _LIBCR_IPC__LINKEDLIST_H_ */
diff --git a/libcr_ipc/include/libcr_ipc/chan.h b/libcr_ipc/include/libcr_ipc/chan.h
index 53e68dd..3c4095c 100644
--- a/libcr_ipc/include/libcr_ipc/chan.h
+++ b/libcr_ipc/include/libcr_ipc/chan.h
@@ -105,7 +105,7 @@ enum _cr_chan_waiter_typ {
};
struct _cr_chan_waiter {
- struct _cr_chan_waiter *front, *rear;
+ _cr_ipc_dll_node;
cid_t cid;
void *val_ptr;
void (*dequeue)(void *, size_t);
@@ -115,9 +115,7 @@ struct _cr_chan_waiter {
struct _cr_chan {
enum _cr_chan_waiter_typ waiter_typ;
- struct {
- struct _cr_chan_waiter *front, *rear;
- } waiters;
+ _cr_ipc_dll_root waiters;
};
static void _cr_chan_dequeue(void *_ch, size_t) {
@@ -131,13 +129,14 @@ static inline void _cr_chan_xfer(enum _cr_chan_waiter_typ self_typ, struct _cr_c
if (ch->waiters.front && ch->waiter_typ != self_typ) { /* non-blocking fast-path */
/* Copy. */
+ struct _cr_chan_waiter *front = _cr_ipc_dll_node_cast(struct _cr_chan_waiter, ch->waiters.front);
if (self_typ == _CR_CHAN_SENDER)
- memcpy(ch->waiters.front->val_ptr, val_ptr, val_size);
+ memcpy(front->val_ptr, val_ptr, val_size);
else
- memcpy(val_ptr, ch->waiters.front->val_ptr, val_size);
- cr_unpause(ch->waiters.front->cid);
- ch->waiters.front->dequeue(ch->waiters.front->dequeue_arg1,
- ch->waiters.front->dequeue_arg2);
+ memcpy(val_ptr, front->val_ptr, val_size);
+ cr_unpause(front->cid);
+ front->dequeue(front->dequeue_arg1,
+ front->dequeue_arg2);
cr_yield();
} else { /* blocking slow-path */
struct _cr_chan_waiter self = {
diff --git a/libcr_ipc/include/libcr_ipc/mutex.h b/libcr_ipc/include/libcr_ipc/mutex.h
index 579f7d5..eee4f01 100644
--- a/libcr_ipc/include/libcr_ipc/mutex.h
+++ b/libcr_ipc/include/libcr_ipc/mutex.h
@@ -14,7 +14,7 @@
#include <libcr_ipc/_linkedlist.h>
struct _cr_mutex_waiter {
- struct _cr_mutex_waiter *rear;
+ _cr_ipc_sll_node;
cid_t cid;
};
@@ -28,9 +28,7 @@ struct _cr_mutex_waiter {
*/
typedef struct {
bool locked;
- struct {
- struct _cr_mutex_waiter *front, *rear;
- } waiters;
+ _cr_ipc_sll_root waiters;
} cr_mutex_t;
/**
@@ -68,7 +66,7 @@ static inline void cr_mutex_unlock(cr_mutex_t *mu) {
assert(mu->locked);
if (mu->waiters.front) {
- cr_unpause(mu->waiters.front->cid);
+ cr_unpause(_cr_ipc_sll_node_cast(struct _cr_mutex_waiter, mu->waiters.front)->cid);
_cr_ipc_sll_pop_from_front(&mu->waiters);
} else
mu->locked = false;
diff --git a/libcr_ipc/include/libcr_ipc/rpc.h b/libcr_ipc/include/libcr_ipc/rpc.h
index 382105a..0d47514 100644
--- a/libcr_ipc/include/libcr_ipc/rpc.h
+++ b/libcr_ipc/include/libcr_ipc/rpc.h
@@ -95,24 +95,20 @@
} NAME##_req_t; \
\
struct _##NAME##_waiting_req { \
- struct _##NAME##_waiting_req *rear; \
+ _cr_ipc_sll_node; \
REQ_T *req; \
RESP_T *resp; \
cid_t cid; \
}; \
\
struct _##NAME##_waiting_resp { \
- struct _##NAME##_waiting_resp *rear; \
+ _cr_ipc_sll_node; \
cid_t cid; \
}; \
\
typedef struct { \
- struct { \
- struct _##NAME##_waiting_req *front, *rear; \
- } waiting_reqs; \
- struct { \
- struct _##NAME##_waiting_resp *front, *rear; \
- } waiting_resps; \
+ _cr_ipc_sll_root waiting_reqs; \
+ _cr_ipc_sll_root waiting_resps; \
} NAME##_t; \
\
static inline RESP_T NAME##_send_req(NAME##_t *ch, REQ_T req) { \
@@ -124,7 +120,7 @@
}; \
_cr_ipc_sll_push_to_rear(&ch->waiting_reqs, &self); \
if (ch->waiting_resps.front) \
- cr_unpause(ch->waiting_resps.front->cid); \
+ cr_unpause(_cr_ipc_sll_node_cast(struct _##NAME##_waiting_resp, ch->waiting_resps.front)->cid); \
cr_pause_and_yield(); \
return resp; \
} \
@@ -138,10 +134,12 @@
cr_pause_and_yield(); \
} \
assert(ch->waiting_reqs.front); \
+ struct _##NAME##_waiting_req *front_req = \
+ _cr_ipc_sll_node_cast(struct _##NAME##_waiting_req, ch->waiting_reqs.front); \
NAME##_req_t ret = { \
- .req = *(ch->waiting_reqs.front->req), \
- ._resp = ch->waiting_reqs.front->resp, \
- ._requester = ch->waiting_reqs.front->cid, \
+ .req = *(front_req->req), \
+ ._resp = front_req->resp, \
+ ._requester = front_req->cid, \
}; \
_cr_ipc_sll_pop_from_front(&ch->waiting_reqs); \
return ret; \
diff --git a/libcr_ipc/include/libcr_ipc/sema.h b/libcr_ipc/include/libcr_ipc/sema.h
index 0895a22..157c196 100644
--- a/libcr_ipc/include/libcr_ipc/sema.h
+++ b/libcr_ipc/include/libcr_ipc/sema.h
@@ -12,7 +12,7 @@
#include <libcr_ipc/_linkedlist.h>
struct _cr_sema_waiter {
- struct _cr_sema_waiter *rear;
+ _cr_ipc_sll_node;
cid_t cid;
};
@@ -23,9 +23,7 @@ struct _cr_sema_waiter {
*/
typedef struct {
unsigned int cnt;
- struct {
- struct _cr_sema_waiter *front, *rear;
- } waiters;
+ _cr_ipc_sll_root waiters;
} cr_sema_t;
/**
@@ -42,7 +40,8 @@ static inline void cr_sema_signal(cr_sema_t *sema) {
sema->cnt++;
if (sema->waiters.front) {
sema->cnt--;
- cr_unpause(sema->waiters.front->cid);
+ cr_unpause(
+ _cr_ipc_sll_node_cast(struct _cr_sema_waiter, sema->waiters.front)->cid);
_cr_ipc_sll_pop_from_front(&sema->waiters);
}
cr_restore_interrupts(saved);
@@ -59,7 +58,8 @@ static inline void cr_sema_signal_from_intrhandler(cr_sema_t *sema) {
sema->cnt++;
if (sema->waiters.front) {
sema->cnt--;
- cr_unpause_from_intrhandler(sema->waiters.front->cid);
+ cr_unpause_from_intrhandler(
+ _cr_ipc_sll_node_cast(struct _cr_sema_waiter, sema->waiters.front)->cid);
_cr_ipc_sll_pop_from_front(&sema->waiters);
}
}