X-Git-Url: https://git.liburcu.org/?a=blobdiff_plain;f=urcu%2Fwfcqueue.h;h=7e363ea8b526c2fcab8f03cee670bb8ac3052dcf;hb=93aee570e96c48843659caa12667ff7157734532;hp=d9ec5349d7be203da7f80f6e6c0de5cda96e20e9;hpb=f878b49ebb78010f4f9466d3512a7e88787812b2;p=urcu.git diff --git a/urcu/wfcqueue.h b/urcu/wfcqueue.h index d9ec534..7e363ea 100644 --- a/urcu/wfcqueue.h +++ b/urcu/wfcqueue.h @@ -52,6 +52,10 @@ enum cds_wfcq_ret { CDS_WFCQ_RET_SRC_EMPTY = 2, }; +enum cds_wfcq_state { + CDS_WFCQ_STATE_LAST = (1U << 0), +}; + struct cds_wfcq_node { struct cds_wfcq_node *next; }; @@ -76,6 +80,7 @@ struct cds_wfcq_tail { #define cds_wfcq_node_init _cds_wfcq_node_init #define cds_wfcq_init _cds_wfcq_init +#define cds_wfcq_destroy _cds_wfcq_destroy #define cds_wfcq_empty _cds_wfcq_empty #define cds_wfcq_enqueue _cds_wfcq_enqueue @@ -85,12 +90,16 @@ struct cds_wfcq_tail { /* Locking performed within cds_wfcq calls. */ #define cds_wfcq_dequeue_blocking _cds_wfcq_dequeue_blocking +#define cds_wfcq_dequeue_with_state_blocking \ + _cds_wfcq_dequeue_with_state_blocking #define cds_wfcq_splice_blocking _cds_wfcq_splice_blocking #define cds_wfcq_first_blocking _cds_wfcq_first_blocking #define cds_wfcq_next_blocking _cds_wfcq_next_blocking /* Locking ensured by caller by holding cds_wfcq_dequeue_lock() */ #define __cds_wfcq_dequeue_blocking ___cds_wfcq_dequeue_blocking +#define __cds_wfcq_dequeue_with_state_blocking \ + ___cds_wfcq_dequeue_with_state_blocking #define __cds_wfcq_splice_blocking ___cds_wfcq_splice_blocking #define __cds_wfcq_first_blocking ___cds_wfcq_first_blocking #define __cds_wfcq_next_blocking ___cds_wfcq_next_blocking @@ -101,6 +110,8 @@ struct cds_wfcq_tail { * need to block. splice returns nonzero if it needs to block. */ #define __cds_wfcq_dequeue_nonblocking ___cds_wfcq_dequeue_nonblocking +#define __cds_wfcq_dequeue_with_state_nonblocking \ + ___cds_wfcq_dequeue_with_state_nonblocking #define __cds_wfcq_splice_nonblocking ___cds_wfcq_splice_nonblocking #define __cds_wfcq_first_nonblocking ___cds_wfcq_first_nonblocking #define __cds_wfcq_next_nonblocking ___cds_wfcq_next_nonblocking @@ -148,11 +159,19 @@ struct cds_wfcq_tail { extern void cds_wfcq_node_init(struct cds_wfcq_node *node); /* - * cds_wfcq_init: initialize wait-free queue. + * cds_wfcq_init: initialize wait-free queue. Pair with + * cds_wfcq_destroy(). */ extern void cds_wfcq_init(struct cds_wfcq_head *head, struct cds_wfcq_tail *tail); +/* + * cds_wfcq_destroy: destroy wait-free queue. Pair with + * cds_wfcq_init(). + */ +extern void cds_wfcq_destroy(struct cds_wfcq_head *head, + struct cds_wfcq_tail *tail); + /* * cds_wfcq_empty: return whether wait-free queue is empty. * @@ -192,13 +211,24 @@ extern bool cds_wfcq_enqueue(struct cds_wfcq_head *head, * Content written into the node before enqueue is guaranteed to be * consistent, but no other memory ordering is ensured. * It is valid to reuse and free a dequeued node immediately. - * Mutual exlusion with cds_wfcq_dequeue_blocking and dequeue lock is + * Mutual exclusion with cds_wfcq_dequeue_blocking and dequeue lock is * ensured. */ extern struct cds_wfcq_node *cds_wfcq_dequeue_blocking( struct cds_wfcq_head *head, struct cds_wfcq_tail *tail); +/* + * cds_wfcq_dequeue_with_state_blocking: dequeue with state. + * + * Same as cds_wfcq_dequeue_blocking, but saves whether dequeueing the + * last node of the queue into state (CDS_WFCQ_STATE_LAST). + */ +extern struct cds_wfcq_node *cds_wfcq_dequeue_with_state_blocking( + struct cds_wfcq_head *head, + struct cds_wfcq_tail *tail, + int *state); + /* * cds_wfcq_splice_blocking: enqueue all src_q nodes at the end of dest_q. * @@ -206,7 +236,7 @@ extern struct cds_wfcq_node *cds_wfcq_dequeue_blocking( * dest_q must be already initialized. * Content written into the node before enqueue is guaranteed to be * consistent, but no other memory ordering is ensured. - * Mutual exlusion with cds_wfcq_dequeue_blocking and dequeue lock is + * Mutual exclusion with cds_wfcq_dequeue_blocking and dequeue lock is * ensured. * * Returns enum cds_wfcq_ret which indicates the state of the src or @@ -231,6 +261,17 @@ extern struct cds_wfcq_node *__cds_wfcq_dequeue_blocking( struct cds_wfcq_head *head, struct cds_wfcq_tail *tail); +/* + * __cds_wfcq_dequeue_with_state_blocking: dequeue with state. + * + * Same as __cds_wfcq_dequeue_blocking, but saves whether dequeueing the + * last node of the queue into state (CDS_WFCQ_STATE_LAST). + */ +extern struct cds_wfcq_node *__cds_wfcq_dequeue_with_state_blocking( + struct cds_wfcq_head *head, + struct cds_wfcq_tail *tail, + int *state); + /* * __cds_wfcq_dequeue_nonblocking: dequeue a node from a wait-free queue. * @@ -241,6 +282,17 @@ extern struct cds_wfcq_node *__cds_wfcq_dequeue_nonblocking( struct cds_wfcq_head *head, struct cds_wfcq_tail *tail); +/* + * __cds_wfcq_dequeue_with_state_blocking: dequeue with state. + * + * Same as __cds_wfcq_dequeue_nonblocking, but saves whether dequeueing + * the last node of the queue into state (CDS_WFCQ_STATE_LAST). + */ +extern struct cds_wfcq_node *__cds_wfcq_dequeue_with_state_nonblocking( + struct cds_wfcq_head *head, + struct cds_wfcq_tail *tail, + int *state); + /* * __cds_wfcq_splice_blocking: enqueue all src_q nodes at the end of dest_q. * @@ -280,6 +332,8 @@ extern enum cds_wfcq_ret __cds_wfcq_splice_nonblocking( * Used by for-like iteration macros: * __cds_wfcq_for_each_blocking() * __cds_wfcq_for_each_blocking_safe() + * + * Returns NULL if queue is empty, first node otherwise. */ extern struct cds_wfcq_node *__cds_wfcq_first_blocking( struct cds_wfcq_head *head, @@ -306,6 +360,9 @@ extern struct cds_wfcq_node *__cds_wfcq_first_nonblocking( * Used by for-like iteration macros: * __cds_wfcq_for_each_blocking() * __cds_wfcq_for_each_blocking_safe() + * + * Returns NULL if reached end of queue, non-NULL next queue node + * otherwise. */ extern struct cds_wfcq_node *__cds_wfcq_next_blocking( struct cds_wfcq_head *head,