1*eff3860bSMatthew Wilcox // SPDX-License-Identifier: GPL-2.0
2*eff3860bSMatthew Wilcox #include <linux/kernel.h>
3*eff3860bSMatthew Wilcox #include <linux/gfp.h>
4*eff3860bSMatthew Wilcox #include <linux/slab.h>
5*eff3860bSMatthew Wilcox #include <linux/radix-tree.h>
6*eff3860bSMatthew Wilcox #include <linux/rcupdate.h>
7*eff3860bSMatthew Wilcox #include <stdlib.h>
8*eff3860bSMatthew Wilcox #include <pthread.h>
9*eff3860bSMatthew Wilcox #include <stdio.h>
10*eff3860bSMatthew Wilcox #include <assert.h>
11*eff3860bSMatthew Wilcox
12*eff3860bSMatthew Wilcox #include "regression.h"
13*eff3860bSMatthew Wilcox
14*eff3860bSMatthew Wilcox static pthread_barrier_t worker_barrier;
15*eff3860bSMatthew Wilcox static int obj0, obj1;
16*eff3860bSMatthew Wilcox static RADIX_TREE(mt_tree, GFP_KERNEL);
17*eff3860bSMatthew Wilcox
reader_fn(void * arg)18*eff3860bSMatthew Wilcox static void *reader_fn(void *arg)
19*eff3860bSMatthew Wilcox {
20*eff3860bSMatthew Wilcox int i;
21*eff3860bSMatthew Wilcox void *entry;
22*eff3860bSMatthew Wilcox
23*eff3860bSMatthew Wilcox rcu_register_thread();
24*eff3860bSMatthew Wilcox pthread_barrier_wait(&worker_barrier);
25*eff3860bSMatthew Wilcox
26*eff3860bSMatthew Wilcox for (i = 0; i < 1000000; i++) {
27*eff3860bSMatthew Wilcox rcu_read_lock();
28*eff3860bSMatthew Wilcox entry = radix_tree_lookup(&mt_tree, 0);
29*eff3860bSMatthew Wilcox rcu_read_unlock();
30*eff3860bSMatthew Wilcox if (entry != &obj0) {
31*eff3860bSMatthew Wilcox printf("iteration %d bad entry = %p\n", i, entry);
32*eff3860bSMatthew Wilcox abort();
33*eff3860bSMatthew Wilcox }
34*eff3860bSMatthew Wilcox }
35*eff3860bSMatthew Wilcox
36*eff3860bSMatthew Wilcox rcu_unregister_thread();
37*eff3860bSMatthew Wilcox
38*eff3860bSMatthew Wilcox return NULL;
39*eff3860bSMatthew Wilcox }
40*eff3860bSMatthew Wilcox
writer_fn(void * arg)41*eff3860bSMatthew Wilcox static void *writer_fn(void *arg)
42*eff3860bSMatthew Wilcox {
43*eff3860bSMatthew Wilcox int i;
44*eff3860bSMatthew Wilcox
45*eff3860bSMatthew Wilcox rcu_register_thread();
46*eff3860bSMatthew Wilcox pthread_barrier_wait(&worker_barrier);
47*eff3860bSMatthew Wilcox
48*eff3860bSMatthew Wilcox for (i = 0; i < 1000000; i++) {
49*eff3860bSMatthew Wilcox radix_tree_insert(&mt_tree, 1, &obj1);
50*eff3860bSMatthew Wilcox radix_tree_delete(&mt_tree, 1);
51*eff3860bSMatthew Wilcox }
52*eff3860bSMatthew Wilcox
53*eff3860bSMatthew Wilcox rcu_unregister_thread();
54*eff3860bSMatthew Wilcox
55*eff3860bSMatthew Wilcox return NULL;
56*eff3860bSMatthew Wilcox }
57*eff3860bSMatthew Wilcox
regression4_test(void)58*eff3860bSMatthew Wilcox void regression4_test(void)
59*eff3860bSMatthew Wilcox {
60*eff3860bSMatthew Wilcox pthread_t reader, writer;
61*eff3860bSMatthew Wilcox
62*eff3860bSMatthew Wilcox printv(1, "regression test 4 starting\n");
63*eff3860bSMatthew Wilcox
64*eff3860bSMatthew Wilcox radix_tree_insert(&mt_tree, 0, &obj0);
65*eff3860bSMatthew Wilcox pthread_barrier_init(&worker_barrier, NULL, 2);
66*eff3860bSMatthew Wilcox
67*eff3860bSMatthew Wilcox if (pthread_create(&reader, NULL, reader_fn, NULL) ||
68*eff3860bSMatthew Wilcox pthread_create(&writer, NULL, writer_fn, NULL)) {
69*eff3860bSMatthew Wilcox perror("pthread_create");
70*eff3860bSMatthew Wilcox exit(1);
71*eff3860bSMatthew Wilcox }
72*eff3860bSMatthew Wilcox
73*eff3860bSMatthew Wilcox if (pthread_join(reader, NULL) || pthread_join(writer, NULL)) {
74*eff3860bSMatthew Wilcox perror("pthread_join");
75*eff3860bSMatthew Wilcox exit(1);
76*eff3860bSMatthew Wilcox }
77*eff3860bSMatthew Wilcox
78*eff3860bSMatthew Wilcox printv(1, "regression test 4 passed\n");
79*eff3860bSMatthew Wilcox }
80