proposal.scm 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Richard Kelsey, Jonathan Rees, Robert Ransom
  3. ; Higher-level proposal stuff.
  4. ; Execute THUNK atomically with its own proposal, saving and restoring
  5. ; the current proposal.
  6. (define (call-atomically thunk)
  7. (let ((old (current-proposal)))
  8. (let loop ()
  9. (set-current-proposal! (make-proposal))
  10. (call-with-values thunk
  11. (lambda results
  12. (if (maybe-commit)
  13. (begin
  14. (set-current-proposal! old)
  15. (apply values results))
  16. (loop)))))))
  17. ; Ditto, but no values are returned.
  18. (define (call-atomically! thunk)
  19. (with-new-proposal (lose)
  20. (thunk)
  21. (or (maybe-commit)
  22. (lose)))
  23. (values))
  24. ; Same again, except that we use the current proposal, if there is one
  25. ; (and don't commit on the existing proposal).
  26. (define (call-ensuring-atomicity thunk)
  27. (if (current-proposal)
  28. (thunk)
  29. (call-atomically thunk)))
  30. (define (call-ensuring-atomicity! thunk)
  31. (if (current-proposal)
  32. (thunk)
  33. (call-atomically! thunk)))
  34. ; Macro versions of the above that avoid the need to write (lambda () ...)
  35. ; around the critical section.
  36. (define-syntax atomically
  37. (syntax-rules ()
  38. ((atomically)
  39. (unspecific))
  40. ((atomically body ...)
  41. (call-atomically
  42. (lambda () body ...)))))
  43. (define-syntax atomically!
  44. (syntax-rules ()
  45. ((atomically)
  46. (values))
  47. ((atomically body ...)
  48. (call-atomically!
  49. (lambda () body ...)))))
  50. (define-syntax ensure-atomicity
  51. (syntax-rules ()
  52. ((ensure-atomicity)
  53. (unspecific))
  54. ((ensure-atomicity body ...)
  55. (call-ensuring-atomicity
  56. (lambda () body ...)))))
  57. (define-syntax ensure-atomicity!
  58. (syntax-rules ()
  59. ((ensure-atomicity)
  60. (values))
  61. ((ensure-atomicity body ...)
  62. (call-ensuring-atomicity!
  63. (lambda () body ...)))))
  64. ; Save the existing proposal, install a new one, execute the body, and then
  65. ; replace the original proposal.
  66. (define-syntax with-new-proposal
  67. (syntax-rules ()
  68. ((with-new-proposal (?lose) ?body ?more ...)
  69. (let ((old (current-proposal)))
  70. (call-with-values
  71. (lambda ()
  72. (let ?lose ()
  73. (set-current-proposal! (make-proposal))
  74. (begin ?body ?more ...)))
  75. (lambda results
  76. (set-current-proposal! old)
  77. (apply values results)))))))
  78. ; Useful for getting rid of a proposal before raising an error.
  79. (define (remove-current-proposal!)
  80. (set-current-proposal! #f))
  81. ; Useful for detecting that a proposal should be got rid of.
  82. (define (proposal-active?)
  83. (x->boolean (current-proposal)))
  84. ; For use when an inconsistency has been detected. The SET-CAR! ensures that
  85. ; the earlier PROVISIONAL-CAR will fail.
  86. (define (invalidate-current-proposal!)
  87. (let ((value (provisional-car j-random-pair)))
  88. (set-car! j-random-pair (cons #f #f))
  89. value))
  90. (define j-random-pair (list #f))