source: CIVL/examples/concurrency/bank.cvl@ b968f34

1.23 2.0 acw/focus-triggers main test-branch
Last change on this file since b968f34 was 9fb69d3, checked in by Manchun Zheng <zmanchun@…>, 13 years ago

cleaned up examples/tests in concurrency folder.

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

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