(define (make-semaphore n)
(let ((the-mutex (make-mutex))
(count 0))
(define (the-semaphore m)
(cond ((eq? m 'acquire)
(the-mutex 'acquire)
(if (= count n)
(begin
(the-mutex 'release)
(the-semaphore 'acquire))
(begin
(set! count (+ count 1))
(the-mutex 'release))))
((eq? m 'release)
(the-mutex 'acquire)
(if (> count 0)
(set! count (- count 1)))
(the-mutex 'release))))
the-semaphore))
(I’ve Borrowed code above from Weiqun Zhang’s Blog – SICP Exercise 3.47.)
It took some time to understand the structure of semaphore. Here is the problem:
The place of ‘acquire’
Next question that bothered me was that: does the code still work if I replace acquire method as follows?
(define (make-semaphore n)
(let ((the-mutex (make-mutex))
(count 0))
(define (the-semaphore m)
(cond ((eq? m 'acquire)
(if (= count n)
(the-semaphore 'acquire))
(begin
(the-mutex 'acquire) ; Added acquire method here instead
(set! count (+ count 1))
(the-mutex 'release))))
((eq? m 'release)
(the-mutex 'acquire)
(if (> count 0)
(set! count (- count 1)))
(the-mutex 'release))))
the-semaphore))
After a little bit observation I noticed that this code has a problem:
So the place of ‘acquire’ should be before (if (= count n) … :

