uatomic/x86: Remove redundant memory barriers
[urcu.git] / doc / examples / rculfqueue / cds_lfq_dequeue.c
CommitLineData
1c87adb3
MJ
1// SPDX-FileCopyrightText: 2013 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
2//
3// SPDX-License-Identifier: MIT
4
d4b71408 5/*
d4b71408
MD
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
b9050d91 13#include <urcu/urcu-memb.h> /* RCU flavor */
d4b71408
MD
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 */
20struct 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
26static
27void 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
70469b43 35int main(void)
d4b71408
MD
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 */
b9050d91 46 urcu_memb_register_thread();
d4b71408 47
b9050d91 48 cds_lfq_init_rcu(&myqueue, urcu_memb_call_rcu);
d4b71408
MD
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 */
b9050d91 68 urcu_memb_read_lock();
d4b71408 69 cds_lfq_enqueue_rcu(&myqueue, &node->node);
b9050d91 70 urcu_memb_read_unlock();
d4b71408
MD
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 */
b9050d91 86 urcu_memb_read_lock();
d4b71408 87 qnode = cds_lfq_dequeue_rcu(&myqueue);
b9050d91 88 urcu_memb_read_unlock();
d4b71408
MD
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);
b9050d91 95 urcu_memb_call_rcu(&node->rcu_head, free_node);
d4b71408
MD
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 }
105end:
b9050d91 106 urcu_memb_unregister_thread();
d4b71408
MD
107 return ret;
108}
This page took 0.039867 seconds and 4 git commands to generate.