X-Git-Url: https://git.liburcu.org/?a=blobdiff_plain;f=urcu%2Fstatic%2Fwfcqueue.h;h=b2ad7ab6957699d36ca3100737b8086683b4165b;hb=13652c4b7e2dd74e8b206c8f724f064fe45e2c8a;hp=48b2625dd3a4d0b28450dac4d7d0f7df921028c7;hpb=bf02499bae889e418cfda14a0bab9f65c72410bb;p=urcu.git diff --git a/urcu/static/wfcqueue.h b/urcu/static/wfcqueue.h index 48b2625..b2ad7ab 100644 --- a/urcu/static/wfcqueue.h +++ b/urcu/static/wfcqueue.h @@ -367,7 +367,8 @@ static inline struct cds_wfcq_node * ___cds_wfcq_dequeue_with_state(cds_wfcq_head_ptr_t u_head, struct cds_wfcq_tail *tail, int *state, - int blocking) + int blocking, + int safe) { struct __cds_wfcq_head *head = u_head._h; struct cds_wfcq_node *node, *next; @@ -385,6 +386,8 @@ ___cds_wfcq_dequeue_with_state(cds_wfcq_head_ptr_t u_head, } if ((next = CMM_LOAD_SHARED(node->next)) == NULL) { + struct cds_wfcq_node *ret_node; + /* * @node is probably the only node in the queue. * Try to move the tail to &q->head. @@ -400,7 +403,15 @@ ___cds_wfcq_dequeue_with_state(cds_wfcq_head_ptr_t u_head, * content. */ _cds_wfcq_node_init(&head->node); - if (uatomic_cmpxchg(&tail->p, node, &head->node) == node) { + if (safe) { + ret_node = uatomic_cmpxchg(&tail->p, node, + &head->node); + } else { + ret_node = tail->p; + if (ret_node == node) + tail->p = &head->node; + } + if (ret_node == node) { if (state) *state |= CDS_WFCQ_STATE_LAST; return node; @@ -440,7 +451,7 @@ static inline struct cds_wfcq_node * ___cds_wfcq_dequeue_with_state_blocking(cds_wfcq_head_ptr_t head, struct cds_wfcq_tail *tail, int *state) { - return ___cds_wfcq_dequeue_with_state(head, tail, state, 1); + return ___cds_wfcq_dequeue_with_state(head, tail, state, 1, 1); } /* @@ -466,7 +477,7 @@ static inline struct cds_wfcq_node * ___cds_wfcq_dequeue_with_state_nonblocking(cds_wfcq_head_ptr_t head, struct cds_wfcq_tail *tail, int *state) { - return ___cds_wfcq_dequeue_with_state(head, tail, state, 0); + return ___cds_wfcq_dequeue_with_state(head, tail, state, 0, 1); } /*