lock.scm 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Richard Kelsey, Jonathan Rees, Mike Sperber
  3. ; Locks (= semaphores)
  4. ; Each lock has:
  5. ; The owning thread, or #f if not locked. We use the owning thread instead
  6. ; of #t as an aid to debugging.
  7. ; A queue of waiting threads
  8. (define-synchronized-record-type lock :lock
  9. (really-make-lock owner queue uid)
  10. (owner)
  11. lock?
  12. (owner lock-owner set-lock-owner!)
  13. (queue lock-queue)
  14. (uid lock-uid)) ; for debugging
  15. (define lock-uid (list 0))
  16. (define (next-uid)
  17. (atomically
  18. (let ((uid (provisional-car lock-uid)))
  19. (provisional-set-car! lock-uid (+ uid 1))
  20. uid)))
  21. (define (make-lock)
  22. (really-make-lock #f (make-queue) (next-uid)))
  23. (define (obtain-lock lock)
  24. (with-new-proposal (lose)
  25. (or (cond ((lock-owner lock)
  26. (maybe-commit-and-block-on-queue (lock-queue lock)))
  27. (else
  28. (set-lock-owner! lock (current-thread))
  29. (maybe-commit)))
  30. (lose))))
  31. ; Returns #T if the lock is obtained and #F if not. Doesn't block.
  32. (define (maybe-obtain-lock lock)
  33. (with-new-proposal (lose)
  34. (cond ((lock-owner lock) ; no need to commit - we have only done
  35. #f) ; a single read
  36. (else
  37. (set-lock-owner! lock (current-thread))
  38. (or (maybe-commit)
  39. (lose))))))
  40. ; Returns #t if the lock has no new owner.
  41. (define (release-lock lock)
  42. (with-new-proposal (lose)
  43. (let ((next (maybe-dequeue-thread! (lock-queue lock))))
  44. (cond (next
  45. (set-lock-owner! lock next)
  46. (or (maybe-commit-and-make-ready next)
  47. (lose)))
  48. (else
  49. (set-lock-owner! lock #f)
  50. (or (maybe-commit)
  51. (lose)))))))
  52. (define (with-lock lock thunk)
  53. (dynamic-wind
  54. (lambda () (obtain-lock lock))
  55. thunk
  56. (lambda () (release-lock lock))))