Blob


1 (define (make-serializer)
2 (let ((mutex (make-mutex)))
3 (lambda (p)
4 (define (serialized-p . args)
5 (mutex 'acquire)
6 (let ((val (apply p args)))
7 (mutex 'release)
8 val))
9 serialized-p)))
11 (define (make-mutex)
12 (let ((cell (list false)))
13 (define (the-mutex m)
14 (cond ((eq? m 'acquire) (if (test-and-set! cell)
15 (the-mutex 'acquire)))
16 ((eq? m 'release) (clear! cell))))
17 the-mutex))
19 (define (clear! cell)
20 (set-car! cell false))
21 ;; (define (test-and-set! cell)
22 ;; (if (car cell)
23 ;; true
24 ;; (begin (set-car! cell true)
25 ;; false)))
26 (define (test-and-set! cell)
27 (without-interrupts
28 (lambda ()
29 (if (car cell)
30 true
31 (begin (set-car! cell true)
32 false)))))
34 ;; Exercise 3.46. Suppose that we implement test-and-set! using an ordinary procedure as shown in the text, without attempting to make the operation atomic. Draw a timing diagram like the one in figure 3.29 to demonstrate how the mutex implementation can fail by allowing two processes to acquire the mutex at the same time.
36 ;; The same mutex might be acquired at the same time by two different processes. For example, both may check (car cell) right after the other. It appears to both processes as though the mutex were free to be acquired, so both set the cell to true and think that they have exclusive access tothe mutex.