source: CIVL/examples/pthread/threader/qrcu_false.c@ 5c27aa5

1.23 2.0 main test-branch
Last change on this file since 5c27aa5 was e3151da, checked in by Ziqing Luo <ziqing@…>, 11 years ago

re-organized example directory

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@1763 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 3.6 KB
Line 
1extern int __VERIFIER_nondet_int(void);
2/* Testcase from Threader's distribution. For details see:
3 http://www.model.in.tum.de/~popeea/research/threader
4
5 This file is adapted from the Promela code introduced in the paper:
6 Using Promela and Spin to verify parallel algorithms
7 by Paul McKenney
8*/
9
10#include <pthread.h>
11#define assert(e) if (!(e)) ERROR: goto ERROR;
12
13int idx=0; // boolean to control which of the two elements will be used by readers
14 // (idx <= 0) then ctr1 is used
15 // (idx >= 1) then ctr2 is used
16int ctr1=1, ctr2=0;
17int readerprogress1=0, readerprogress2=0; // the progress is indicated by an integer:
18 // 0: reader not yet started
19 // 1: reader withing QRCU read-side critical section
20 // 2: reader finished with QRCU read-side critical section
21pthread_mutex_t mutex; // used to serialize updaters' slowpaths
22
23/* sums the pair of counters forcing weak memory ordering */
24#define sum_unordered \
25 if (__VERIFIER_nondet_int()) { \
26 sum = ctr1; \
27 sum = sum + ctr2; \
28 } else { \
29 sum = ctr2; \
30 sum = sum + ctr1; \
31 }
32
33void __VERIFIER_atomic_use1(int myidx) {
34 __VERIFIER_assume(myidx <= 0 && ctr1>0);
35 ctr1++;
36}
37
38void __VERIFIER_atomic_use2(int myidx) {
39 __VERIFIER_assume(myidx >= 1 && ctr2>0);
40 ctr2++;
41}
42
43void __VERIFIER_atomic_use_done(int myidx) {
44 if (myidx <= 0) { ctr1--; }
45 else { ctr2--; }
46}
47
48void __VERIFIER_atomic_take_snapshot(int readerstart1, int readerstart2) {
49 /* Snapshot reader state. */
50 readerstart1 = readerprogress1;
51 readerstart2 = readerprogress2;
52}
53
54void __VERIFIER_atomic_check_progress1(int readerstart1) {
55 /* Verify reader progress. */
56 if (__VERIFIER_nondet_int()) {
57 __VERIFIER_assume(readerstart1 == 1 && readerprogress1 == 1);
58 assert(0);
59 }
60 return;
61}
62
63void __VERIFIER_atomic_check_progress2(int readerstart2) {
64 if (__VERIFIER_nondet_int()) {
65 __VERIFIER_assume(readerstart2 == 1 && readerprogress2 == 1);
66 assert(0);
67 }
68 return;
69}
70
71void *qrcu_reader1(void * arg) {
72 int myidx;
73 /* rcu_read_lock */
74 while (1) {
75 myidx = idx;
76 if (__VERIFIER_nondet_int()) {
77 __VERIFIER_atomic_use1(myidx);
78 break;
79 } else {
80 if (__VERIFIER_nondet_int()) {
81 __VERIFIER_atomic_use2(myidx);
82 break;
83 } else {}
84 }
85 }
86 readerprogress1 = 1;
87 readerprogress1 = 2;
88 /* rcu_read_unlock */
89 __VERIFIER_atomic_use_done(myidx);
90 return 0;
91}
92
93void *qrcu_reader2(void * arg) {
94 int myidx;
95 /* rcu_read_lock */
96 while (1) {
97 myidx = idx;
98 if (__VERIFIER_nondet_int()) {
99 __VERIFIER_atomic_use1(myidx);
100 break;
101 } else {
102 if (__VERIFIER_nondet_int()) {
103 __VERIFIER_atomic_use2(myidx);
104 break;
105 } else {}
106 }
107 }
108 readerprogress2 = 1;
109 readerprogress2 = 2;
110 /* rcu_read_unlock */
111 __VERIFIER_atomic_use_done(myidx);
112 return 0;
113}
114
115void* qrcu_updater(void * arg) {
116 int i;
117 int readerstart1, readerstart2;
118 int sum;
119 __VERIFIER_atomic_take_snapshot(readerstart1, readerstart2);
120 sum_unordered;
121 if (sum <= 1) { sum_unordered; }
122 else {}
123 if (sum > 1) {
124 pthread_mutex_lock(&mutex);
125 if (idx <= 0) { ctr2++; idx = 1; ctr1--; }
126 else { ctr1++; idx = 0; ctr2--; }
127 if (idx <= 0) { while (ctr1 > 0); }
128 else { while (ctr2 > 0); }
129 pthread_mutex_unlock(&mutex);
130 } else {}
131 __VERIFIER_atomic_check_progress1(readerstart1);
132 __VERIFIER_atomic_check_progress2(readerstart2);
133 return 0;
134}
135
136int main() {
137 pthread_t t1, t2, t3;
138 pthread_mutex_init(&mutex, 0);
139 pthread_create(&t1, 0, qrcu_reader1, 0);
140 pthread_create(&t2, 0, qrcu_reader2, 0);
141 pthread_create(&t3, 0, qrcu_updater, 0);
142 pthread_join(t1, 0);
143 pthread_join(t2, 0);
144 pthread_join(t3, 0);
145 pthread_mutex_destroy(&mutex);
146 return 0;
147}
Note: See TracBrowser for help on using the repository browser.