xref: /openbmc/linux/tools/testing/radix-tree/regression4.c (revision 95d002e0a34cb0f238abb39987f9980f325d8332)
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