source: CIVL/examples/pthread/threader/qrcu_false-unreach-call.c@ 1aaefd4

main test-branch
Last change on this file since 1aaefd4 was ea777aa, checked in by Alex Wilton <awilton@…>, 3 years ago

Moved examples, include, build_default.properties, common.xml, and README out from dev.civl.com into the root of the repo.

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

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