source: CIVL/examples/concurrency/bank.cvl@ 98faf28

1.23 2.0 acw/focus-triggers main test-branch
Last change on this file since 98faf28 was 98faf28, checked in by Stephen Siegel <siegel@…>, 13 years ago

Small change to bank.cvl: moved function definitions around to test fix to ABC Pruner.

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

  • Property mode set to 100644
File size: 5.1 KB
RevLine 
[8d704f9e]1/* bank.cil
2
3simple exercise in multitasking verification using CIVL.
4
5*/
6
7/* ========================================================================
8 constants
9 */
10#define NUM_ACCOUNTS 3
11
12#define true 1
13#define false 0
14
15
16/* ========================================================================
17 prototypes
18 */
19void init();
20int withdraw( int account_num, int amount );
21int deposit( int account_num, int amount );
22int balance( int account_num );
23int transfer( int to_account_num, int from_account_num, int amount );
24void lock_account( int account_num );
25void unlock_account( int account_num );
26
27/* ========================================================================
28 global variables
29 */
30int account_balance[ NUM_ACCOUNTS ];
31int account_locked[ NUM_ACCOUNTS ];
32
33/* ======================================================================== */
34void init ()
35{{
36 int acct_num;
37 for ( acct_num= 0; acct_num < NUM_ACCOUNTS; acct_num++ ) {
38 account_balance[acct_num]= 0;
39 account_locked[acct_num]= false;
40 }
41}}
42
43/* ======================================================================== */
44int withdraw( int account_num, int amount )
45/* Return value: false if success, true if an error occurred
46 */
47{{
48 $assume 0 <= account_num;
49 $assume account_num <= NUM_ACCOUNTS;
50 $assume amount >= 0;
51
52 int result;
53
54 // begin transaction
55 lock_account( account_num );
56
57 if ( account_balance[account_num] >= amount ) {
58 account_balance[account_num]= account_balance[account_num]- amount;
59 result= false;
60 } else {
61 result= true;
62 }
63
64 // end transaction
65 unlock_account( account_num );
66
67 return result;
68}}
69
70/* ======================================================================== */
71int deposit( int account_num, int amount )
72/* Return value: false if success, true if an error occurred
73 */
74{{
75 $assume 0 <= account_num;
76 $assume account_num <= NUM_ACCOUNTS;
77 $assume amount >= 0;
78
79 // begin transaction
80 lock_account( account_num );
81
82 account_balance[account_num]= account_balance[account_num]+ amount;
83
84 // end transaction
85 unlock_account( account_num );
86
87 return false;
88}}
89
90/* ======================================================================== */
91int balance( int account_num )
92/* Return value: the balance of the indicated account
93 */
94{{
95 $assume 0 <= account_num;
96 $assume account_num <= NUM_ACCOUNTS;
97
98 int balance= 0;
99
100 // begin transaction
101 lock_account( account_num );
102
103 balance= account_balance[account_num];
104
105 // end transaction
106 unlock_account( account_num );
107
108 return account_balance[account_num];
109}}
110
111/* ======================================================================== */
112int transfer( int to_account_num, int from_account_num, int amount )
113/* Return value: false if success, true if an error occurred
114 */
115{{
116 $assume 0 <= to_account_num;
117 $assume to_account_num <= NUM_ACCOUNTS;
118 $assume 0 <= from_account_num;
119 $assume from_account_num <= NUM_ACCOUNTS;
120 $assume from_account_num != to_account_num;
121 $assume amount >= 0;
122
123 int result= false;
124
125 // begin transaction
126 if ( from_account_num < to_account_num ) {
127 lock_account( from_account_num );
128 lock_account( to_account_num );
129 } else {
130 lock_account( to_account_num );
131 lock_account( from_account_num );
132 }
133
134 if ( account_balance[from_account_num] >= amount ) {
135 account_balance[from_account_num]-= amount;
136 account_balance[to_account_num]+= amount;
137 result= false;
138 } else {
139 result= true;
140 }
141
142 // end transaction
143 if ( from_account_num < to_account_num ) {
144 lock_account( to_account_num );
145 lock_account( from_account_num );
146 } else {
147 lock_account( from_account_num );
148 lock_account( to_account_num );
149 }
150
151 return result;
152}}
153
154/* ======================================================================== */
155/* main() and its helper ftns
156 */
157void main_a()
158{{
159 withdraw( 0, 50 );
160 transfer( 0, 1, 50 );
161 deposit( 2, 100 );
162}}
163
164void main_b()
165{{
166 deposit( 1, 10 );
167 withdraw( 2, 50 );
168 transfer( 2, 0, 20 );
169}}
170
171void main()
172{{
173 int acct_num= 0;
174
175 //;;$proc proc_a;
176 //;;$proc proc_b;
177
178 init();
179
180 /* give all accounts some money */
181 for ( acct_num= 0; acct_num < NUM_ACCOUNTS; acct_num++ ) {
182 deposit( acct_num, 100 );
183 }
184
185 //;;proc_a= $spawn main_a();
186 //;;proc_b= $spawn main_b();
187
188 //;;$wait proc_a;
189 //;;$wait proc_b;
190 // TODO: resolve why this temporary code generates an error.
191 main_a();
192 main_b();
193}}
194
[98faf28]195/* ======================================================================== */
196
197void lock_account( int account_num )
198{{
199 $assume 0 <= account_num;
200 $assume account_num <= NUM_ACCOUNTS;
201
202 // this needs to happen atomically -- does it?
203 $when (account_locked[account_num] == false) account_locked[account_num]= true;
204}}
205
206/* ======================================================================== */
207void unlock_account( int account_num )
208{{
209 $assume 0 <= account_num;
210 $assume account_num <= NUM_ACCOUNTS;
211
212 account_locked[ account_num ]= false;
213}}
214
215
216
[8d704f9e]217/* ======================================================================== */
218/* end of file */
219
220
Note: See TracBrowser for help on using the repository browser.