diff options
author | Luke T. Shumaker <lukeshu@lukeshu.com> | 2024-11-25 14:39:33 -0700 |
---|---|---|
committer | Luke T. Shumaker <lukeshu@lukeshu.com> | 2024-11-25 14:40:06 -0700 |
commit | 9aad7d02fedca1e265c5433060e57c8f9b6e3b01 (patch) | |
tree | c5ba11faf17839322ad3c95915e18925f4741c61 /libcr_ipc | |
parent | cce21287a154dea92ae9005aebe8c0b650faa173 (diff) |
libcr_ipc: _linkedlist.h: Use inline functions, not macros
Diffstat (limited to 'libcr_ipc')
-rw-r--r-- | libcr_ipc/include/libcr_ipc/_linkedlist.h | 168 | ||||
-rw-r--r-- | libcr_ipc/include/libcr_ipc/chan.h | 17 | ||||
-rw-r--r-- | libcr_ipc/include/libcr_ipc/mutex.h | 8 | ||||
-rw-r--r-- | libcr_ipc/include/libcr_ipc/rpc.h | 22 | ||||
-rw-r--r-- | libcr_ipc/include/libcr_ipc/sema.h | 12 |
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); } } |