SICP問題3.47

セマフォの実装
a. 相互排除器を使った実装

(define (make-semaphore n)
  (let ((acquired 0)
        (mutex (make-mutex)))
    (define (the-semaphore m)
      (cond ((eq? m 'acquire)
             (mutex m)
             (if (> acquired n)
                 (begin
                   (mutex 'release)
                   (the-semaphore m)) ; release
                 (begin
                   (set! acquired (+ acquired 1))
                   (mutex 'release))))
            ((eq? m 'release)
             (mutex 'acquire)
             (set! acquired (- acquired 1))
             (mutex 'release))))
    the-semaphore))

b. test-and-set!を使った実装

(define (make-semaphore n)
  (let ((acquired 0)
        (cell (list #f)))
    (define (the-semaphre m)
      (cond ((eq? m 'acquire)
             (if (or (test-and-set! cell)
                     (>= acquired n))
                 (the-semaphore m) ; retry
                 (begin
                   (set! acquired (+ acquired 1))
                   (clear! cell)))
             ((eq? m 'release)
              (set! acquired (- acquired 1))
              (clear! cell)))))
    the-semaphore))