-
Notifications
You must be signed in to change notification settings - Fork 10
/
ex-3.47.scm
61 lines (54 loc) · 1.78 KB
/
ex-3.47.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.47. A semaphore (of size n) is a generalization of a mutex.
;;; Like a mutex, a semaphore supports acquire and release operations, but it
;;; is more general in that up to n processes can acquire it concurrently.
;;; Additional processes that attempt to acquire the semaphore must wait for
;;; release operations. Give implementations of semaphores
;;; a. in terms of mutexes
(define (make-semaphore n)
(let ([mutex (make-mutex)]
[c 0])
(define (acquire)
(mutex 'acquire)
(cond [(< c n)
(set! c (+ c 1))
(mutex 'release)]
[else
(mutex 'release)
(acquire)]))
(define (release)
(mutex 'acquire)
(if (<= 1 c)
(set! c (- c 1))
(error "This semaphore is not acquired yet"))
(mutex 'release))
(define (dispatch m)
(cond [(eq? m 'acquire) (acquire)]
[(eq? m 'release) (release)]
[else (error "Unknown message sent to a semaphore" m)]))
dispatch))
;;; b. in terms of atomic test-and-set! operations.
(define (make-semaphore n)
(let ([cell (list #f)]
[c 0])
(define (acquire)
(if (test-and-set! cell)
(acquire)
(cond [(< c n)
(set! c (+ c 1))
(clear! cell)]
[else
(clear! cell)
(acquire)])))
(define (release)
(cond [(test-and-set! cell)
(release)]
[else
(if (<= 1 c)
(set! c (- c 1))
(error "This semaphore is not acquired yet"))
(clear! cell)])
(define (dispatch m)
(cond [(eq? m 'acquire) (acquire)]
[(eq? m 'release) (release)]
[else (error "Unknown message sent to a semaphore" m)]))
dispatch))