X-Git-Url: https://git.liburcu.org/?a=blobdiff_plain;f=urcu%2Frculfqueue.h;h=b712998c07a929cfa5d49da370bd0c676c72ecdb;hb=05dd4b94f48c1717c18e0dcee88830394a5f171c;hp=f9b14fe93657343c5e1917ab77afcab4dc087a0d;hpb=453629a9317adef5b96c3d55e4dcd98db680997a;p=urcu.git diff --git a/urcu/rculfqueue.h b/urcu/rculfqueue.h index f9b14fe..b712998 100644 --- a/urcu/rculfqueue.h +++ b/urcu/rculfqueue.h @@ -1,3 +1,6 @@ +#ifndef _URCU_RCULFQUEUE_H +#define _URCU_RCULFQUEUE_H + /* * rculfqueue.h * @@ -72,13 +75,13 @@ void rcu_lfq_enqueue(struct rcu_lfq_queue *q, struct rcu_lfq_node *node) * node before publication. */ - rcu_read_lock(); for (;;) { - struct rcu_lfq_node *tail = rcu_dereference(q->tail); - struct rcu_lfq_node *next; + struct rcu_lfq_node *tail, *next; + rcu_read_lock(); + tail = rcu_dereference(q->tail); /* - * Typically expect tail to be NULL. + * Typically expect tail->next to be NULL. */ next = uatomic_cmpxchg(&tail->next, NULL, node); if (next == NULL) { @@ -97,6 +100,7 @@ void rcu_lfq_enqueue(struct rcu_lfq_queue *q, struct rcu_lfq_node *node) * further and retry. */ uatomic_cmpxchg(&q->tail, tail, next); + rcu_read_unlock(); continue; } } @@ -107,17 +111,19 @@ void rcu_lfq_enqueue(struct rcu_lfq_queue *q, struct rcu_lfq_node *node) * which calls the release primitive when the reference count drops to zero. A * grace period must be waited before performing the actual memory reclamation * in the release primitive. - * The entry lfq node returned by dequeue must no be re-used before the - * reference count reaches zero. + * The entry lfq node returned by dequeue must not be modified/re-used/freed + * until the reference count reaches zero and a grace period has elapsed (after + * the refcount reached 0). */ struct rcu_lfq_node * rcu_lfq_dequeue(struct rcu_lfq_queue *q, void (*release)(struct urcu_ref *)) { - rcu_read_lock(); for (;;) { - struct rcu_lfq_node *head = rcu_dereference(q->head); - struct rcu_lfq_node *next = rcu_dereference(head->next); + struct rcu_lfq_node *head, *next; + rcu_read_lock(); + head = rcu_dereference(q->head); + next = rcu_dereference(head->next); if (next) { if (uatomic_cmpxchg(&q->head, head, next) == head) { rcu_read_unlock(); @@ -125,6 +131,7 @@ rcu_lfq_dequeue(struct rcu_lfq_queue *q, void (*release)(struct urcu_ref *)) return next; } else { /* Concurrently pushed, retry */ + rcu_read_unlock(); continue; } } else { @@ -134,3 +141,5 @@ rcu_lfq_dequeue(struct rcu_lfq_queue *q, void (*release)(struct urcu_ref *)) } } } + +#endif /* _URCU_RCULFQUEUE_H */