source: CIVL/examples/pthread/cprover/08_rand_cas_true.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: 2.0 KB
Line 
1//http://www.ibm.com/developerworks/java/library/j-jtp11234/
2//Listing 5. Implementing a thread-safe PRNG with synchronization and atomic variables
3
4#include <pthread.h>
5
6#define assume(e) __VERIFIER_assume(e)
7#define assert(e) { if(!(e)) { ERROR: goto ERROR; (void)0; } }
8
9inline int calculateNext(int s2){
10 int calculateNext_return;
11 do
12 {
13 calculateNext_return = __VERIFIER_nondet_int();
14 }
15 while(calculateNext_return == s2 || calculateNext_return == 0);
16
17 return calculateNext_return;
18}
19
20volatile int seed, m=0;
21
22void __VERIFIER_atomic_acquire()
23{
24 assume(m==0);
25 m = 1;
26}
27
28void __VERIFIER_atomic_release()
29{
30 assume(m==1);
31 m = 0;
32}
33
34void __VERIFIER_atomic_CAS(
35 volatile int *v,
36 int e,
37 int u,
38 int *r)
39{
40 if(*v == e)
41 {
42 *v = u, *r = 1;
43 }
44 else
45 {
46 *r = 0;
47 }
48}
49
50inline int PseudoRandomUsingAtomic_nextInt(int n)
51{
52 int read, nexts, casret, nextInt_return;
53
54 while(1) {
55 read = seed;
56 nexts = calculateNext(read);
57 assert(nexts != read);
58 __VERIFIER_atomic_CAS(&seed,read,nexts,&casret);
59
60 if(casret == 1){
61 nextInt_return = nexts % n;
62 //assume(nexts < n);
63 //nextInt_return = nexts;
64 break;
65 }
66 }
67
68 return nextInt_return;
69}
70
71inline void PseudoRandomUsingAtomic_monitor()
72{
73 while(1)
74 {
75 assert(seed != 0);
76 }
77}
78
79inline void PseudoRandomUsingAtomic_constructor(int init)
80{
81 seed = init;
82}
83
84inline void PseudoRandomUsingAtomic__threadmain()
85{
86 int myrand;
87
88 myrand = PseudoRandomUsingAtomic_nextInt(10);
89 assert(myrand <= 10);
90}
91
92#define STATE_UNINITIALIZED 0
93#define STATE_INITIALIZED 1
94
95volatile int state = STATE_UNINITIALIZED;
96void* thr1(void* arg)
97{
98 __VERIFIER_atomic_acquire();
99 switch(state)
100 {
101 case (STATE_UNINITIALIZED):
102 PseudoRandomUsingAtomic_constructor(1);
103 state = STATE_INITIALIZED;
104 __VERIFIER_atomic_release();
105
106 PseudoRandomUsingAtomic_monitor(); //never returns
107 break;
108 case (STATE_INITIALIZED):
109 __VERIFIER_atomic_release();
110
111 PseudoRandomUsingAtomic__threadmain();
112 break;
113 }
114
115 return 0;
116}
117
118int main()
119{
120 pthread_t t;
121
122 while(1) { pthread_create(&t, 0, thr1, 0); }
123}
Note: See TracBrowser for help on using the repository browser.