// SPDX-License-Identifier: GPL-2.0 #include <linux/kernel.h> #include <linux/gfp.h> #include <linux/slab.h> #include <linux/radix-tree.h> #include <linux/rcupdate.h> #include <stdlib.h> #include <pthread.h> #include <stdio.h> #include <assert.h> #include "regression.h" static pthread_barrier_t worker_barrier; static int obj0, obj1; static RADIX_TREE(mt_tree, GFP_KERNEL); static void *reader_fn(void *arg) { int i; void *entry; rcu_register_thread(); pthread_barrier_wait(&worker_barrier); for (i = 0; i < 1000000; i++) { rcu_read_lock(); entry = radix_tree_lookup(&mt_tree, 0); rcu_read_unlock(); if (entry != &obj0) { printf("iteration %d bad entry = %p\n", i, entry); abort(); } } rcu_unregister_thread(); return NULL; } static void *writer_fn(void *arg) { int i; rcu_register_thread(); pthread_barrier_wait(&worker_barrier); for (i = 0; i < 1000000; i++) { radix_tree_insert(&mt_tree, 1, &obj1); radix_tree_delete(&mt_tree, 1); } rcu_unregister_thread(); return NULL; } void regression4_test(void) { pthread_t reader, writer; printv(1, "regression test 4 starting\n"); radix_tree_insert(&mt_tree, 0, &obj0); pthread_barrier_init(&worker_barrier, NULL, 2); if (pthread_create(&reader, NULL, reader_fn, NULL) || pthread_create(&writer, NULL, writer_fn, NULL)) { perror("pthread_create"); exit(1); } if (pthread_join(reader, NULL) || pthread_join(writer, NULL)) { perror("pthread_join"); exit(1); } printv(1, "regression test 4 passed\n"); }