source: CIVL/examples/concurrency/bank.cvl@ 4f22a92

1.23 2.0 acw/focus-triggers main test-branch
Last change on this file since 4f22a92 was 8b354468, checked in by Manchun Zheng <zmanchun@…>, 12 years ago

fix indention of atomic block

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

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