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