From c07754115fc26ba7157c70e013b2e3c73236c657 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Wed, 12 Jun 2024 16:36:54 -0400 Subject: [PATCH] wfcqueue: make cds_wfcq_empty arguments const cds_wfcq_empty does not modify its arguments. Hence, they can be marked as `const`. Signed-off-by: Mathieu Desnoyers Change-Id: I0b14acf21ca0a59bbdda4eb701b83a66e8837d57 --- include/urcu/static/wfcqueue.h | 12 +++---- include/urcu/wfcqueue.h | 65 +++++++++++++++++++++++++++++++--- src/wfcqueue.c | 4 +-- 3 files changed, 69 insertions(+), 12 deletions(-) diff --git a/include/urcu/static/wfcqueue.h b/include/urcu/static/wfcqueue.h index 26741ae..2799c61 100644 --- a/include/urcu/static/wfcqueue.h +++ b/include/urcu/static/wfcqueue.h @@ -133,10 +133,10 @@ static inline void ___cds_wfcq_init(struct __cds_wfcq_head *head, * make a queue appear empty if an enqueuer is preempted for a long time * between xchg() and setting the previous node's next pointer. */ -static inline bool _cds_wfcq_empty(cds_wfcq_head_ptr_t u_head, - struct cds_wfcq_tail *tail) +static inline bool _cds_wfcq_empty(cds_wfcq_head_const_ptr_t u_head, + const struct cds_wfcq_tail *tail) { - struct __cds_wfcq_head *head = u_head._h; + const struct __cds_wfcq_head *head = u_head._h; /* * Queue is empty if no node is pointed by head->node.next nor * tail->p. Even though the tail->p check is sufficient to find @@ -283,7 +283,7 @@ ___cds_wfcq_first(cds_wfcq_head_ptr_t u_head, struct __cds_wfcq_head *head = u_head._h; struct cds_wfcq_node *node; - if (_cds_wfcq_empty(__cds_wfcq_head_cast(head), tail)) + if (_cds_wfcq_empty(__cds_wfcq_head_const_cast(head), tail)) return NULL; node = ___cds_wfcq_node_sync_next(&head->node, blocking); @@ -399,7 +399,7 @@ ___cds_wfcq_dequeue_with_state(cds_wfcq_head_ptr_t u_head, if (state) *state = 0; - if (_cds_wfcq_empty(__cds_wfcq_head_cast(head), tail)) { + if (_cds_wfcq_empty(__cds_wfcq_head_const_cast(head), tail)) { return NULL; } @@ -530,7 +530,7 @@ ___cds_wfcq_splice( * Initial emptiness check to speed up cases where queue is * empty: only require loads to check if queue is empty. */ - if (_cds_wfcq_empty(__cds_wfcq_head_cast(src_q_head), src_q_tail)) + if (_cds_wfcq_empty(__cds_wfcq_head_const_cast(src_q_head), src_q_tail)) return CDS_WFCQ_RET_SRC_EMPTY; for (;;) { diff --git a/include/urcu/wfcqueue.h b/include/urcu/wfcqueue.h index bba5c55..5a4add4 100644 --- a/include/urcu/wfcqueue.h +++ b/include/urcu/wfcqueue.h @@ -78,6 +78,11 @@ typedef union { struct __cds_wfcq_head *_h; struct cds_wfcq_head *h; } __attribute__((__transparent_union__)) cds_wfcq_head_ptr_t; + +typedef union { + const struct __cds_wfcq_head *_h; + const struct cds_wfcq_head *h; +} __attribute__((__transparent_union__)) cds_wfcq_head_const_ptr_t; #if defined(__clang__) #pragma clang diagnostic pop #endif @@ -100,6 +105,25 @@ static inline struct cds_wfcq_head *cds_wfcq_head_cast(struct cds_wfcq_head *hea { return head; } + +/* + * This static inline is only present for compatibility with C++. It is + * effect-less in C. + */ +static inline const struct __cds_wfcq_head *__cds_wfcq_head_const_cast(const struct __cds_wfcq_head *head) +{ + return head; +} + +/* + * This static inline is only present for compatibility with C++. It is + * effect-less in C. + */ +static inline const struct cds_wfcq_head *cds_wfcq_head_const_cast(const struct cds_wfcq_head *head) +{ + return head; +} + #else /* #ifndef __cplusplus */ /* @@ -121,6 +145,27 @@ static inline cds_wfcq_head_ptr_t cds_wfcq_head_cast(struct cds_wfcq_head *head) cds_wfcq_head_ptr_t ret = { .h = head }; return ret; } + +/* + * This static inline is used by internally in the static inline + * implementation of the API. + */ +static inline cds_wfcq_head_const_ptr_t __cds_wfcq_head_const_cast(const struct __cds_wfcq_head *head) +{ + cds_wfcq_head_const_ptr_t ret = { ._h = head }; + return ret; +} + +/* + * This static inline is used by internally in the static inline + * implementation of the API. + */ +static inline cds_wfcq_head_const_ptr_t cds_wfcq_head_const_cast(const struct cds_wfcq_head *head) +{ + cds_wfcq_head_const_ptr_t ret = { .h = head }; + return ret; +} + #endif /* #else #ifndef __cplusplus */ struct cds_wfcq_tail { @@ -238,8 +283,8 @@ extern void __cds_wfcq_init(struct __cds_wfcq_head *head, * * No memory barrier is issued. No mutual exclusion is required. */ -extern bool cds_wfcq_empty(cds_wfcq_head_ptr_t head, - struct cds_wfcq_tail *tail); +extern bool cds_wfcq_empty(cds_wfcq_head_const_ptr_t head, + const struct cds_wfcq_tail *tail); /* * cds_wfcq_dequeue_lock: take the dequeue mutual exclusion lock. @@ -500,10 +545,22 @@ static inline cds_wfcq_head_ptr_t cds_wfcq_head_cast_cpp(struct cds_wfcq_head *h return ret; } +static inline cds_wfcq_head_const_ptr_t cds_wfcq_head_const_cast_cpp(const struct __cds_wfcq_head *head) +{ + cds_wfcq_head_const_ptr_t ret = { ._h = head }; + return ret; +} + +static inline cds_wfcq_head_const_ptr_t cds_wfcq_head_const_cast_cpp(const struct cds_wfcq_head *head) +{ + cds_wfcq_head_const_ptr_t ret = { .h = head }; + return ret; +} + template static inline bool cds_wfcq_empty(T head, - struct cds_wfcq_tail *tail) + const struct cds_wfcq_tail *tail) { - return cds_wfcq_empty(cds_wfcq_head_cast_cpp(head), tail); + return cds_wfcq_empty(cds_wfcq_head_const_cast_cpp(head), tail); } template static inline bool cds_wfcq_enqueue(T head, diff --git a/src/wfcqueue.c b/src/wfcqueue.c index ff05510..294b266 100644 --- a/src/wfcqueue.c +++ b/src/wfcqueue.c @@ -38,8 +38,8 @@ void __cds_wfcq_init(struct __cds_wfcq_head *head, ___cds_wfcq_init(head, tail); } -bool cds_wfcq_empty(cds_wfcq_head_ptr_t head, - struct cds_wfcq_tail *tail) +bool cds_wfcq_empty(cds_wfcq_head_const_ptr_t head, + const struct cds_wfcq_tail *tail) { return _cds_wfcq_empty(head, tail); -- 2.34.1