1 // SPDX-License-Identifier: GPL-2.0
2 #include <src/combined_source.c>
3 
4 int x;
5 int y;
6 
7 int __unbuffered_tpr_x;
8 int __unbuffered_tpr_y;
9 
10 DEFINE_SRCU(ss);
11 
rcu_reader(void)12 void rcu_reader(void)
13 {
14 	int idx;
15 
16 #ifndef FORCE_FAILURE_3
17 	idx = srcu_read_lock(&ss);
18 #endif
19 	might_sleep();
20 
21 	__unbuffered_tpr_y = READ_ONCE(y);
22 #ifdef FORCE_FAILURE
23 	srcu_read_unlock(&ss, idx);
24 	idx = srcu_read_lock(&ss);
25 #endif
26 	WRITE_ONCE(x, 1);
27 
28 #ifndef FORCE_FAILURE_3
29 	srcu_read_unlock(&ss, idx);
30 #endif
31 	might_sleep();
32 }
33 
thread_update(void * arg)34 void *thread_update(void *arg)
35 {
36 	WRITE_ONCE(y, 1);
37 #ifndef FORCE_FAILURE_2
38 	synchronize_srcu(&ss);
39 #endif
40 	might_sleep();
41 	__unbuffered_tpr_x = READ_ONCE(x);
42 
43 	return NULL;
44 }
45 
thread_process_reader(void * arg)46 void *thread_process_reader(void *arg)
47 {
48 	rcu_reader();
49 
50 	return NULL;
51 }
52 
main(int argc,char * argv[])53 int main(int argc, char *argv[])
54 {
55 	pthread_t tu;
56 	pthread_t tpr;
57 
58 	if (pthread_create(&tu, NULL, thread_update, NULL))
59 		abort();
60 	if (pthread_create(&tpr, NULL, thread_process_reader, NULL))
61 		abort();
62 	if (pthread_join(tu, NULL))
63 		abort();
64 	if (pthread_join(tpr, NULL))
65 		abort();
66 	assert(__unbuffered_tpr_y != 0 || __unbuffered_tpr_x != 0);
67 
68 #ifdef ASSERT_END
69 	assert(0);
70 #endif
71 
72 	return 0;
73 }
74