File: proposal.scm

package info (click to toggle)
scheme48 1.9.2-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 18,232 kB
  • sloc: lisp: 88,907; ansic: 87,519; sh: 3,224; makefile: 771
file content (114 lines) | stat: -rw-r--r-- 2,880 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
; Part of Scheme 48 1.9.  See file COPYING for notices and license.

; Authors: Richard Kelsey, Jonathan Rees, Robert Ransom


; Higher-level proposal stuff.

; Execute THUNK atomically with its own proposal, saving and restoring
; the current proposal.

(define (call-atomically thunk)
  (let ((old (current-proposal)))
    (let loop ()
      (set-current-proposal! (make-proposal))
      (call-with-values thunk
			(lambda results
			  (if (maybe-commit)
			      (begin
				(set-current-proposal! old)
				(apply values results))
			      (loop)))))))

; Ditto, but no values are returned.

(define (call-atomically! thunk)
  (with-new-proposal (lose)
    (thunk)
    (or (maybe-commit)
	(lose)))
  (values))

; Same again, except that we use the current proposal, if there is one
; (and don't commit on the existing proposal).

(define (call-ensuring-atomicity thunk)
  (if (current-proposal)
      (thunk)
      (call-atomically thunk)))

(define (call-ensuring-atomicity! thunk)
  (if (current-proposal)
      (thunk)
      (call-atomically! thunk)))

; Macro versions of the above that avoid the need to write (lambda () ...)
; around the critical section.

(define-syntax atomically
  (syntax-rules ()
    ((atomically)
     (unspecific))
    ((atomically body ...)
     (call-atomically
       (lambda () body ...)))))

(define-syntax atomically!
  (syntax-rules ()
    ((atomically)
     (values))
    ((atomically body ...)
     (call-atomically!
       (lambda () body ...)))))

(define-syntax ensure-atomicity
  (syntax-rules ()
    ((ensure-atomicity)
     (unspecific))
    ((ensure-atomicity body ...)
     (call-ensuring-atomicity
       (lambda () body ...)))))

(define-syntax ensure-atomicity!
  (syntax-rules ()
    ((ensure-atomicity)
     (values))
    ((ensure-atomicity body ...)
     (call-ensuring-atomicity!
       (lambda () body ...)))))

; Save the existing proposal, install a new one, execute the body, and then
; replace the original proposal.

(define-syntax with-new-proposal
  (syntax-rules ()
    ((with-new-proposal (?lose) ?body ?more ...)
     (let ((old (current-proposal)))
       (call-with-values
	(lambda ()
	  (let ?lose ()
	    (set-current-proposal! (make-proposal))
	    (begin ?body ?more ...)))
	(lambda results
	  (set-current-proposal! old)
	  (apply values results)))))))

; Useful for getting rid of a proposal before raising an error.

(define (remove-current-proposal!)
  (set-current-proposal! #f))

; Useful for detecting that a proposal should be got rid of.

(define (proposal-active?)
  (x->boolean (current-proposal)))

; For use when an inconsistency has been detected.  The SET-CAR! ensures that
; the earlier PROVISIONAL-CAR will fail.

(define (invalidate-current-proposal!)
  (let ((value (provisional-car j-random-pair)))
    (set-car! j-random-pair (cons #f #f))
    value))

(define j-random-pair (list #f))