]> git.rkrishnan.org Git - sicp.git/blob - src/sicp/ex3_48.rkt
Lazy version of evaluator and tests.
[sicp.git] / src / sicp / ex3_48.rkt
1 #lang racket
2
3 #|
4
5 by giving a unique number to each account, we are ordering the access to the account
6 in a specific manner (say in the ascending order of the number). The reason why deadlock
7 occurs is be cause of the concurrent access to the accounts in a specific order (Paul
8 attempts to transfer a1 and a2 while Peter attempts to transfer a2 and a1. With the 
9 suggested change, both will concurrently try to access a1 first but only one of them
10 will get access while the other will wait until the serializer for a1 is released.
11
12 |#
13
14 (define (make-account-and-serializer account-number balance)
15   (define (withdraw amount)
16     (if (>= balance amount)
17         (begin (set! balance (- balance amount))
18                balance)
19         "Insufficient funds"))
20   (define (deposit amount)
21     (set! balance (+ balance amount))
22     balance)
23   (let ((balance-serializer (make-serializer)))
24     (define (dispatch m)
25       (cond ((eq? m 'withdraw) withdraw)
26             ((eq? m 'deposit) deposit)
27             ((eq? m 'balance) balance)
28             ((eq? m 'account-number) account-number)
29             ((eq? m 'serializer) balance-serializer)
30             (else (error "Unknown request -- MAKE-ACCOUNT"
31                          m))))
32     dispatch))
33
34 (define (serialized-exchange account1 account2)
35   (let ((serializer1 (account1 'serializer))
36         (serializer2 (account2 'serializer))
37         (number1 (account1 'account-number))
38         (number2 (account2 'account-number)))
39     (if (< number1 number2)
40         ((serializer2 (serializer1 exchange))
41          account1
42          account2)
43         ((serializer1 (serializer2 exchange))
44          account1
45          account2)
46 ))