- for (;;) {
- struct rcu_lfq_node *tail, *next;
-
- rcu_read_lock();
- tail = rcu_dereference(q->tail);
- /*
- * Typically expect tail->next to be NULL.
- */
- next = uatomic_cmpxchg(&tail->next, NULL, node);
- if (next == NULL) {
- /*
- * Tail was at the end of queue, we successfully
- * appended to it.
- * Now move tail (another enqueue might beat
- * us to it, that's fine).
- */
- uatomic_cmpxchg(&q->tail, tail, node);
- rcu_read_unlock();
- return;
- } else {
- /*
- * Failure to append to current tail. Help moving tail
- * further and retry.
- */
- uatomic_cmpxchg(&q->tail, tail, next);
- rcu_read_unlock();
- continue;
- }
- }
-}
+extern void rcu_lfq_node_init(struct rcu_lfq_node *node);
+extern void rcu_lfq_init(struct rcu_lfq_queue *q);
+extern void rcu_lfq_enqueue(struct rcu_lfq_queue *q, struct rcu_lfq_node *node);