source: CIVL/examples/concurrency/bank.cvl

main
Last change on this file 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: 5.0 KB
RevLine 
[9fb69d3]1/* simple exercise in multitasking verification using CIVL.
2 * Commandline execution:
3 * civl verify -inputNUM_ACCOUNTS=5 bank.cvl
4 * */
[e6b02c8]5#include<civlc.cvh>
[8d704f9e]6
[0baeebd]7$input int NUM_ACCOUNTS = 3;
[9fb69d3]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
[3ff27cf]51 $assume(0 <= account_num);
52 $assume(account_num <= NUM_ACCOUNTS);
53 $assume(amount >= 0);
[8d704f9e]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{
[3ff27cf]72 $assume(0 <= account_num);
73 $assume(account_num <= NUM_ACCOUNTS);
74 $assume(amount >= 0);
[8d704f9e]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
[3ff27cf]90 $assume(0 <= account_num);
91 $assume(account_num <= NUM_ACCOUNTS);
[8d704f9e]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
[3ff27cf]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);
[8d704f9e]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{
[b50c660]144 withdraw( 0, 50 );
145 transfer( 0, 1, 50 );
146 deposit( 2, 100 );
[9fb69d3]147}
[8d704f9e]148
149void main_b()
[9fb69d3]150{
[b50c660]151 deposit( 1, 10 );
152 withdraw( 2, 50 );
153 transfer( 2, 0, 20 );
[9fb69d3]154}
[8d704f9e]155
156void main()
[9fb69d3]157{
[a6ae46e]158 int acct_num = 0;
159 $proc proc_a;
160 $proc proc_b;
[8d704f9e]161
[b50c660]162 init();
163 /* give all accounts some money */
164 for ( acct_num= 0; acct_num < NUM_ACCOUNTS; acct_num++ ) {
165 deposit( acct_num, 100 );
[8b354468]166 }
[b50c660]167 proc_a= $spawn main_a();
168 proc_b= $spawn main_b();
[a82987f]169 $wait(proc_a);
170 $wait(proc_b);
[9fb69d3]171}
[8d704f9e]172
[98faf28]173/* ======================================================================== */
174void lock_account( int account_num )
[9fb69d3]175{
[3ff27cf]176 $assume(0 <= account_num);
177 $assume(account_num <= NUM_ACCOUNTS);
[98faf28]178 // this needs to happen atomically -- does it?
179 $when (account_locked[account_num] == false) account_locked[account_num]= true;
[9fb69d3]180}
[98faf28]181
182/* ======================================================================== */
183void unlock_account( int account_num )
[9fb69d3]184{
[3ff27cf]185 $assume(0 <= account_num);
186 $assume(account_num <= NUM_ACCOUNTS);
[98faf28]187
188 account_locked[ account_num ]= false;
[9fb69d3]189}
[8d704f9e]190/* ======================================================================== */
191/* end of file */
Note: See TracBrowser for help on using the repository browser.