-
Notifications
You must be signed in to change notification settings - Fork 10
/
ex-3.48.scm
61 lines (53 loc) · 2.23 KB
/
ex-3.48.scm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
;;; Exercise 3.48. Explain in detail why the deadlock-avoidance method
;;; described above, (i.e., the accounts are numbered, and each process
;;; attempts to acquire the smaller-numbered account first) avoids deadlock in
;;; the exchange problem.
; Deadlock occurs if two processes P1 and P2 try to exchange two accounts A1
; and A2 but each process try to acquire exclusive access rights in different
; order. For example, if P1 try to acquire the rights for A1 then A2 while P2
; try to acquire the rights for A2 then A1, deadlock can be occurred when P1
; acquires A1 and P2 acquires A2.
;
; If both processes try to acquire accounts in the same order, deadlock will
; never be occurred. For example, if P1 already acquires A1, P2 can't acquire
; A1 until P1 finishes. And if P2 already acquires A1, P1 can't acquire A1
; until P2 finishes.
;;; Rewrite serialized-exchange to incorporate this idea. (You will also need
;;; to modify make-account so that each account is created with a number, which
;;; can be accessed by sending an appropriate message.)
(define (serialized-exchange account1 account2)
(define (do-exchange account1 account2)
(let ((serializer1 (account1 'serializer))
(serializer2 (account2 'serializer)))
((serializer1 (serializer2 exchange))
account1
account2)))
(if (<= (account1 'id) (account2 'id))
(do-exchange account1 account2)
(do-exchange account2 account1)))
(define generate-accout-id
(let ([id 0]
[s (make-serializer)])
(s (lambda ()
(set! id (+ id 1))
id))))
(define (make-account-and-serializer balance)
(define (withdraw amount)
(if (>= balance amount)
(begin (set! balance (- balance amount))
balance)
"Insufficient funds"))
(define (deposit amount)
(set! balance (+ balance amount))
balance)
(let ((balance-serializer (make-serializer))
(id (generate-accout-id)))
(define (dispatch m)
(cond ((eq? m 'withdraw) withdraw)
((eq? m 'deposit) deposit)
((eq? m 'balance) balance)
((eq? m 'serializer) balance-serializer)
((eq? m 'id) id)
(else (error "Unknown request -- MAKE-ACCOUNT"
m))))
dispatch))