uatomic/x86: Remove redundant memory barriers
[urcu.git] / doc / examples / rculfqueue / cds_lfq_dequeue.c
1 // SPDX-FileCopyrightText: 2013 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
2 //
3 // SPDX-License-Identifier: MIT
4
5 /*
6 * This example shows how to dequeue nodes from a RCU lock-free queue.
7 * This queue requires using a RCU scheme.
8 */
9
10 #include <stdio.h>
11 #include <stdlib.h>
12
13 #include <urcu/urcu-memb.h> /* RCU flavor */
14 #include <urcu/rculfqueue.h> /* RCU Lock-free queue */
15 #include <urcu/compiler.h> /* For CAA_ARRAY_SIZE */
16
17 /*
18 * Nodes populated into the queue.
19 */
20 struct mynode {
21 int value; /* Node content */
22 struct cds_lfq_node_rcu node; /* Chaining in queue */
23 struct rcu_head rcu_head; /* For call_rcu() */
24 };
25
26 static
27 void free_node(struct rcu_head *head)
28 {
29 struct mynode *node =
30 caa_container_of(head, struct mynode, rcu_head);
31
32 free(node);
33 }
34
35 int main(void)
36 {
37 int values[] = { -5, 42, 36, 24, };
38 struct cds_lfq_queue_rcu myqueue; /* Queue */
39 unsigned int i;
40 int ret = 0;
41
42 /*
43 * Each thread need using RCU read-side need to be explicitly
44 * registered.
45 */
46 urcu_memb_register_thread();
47
48 cds_lfq_init_rcu(&myqueue, urcu_memb_call_rcu);
49
50 /*
51 * Enqueue nodes.
52 */
53 for (i = 0; i < CAA_ARRAY_SIZE(values); i++) {
54 struct mynode *node;
55
56 node = malloc(sizeof(*node));
57 if (!node) {
58 ret = -1;
59 goto end;
60 }
61
62 cds_lfq_node_init_rcu(&node->node);
63 node->value = values[i];
64 /*
65 * Both enqueue and dequeue need to be called within RCU
66 * read-side critical section.
67 */
68 urcu_memb_read_lock();
69 cds_lfq_enqueue_rcu(&myqueue, &node->node);
70 urcu_memb_read_unlock();
71 }
72
73 /*
74 * Dequeue each node from the queue. Those will be dequeued from
75 * the oldest (first enqueued) to the newest (last enqueued).
76 */
77 printf("dequeued content:");
78 for (;;) {
79 struct cds_lfq_node_rcu *qnode;
80 struct mynode *node;
81
82 /*
83 * Both enqueue and dequeue need to be called within RCU
84 * read-side critical section.
85 */
86 urcu_memb_read_lock();
87 qnode = cds_lfq_dequeue_rcu(&myqueue);
88 urcu_memb_read_unlock();
89 if (!qnode) {
90 break; /* Queue is empty. */
91 }
92 /* Getting the container structure from the node */
93 node = caa_container_of(qnode, struct mynode, node);
94 printf(" %d", node->value);
95 urcu_memb_call_rcu(&node->rcu_head, free_node);
96 }
97 printf("\n");
98 /*
99 * Release memory used by the queue.
100 */
101 ret = cds_lfq_destroy_rcu(&myqueue);
102 if (ret) {
103 printf("Error destroying queue (non-empty)\n");
104 }
105 end:
106 urcu_memb_unregister_thread();
107 return ret;
108 }
This page took 0.03093 seconds and 4 git commands to generate.