4 * Userspace RCU library - double-ended queue unit test
6 * Copyright 2013 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #include <urcu/rcudq.h>
25 #include <urcu/compiler.h>
30 #define err_printf(fmt, args...) \
31 fprintf(stderr, "[error in %s@%d:%s()] " fmt, __FILE__, __LINE__, __func__, ## args)
36 struct cds_rcudq_head node
;
37 struct rcu_head rcu_head
;
40 static CDS_RCUDQ_HEAD(dq
);
43 struct myobj
*create_obj(int a
, int b
)
47 obj
= malloc(sizeof(*obj
));
52 CDS_INIT_RCUDQ_HEAD(&obj
->node
);
57 void poison_head(struct cds_rcudq_head
*head
)
59 memset(head
, 42, sizeof(*head
));
63 void print_obj(struct myobj
*obj
)
65 printf("(%d, %d) ", obj
->a
, obj
->b
);
69 void free_obj(struct rcu_head
*rcu_head
)
71 struct myobj
*obj
= caa_container_of(rcu_head
, struct myobj
, rcu_head
);
76 int main(int argc
, char **argv
)
78 struct myobj
*obj
, *tmp
;
79 struct cds_rcudq_head
*pos
, *p
;
82 rcu_register_thread();
84 if (!cds_rcudq_empty(&dq
)) {
85 err_printf("Queue is not empty as expected\n");
90 CDS_INIT_RCUDQ_HEAD(&dq
);
91 if (!cds_rcudq_empty(&dq
)) {
92 err_printf("Queue is not empty as expected\n");
97 for (i
= 0; i
< 4; i
++) {
98 for (j
= 0; j
< 4; j
++) {
99 obj
= create_obj(i
, j
);
103 cds_rcudq_add_tail(&obj
->node
, &dq
);
106 for (i
= 42; i
< 46; i
++) {
107 obj
= create_obj(i
, i
);
111 cds_rcudq_add(&obj
->node
, &dq
);
114 printf("cds_rcudq_first_entry()\n");
115 obj
= cds_rcudq_first_entry(&dq
, struct myobj
, node
);
119 printf("cds_rcudq_for_each()\n");
120 cds_rcudq_for_each(pos
, &dq
) {
121 obj
= cds_rcudq_entry(pos
, struct myobj
, node
);
126 printf("cds_rcudq_for_each_safe()\n");
127 cds_rcudq_for_each_safe(pos
, p
, &dq
) {
128 obj
= cds_rcudq_entry(pos
, struct myobj
, node
);
131 printf("(removing) ");
132 cds_rcudq_del(&obj
->node
);
133 call_rcu(&obj
->rcu_head
, free_obj
);
138 printf("cds_rcudq_for_each_entry()\n");
139 cds_rcudq_for_each_entry(obj
, &dq
, node
) {
144 printf("cds_rcudq_for_each_entry_safe()\n");
145 cds_rcudq_for_each_entry_safe(obj
, tmp
, &dq
, node
) {
148 printf("(removing) ");
149 cds_rcudq_del(&obj
->node
);
150 call_rcu(&obj
->rcu_head
, free_obj
);
155 printf("cds_rcudq_for_each_reverse()\n");
156 cds_rcudq_for_each_reverse(pos
, &dq
) {
157 obj
= cds_rcudq_entry(pos
, struct myobj
, node
);
162 printf("cds_rcudq_for_each_reverse_safe()\n");
163 cds_rcudq_for_each_reverse_safe(pos
, p
, &dq
) {
164 obj
= cds_rcudq_entry(pos
, struct myobj
, node
);
167 printf("(removing) ");
168 cds_rcudq_del(&obj
->node
);
169 call_rcu(&obj
->rcu_head
, free_obj
);
174 printf("cds_rcudq_for_each_entry_reverse()\n");
175 cds_rcudq_for_each_entry_reverse(obj
, &dq
, node
) {
180 printf("cds_rcudq_for_each_entry_reverse_safe()\n");
181 cds_rcudq_for_each_entry_reverse_safe(obj
, tmp
, &dq
, node
) {
184 printf("(removing) ");
185 cds_rcudq_del(&obj
->node
);
186 call_rcu(&obj
->rcu_head
, free_obj
);
194 printf("cds_rcudq_for_each_rcu()\n");
195 cds_rcudq_for_each_rcu(pos
, &dq
) {
196 obj
= cds_rcudq_entry(pos
, struct myobj
, node
);
201 printf("cds_rcudq_for_each_entry_rcu()\n");
202 cds_rcudq_for_each_entry_rcu(obj
, &dq
, node
) {
207 printf("cds_rcudq_for_each_reverse_rcu()\n");
208 cds_rcudq_for_each_reverse_rcu(pos
, &dq
) {
209 obj
= cds_rcudq_entry(pos
, struct myobj
, node
);
214 printf("cds_rcudq_for_each_entry_reverse_rcu()\n");
215 cds_rcudq_for_each_entry_reverse_rcu(obj
, &dq
, node
) {
222 cds_rcudq_for_each_entry_safe(obj
, tmp
, &dq
, node
) {
223 cds_rcudq_del(&obj
->node
);
224 call_rcu(&obj
->rcu_head
, free_obj
);
227 if (!cds_rcudq_empty(&dq
)) {
228 err_printf("Queue is not empty as expected\n");
232 /* Free memory (in flight call_rcu callback execution) before exiting */
235 rcu_unregister_thread();
This page took 0.042458 seconds and 5 git commands to generate.