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