2 * Copyright (C) 2013 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
4 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
5 * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
7 * Permission is hereby granted to use or copy this program for any
8 * purpose, provided the above notices are retained on all copies.
9 * Permission to modify the code and to distribute modified code is
10 * granted, provided the above notices are retained, and a notice that
11 * the code was modified is included with the above copyright notice.
13 * This example shows how to dequeue nodes from a RCU lock-free queue.
14 * This queue requires using a RCU scheme.
20 #include <urcu.h> /* RCU flavor */
21 #include <urcu/rculfqueue.h> /* RCU Lock-free queue */
22 #include <urcu/compiler.h> /* For CAA_ARRAY_SIZE */
25 * Nodes populated into the queue.
28 int value
; /* Node content */
29 struct cds_lfq_node_rcu node
; /* Chaining in queue */
30 struct rcu_head rcu_head
; /* For call_rcu() */
34 void free_node(struct rcu_head
*head
)
37 caa_container_of(head
, struct mynode
, rcu_head
);
42 int main(int argc
, char **argv
)
44 int values
[] = { -5, 42, 36, 24, };
45 struct cds_lfq_queue_rcu myqueue
; /* Queue */
50 * Each thread need using RCU read-side need to be explicitly
53 rcu_register_thread();
55 cds_lfq_init_rcu(&myqueue
, call_rcu
);
60 for (i
= 0; i
< CAA_ARRAY_SIZE(values
); i
++) {
63 node
= malloc(sizeof(*node
));
69 cds_lfq_node_init_rcu(&node
->node
);
70 node
->value
= values
[i
];
72 * Both enqueue and dequeue need to be called within RCU
73 * read-side critical section.
76 cds_lfq_enqueue_rcu(&myqueue
, &node
->node
);
81 * Dequeue each node from the queue. Those will be dequeued from
82 * the oldest (first enqueued) to the newest (last enqueued).
84 printf("dequeued content:");
86 struct cds_lfq_node_rcu
*qnode
;
90 * Both enqueue and dequeue need to be called within RCU
91 * read-side critical section.
94 qnode
= cds_lfq_dequeue_rcu(&myqueue
);
97 break; /* Queue is empty. */
99 /* Getting the container structure from the node */
100 node
= caa_container_of(qnode
, struct mynode
, node
);
101 printf(" %d", node
->value
);
102 call_rcu(&node
->rcu_head
, free_node
);
106 * Release memory used by the queue.
108 ret
= cds_lfq_destroy_rcu(&myqueue
);
110 printf("Error destroying queue (non-empty)\n");
113 rcu_unregister_thread();