Develop a monitor to solve this problem. The monitor should have two procedures: deposit(amount) and withdraw(amount). Assume the arguments to deposit and withdraw are positive, and the monitor uses Signal and Continue.
monitor SavingsAccount { // Private variables integer balance = 0; // Condition variables condvar funds; // Monitor procedures ... procedure deposit(integer amount) { balance = balance + amount; signal(funds); } procedure withdraw(integer amount) { while (amount > balance) { wait(funds); } balance = balance - amount; } }
The current balance is held in the private integer variable, balance
. Mutual exclusion is implicit; condition
synchronisation is achieved using the condition variable funds
, which is used to indicate that funds have been
deposited.
The deposit and withdraw operations are implemented as monitor
procedures. Deposit simply increases the current balance by amount
and signals that additional funds are now
available. Deposit never blocks (except for mutual exclusion), since making
a deposit is always legal, whatever the balance.
Withdraw checks to see if there are sufficient funds to cover the
withdrawal. If there are, it simply decreases the balance by amount. If
there are insufficient funds, it waits on the condition variable funds
until a deposit operation signals that there
are more funds available, at which point it tries again.
The wait
statement is enclosed in a
while loop to ensure that the condition on which we are waiting--there being
sufficient funds to cover the withdrawal--is actually true when we update
the balance.
Note that, as programmed, each deposit will only allow one blocked withdrawal
to be retried, even if there are now sufficient funds to allow several
processes to make withdrawals. If the process which is woken following the
deposit wants to make a withdrawal which exceeds the current balance, then
no withdrawals will be made, even if other, smaller, withdrawals could
proceed. One solution to this is to use signal_all(funds)
in deposit
to wake all processes wishing to make a withdrawal.