1% Part of Scheme 48 1.9.  See file COPYING for notices and license.
2
3% Authors: Richard Kelsey, Jonathan Rees, Mike Sperber, Robert Ransom
4
5\chapter{Threads}
6
7% safety (and the lack thereof)
8
9This chapter describes Scheme~48's thread system: Scheme~48 threads
10are fully preemptive; all threads (currently) run within a single
11operating system process.  Scheme~48 allows writing customized, nested
12schedulers, and provides numerous facilities for the synchronization
13of shared-memory programs, most importantly \textit{proposals} for
14optimistic concurrency.
15
16\section{Creating and controlling threads}
17
18The bindings described in this section are part of the \code{threads}
19structure.
20%
21\begin{protos}
22\proto{spawn}{ thunk}{thread}
23\proto{spawn}{ thunk name}{thread}
24\end{protos}
25%
26\code{Spawn} creates a new thread, passes that thread to the current
27scheduler, and instructs the scheduler to run \cvar{thunk} in that
28thread.  The \cvar{name} argument (a symbol) associates a symbolic
29name with the thread; it is purely for debugging purposes.
30%
31\begin{protos}
32\protonoresult{relinquish-timeslice}{}
33\protonoresult{sleep}{ time-in-milliseconds}
34\protonoresult{terminate-current-thread}{}
35\end{protos}
36%
37\code{Relinquish-timeslice} instructs the scheduler to run another
38thread, thus relinquishing the timeslice of the current thread.
39\code{Sleep} does the same and asks the scheduler to suspend the
40current thread for at least \cvar{time-in-milliseconds} milliseconds
41before resuming it.  Finally, \code{terminate-current-thread}
42terminates the current thread.
43
44Each thread is represented by a thread object.  The following
45procedures operate on that object:
46%
47\begin{protos}
48\proto{current-thread}{}{thread}
49\proto{thread?}{ thing}{boolean}
50\proto{thread-name}{ thread}{name}
51\proto{thread-uid}{ thread}{integer}
52\end{protos}
53%
54\code{Current-thread} returns the thread object associated with the
55currently running thread.
56\code{Thread?} is the predicate for thread objects.
57\code{Thread-name} extracts the name of the thread, if one was
58specified in the call to \code{spawn}, \code{\#f} otherwise.
59\code{Thread-uid} returns the \textit{uid} of the thread, a unique
60integer assigned by the thread system.
61
62\section{Advanced thread handling}
63
64The following bindings are part of the \code{threads-internal} structure:
65%
66\begin{protos}
67\protonoresultnoindex{terminate-thread!}{ thread}\mainschindex{terminate-thread"!}
68\protonoresultnoindex{kill-thread!}{ thread}\mainschindex{kill-thread"!}
69\end{protos}
70%
71\code{Terminate-thread!} unwinds the thread
72associated with \cvar{thread}, running any pending \code{dynamic-wind}
73\cvar{after} thunks (in that thread), after which the thread
74terminates.  \code{Kill-thread!} causes the thread associated with
75\cvar{thread} to terminate immediately without unwinding its continuation.
76%
77
78
79\section{Debugging multithreaded programs}
80
81Debugging multithreaded programs can be difficult.
82
83As described in section~\ref{command-threads}, when any thread signals an
84 error, Scheme~48 stops running all of the threads at that command level.
85
86 The following procedure (exported by the structure
87 \code{debug-messages}) is useful in debugging multi-threaded
88 programs.
89\begin{protos}
90\protonoresult{debug-message}{ element$_0$ \ldots}
91\end{protos}
92\code{Debug-message} prints the elements to `\code{stderr}', followed by a
93 newline.
94The only types of values that \code{debug-message} prints in full are small
95 integers (fixnums), strings, characters, symbols, booleans, and the empty list.
96Values of other types are abbreviated as follows:
97%
98\begin{center}
99\begin{tabular}{ll}
100 pair       &   \code{(...)}\\
101 vector     &   \code{\#(...)}\\
102 procedure  &   \code{\#\{procedure\}}\\
103 record     &   \code{\#\{<name of record type>\}}\\
104 all others &   \code{???}\\
105\end{tabular}
106\end{center}
107%
108The great thing about \code{debug-message} is that it bypasses Scheme~48's
109 I/O and thread handling.
110The message appears immediately, with no delays or errors.
111
112\section{Optimistic concurrency}
113\label{sec:optimistic-concurrency}
114
115Most of the bindings described in this section are part of the \code{proposals}
116structure---the low-level bindings described at the very end of the
117section are part of the \code{low-proposals} structure.
118
119A \cvar{proposal} is a record of reads from and and writes to locations in
120 memory.  Each thread has an associated \textit{current proposal}
121 (which may be \code{\#f}).
122The \cvar{logging} operations listed below record any values read or
123 written in the current proposal.
124A reading operation, such as \code{provisional-vector-ref}, first checks to
125 see if the current proposal contains a value for the relevant location.
126If so, that value is returned as the result of the read.
127If not, the current contents of the location are stored in the proposal and
128 then returned as the result of the read.
129A logging write to a location stores the new value as the current contents of
130 the location in the current proposal; the contents of the location itself
131 remain unchanged.
132
133\cvar{Committing} to a proposal verifies that any reads logged in
134 the proposal are still valid and, if so, performs any writes that
135 the proposal contains.
136A logged read is valid if, at the time of the commit, the location contains
137 the same value it had at the time of the original read (note that this does
138 not mean that no change occurred, simply that the value now is the same as
139 the value then).
140If a proposal has an invalid read then the effort to commit fails; no change
141 is made to the value of any location.
142The verifications and subsequent writes to memory are performed atomically
143 with respect to other proposal commit attempts.
144% Explain better?
145
146The \code{queues} structure (with source in \code{scheme/big/queue.scm})
147 is a thoroughly commented example of a moderately complex data structure
148 made thread-safe using optimistic concurrency.
149
150\begin{protos}
151\proto{call-ensuring-atomicity}{ thunk}{value \ldots}
152\protonoresultnoindex{call-ensuring-atomicity!}{ thunk}\mainschindex{call-ensuring-atomicity"!}
153\syntaxproto{ensure-atomicity}{ \cvar{exp} \ldots}{value \ldots}
154\syntaxprotonoresultnoindex{ensure-atomicity!}{ \cvar{exp} \ldots}\mainschindex{ensure-atomicity"!}
155\end{protos}
156\noindent
157If there is a proposal in place
158 \code{call-ensuring-atomicity} and \code{call-ensuring-atomicity!}
159 simply make a (tail-recursive) call to \cvar{thunk}.
160If the current proposal is \code{\#f} they create a new proposal,
161 install it, call \cvar{thunk}, and then try to commit to the proposal.
162This process repeats, with a new proposal on each iteration, until
163 the commit succeeds.
164\code{Call-ensuring-atomicity} returns whatever values are returned by \cvar{thunk}
165 on its final invocation, while \code{ensure-atomicity!} discards any such
166 values and returns nothing.
167
168\code{Ensure-atomicity} and \code{ensure-atomicity!} are macro versions of
169\code{call-ensuring-atomicity} and \code{call-ensuring-atomicity!}:
170\code{(ensure-atomicity \cvar{exp} \ldots)} expands into
171\code{(call-ensuring-atomicity (lambda () \cvar{exp} \ldots))}; likewise for
172\code{ensure-atomicity!} and \code{call-ensuring-atomicity!}.
173
174\begin{protos}
175\proto{provisional-car}{ pair}{value}
176\proto{provisional-cdr}{ pair}{value}
177\protonoresultnoindex{provisional-set-car!}{ pair value}\mainschindex{provisional-set-car"!}
178\protonoresultnoindex{provisional-set-cdr!}{ pair value}\mainschindex{provisional-set-cdr"!}
179\proto{provisional-cell-ref}{ cell}{value}
180\protonoresultnoindex{provisional-cell-set!}{ cell value}\mainschindex{provisional-cell-set"!}
181\proto{provisional-vector-ref}{ vector i}{value}
182\protonoresultnoindex{provisional-vector-set!}{ vector i value}\mainschindex{provisional-vector-set"!}
183\proto{provisional-string-ref}{ vector i}{char}
184\protonoresultnoindex{provisional-string-set!}{ vector i char}\mainschindex{provisional-string-set"!}
185\proto{provisional-byte-vector-ref}{ vector i}{k}
186\protonoresultnoindex{provisional-byte-vector-set!}{ vector i k}\mainschindex{provisional-byte-vector-set"!}
187\end{protos}
188\noindent
189These are all logging versions of their Scheme counterparts.
190Reads are checked when the current proposal is committed and writes are
191 delayed until the commit succeeds.
192If the current proposal is \code{\#f} these perform exactly as their Scheme
193 counterparts.
194
195The following implementation of a simple counter may not function properly
196 when used by multiple threads.
197\begin{example}
198(define (make-counter)
199  (let ((value 0))
200    (lambda ()
201      (set! value (+ value 1))
202      value)))
203\end{example}
204
205Here is the same procedure using a proposal to ensure that each
206 increment operation happens atomically.
207The value of the counter is kept in a
208cell (see section~\ref{cells})
209 to allow the use of
210 logging operations.
211\begin{example}
212(define (make-counter)
213  (let ((value (make-cell 0)))
214    (lambda ()
215      (ensure-atomicity
216        (lambda ()
217          (let ((v (+ (provisional-cell-ref value)
218                      1)))
219            (provisional-cell-set! value v)
220            v))))))
221\end{example}
222
223Because \code{ensure-atomicity} creates a new proposal only if there is
224 no existing proposal in place, multiple atomic actions can be merged
225 into a single atomic action.
226For example, the following procedure increments an arbitrary number of
227 counters at the same time.
228This works even if the same counter appears multiple times;
229 \code{(step-counters! c0 c0)} would add two to the value of counter \code{c0}.
230\begin{example}
231(define (step-counters! . counters)
232  (ensure-atomicity
233    (lambda ()
234      (for-each (lambda (counter)
235                  (counter))
236                counters))))
237\end{example}
238
239\begin{example}
240(define-synchronized-record-type \cvar{tag} \cvar{type-name}
241  (\cvar{constructor-name} \cvar{field-tag} \ldots)
242  [(\cvar \cvar{field-tag} \ldots)]
243  \cvar{predicate-name}
244  (\cvar{field-tag} \cvar{accessor-name} [\cvar{modifier-name}])
245  \ldots)
246\end{example}
247This is the same as \code{define-record-type}
248 except all field reads and
249 writes are logged in the current proposal.
250If the optional list of field tags is present then only those fields will
251 be logged.
252
253\begin{protos}
254\proto{call-atomically}{ thunk}{value(s)}
255\protonoresultnoindex{call-atomically!}{ thunk}\mainschindex{call-atomically"!}
256\syntaxproto{atomically}{ \cvar{exp} \ldots}{value(s)}
257\syntaxprotonoresultnoindex{atomically!}{ \cvar{exp} \ldots}\mainschindex{atomically"!}
258\end{protos}
259\noindent
260\code{Call-atomically} and \code{call-atomically!} are identical
261 to \code{call-ensuring-atomicity} and \code{call-ensuring-atomicity!} except that they
262 always install a new proposal before calling \code{thunk}.
263The current proposal is saved and then restored after \code{thunk} returns.
264\code{Call-atomically} and \code{call-atomically!} are useful if \code{thunk} contains
265 code that is not to be combined with any other operation.
266
267\code{Atomically} and \code{atomically!} are macro versions of
268\code{call-atomically} and \code{call-atomically!}:
269\code{(atomically \cvar{exp} \ldots)} expands into
270\code{(call-atomically (lambda () \cvar{exp} \ldots))}; likewise for
271\code{atomically!} and \code{call-atomically!}.
272
273% example?
274
275The following procedures and macro are intended primarily for use in
276 implementing new synchronization primitives or complex thread-safe data
277 structures.
278\begin{protos}
279\syntaxproto{with-new-proposal}{ (\cvar{lose}) \cvar{exp} \ldots}{value \ldots}
280\proto{maybe-commit}{}{boolean}
281\proto{proposal-active?}{}{boolean}
282\protonoresultnoindex{remove-current-proposal!}{}\mainschindex{remove-current-proposal"!}
283\protonoresultnoindex{invalidate-current-proposal!}{}\mainschindex{invalidate-current-proposal"!}
284\end{protos}
285\noindent
286\code{With-new-proposal} saves the current proposal, installs a new one,
287 executes the forms in the body, reinstalls the formerly current proposal,
288 and returns whatever the last body form returned.
289It also binds \cvar{lose} to a thunk repeating the procedure of installing
290 a new procedure and running the body.
291Typically, the body will call \code{maybe-commit} and, if that fails,
292 tail-call \cvar{lose} to try again.
293If \cvar{lose} is called from a non-tail position of the body, the results
294 are unspecified (and probably harmful).
295
296\code{Maybe-commit} verifies that any reads logged in the current proposal are
297 still valid and, if so, performs any writes that it contains.
298A logged read is valid if, at the time of the commit, the location read contains
299 the same value it had at the time of the original read (note that this does
300 not mean that no change occurred, simply that the value now is the same as
301 the value then).
302\code{Maybe-commit} returns \code{\#t} if the commit succeeds and \code{\#f}
303 if it fails.
304
305\code{Proposal-active?} returns \code{\#t} if a proposal is active, and
306 \code{\#f} otherwise.
307\code{Remove-current-proposal!} removes and discards the current proposal;
308 this can be used to clean up before raising an error.
309\code{Invalidate-current-proposal!} ensures that any attempt to commit the
310 current proposal will fail; this can be used if an operation on a
311 thread-safe data structure detects that it has seen the data structure in an
312 inconsistent state.
313
314
315
316The following procedures give access to the low-level proposal
317mechanism.  They are defined in the \code{low-proposals} structure.
318\begin{protos}
319\proto{make-proposal}{}{proposal}
320\proto{current-proposal}{}{proposal}
321\protonoresultnoindex{set-current-proposal!}{ proposal}\mainschindex{set-current-proposal"!}
322\end{protos}
323\noindent
324
325\code{Make-proposal} creates a new proposal.
326\code{Current-proposal} and \code{set-current-proposal} access and set
327 the current thread's proposal.
328It is an error to pass to \code{set-current-proposal!} a proposal that
329 is already in use.
330
331
332\section{Condition variables}
333\label{sec:condition-variables}
334% these require proposals
335
336\textit{Condition variables} (defined in the \code{condvars}
337structure) allow threads perform condition synchronization: It allows
338threads to block, waiting for a specified condition---associated with a
339condition variable---to occur, and other threads to wake up the waiting
340threads when the condition is fulfilled.
341
342Note that, in Scheme~48, condition variables work in conjunction with
343proposals, not with mutex locks or semaphores, as in most other
344implementations of this concept.
345
346\begin{protos}
347\proto{make-condvar}{}{condvar}
348\proto{make-condvar}{ id}{condvar}
349\proto{condvar?}{ thing}{boolean}
350\protonoresultnoindex{set-condvar-has-value?!}{ condvar boolean}\mainschindex{set-condvar-has-value?"!}
351\proto{condvar-has-value?}{ condvar}{boolean}
352\protonoresultnoindex{set-condvar-value!}{ condvar value}\mainschindex{set-condvar-value"!}
353\proto{condvar-value}{ condvar}{value}
354\proto{maybe-commit-and-wait-for-condvar}{ condvar}{boolean}
355\protonoindex{maybe-commit-and-set-condvar!}{ condvar value}{boolean}\mainschindex{maybe-commit-and-set-condvar"!}
356\end{protos}
357%
358\code{Make-condvar} creates a condition variable.  (The optional
359\cvar{id} argument is only for debugging purposes; the discloser for
360condition variables prints it out if present.)  \code{Condvar?} is the
361predicate for condition variables.
362
363Each condition variable has an associated value and a flag
364\code{has-value?} signalling if the condition has already occured.
365The accessor for flag is \code{condvar-has-value?};
366\code{set-condvar-has-value?!} sets it.  Both are provisional
367operations and go through the current proposal.
368\code{Set-condvar-value!} sets the value of the condition variable
369(provisionally), and \code{condvar-value} extracts it.
370
371\code{Maybe-commit-and-wait-for-condvar} attempts to commit the
372current proposal.  If the commit succeeds, it suspends the current
373thread and registers it with the \cvar{condvar} condition variable.
374Upon waking up again \code{maybe-commit-and-wait-for-condvar} returns
375\code{\#t}, If the commit fails, \code{maybe-commit-and-set-condvar}
376returns \code{\#f}.
377
378\code{Maybe-commit-and-set-condvar!} sets the value of the
379\cvar{condvar} condition variable to \cvar{value}, (provisionally)
380sets the \code{has-value?} flag to \code{\#t}, and then attempt to
381commit the current proposal.  Upon success, it wakes up all suspended
382threads registered with \cvar{condvar} and returns \code{\#t},
383otherwise, it returns \code{\#f}.
384
385\section{Mutual exclusion}
386
387Scheme~48 also has more traditional mutual-exclusion synchronization
388abstractions, specifically mutex locks and placeholders.  Note that
389typically synchronization via optimistic concurrency is usually
390preferable: Mutual exclusion often puts the running program into an
391inconsistent state for the time of the inclusion, which has adverse
392effects on modularity and interruptibility.
393
394\subsection{Locks}
395
396The \code{locks} structure contains bindings that implement standard
397mutex locks:
398%
399\begin{protos}
400\proto{make-lock}{}{lock}
401\proto{lock?}{ thing}{boolean}
402\protonoresult{obtain-lock}{ lock}
403\proto{maybe-obtain-lock}{ lock}{boolean}
404\protonoresult{release-lock}{ lock}
405\end{protos}
406%
407\code{Make-lock} creates a lock in the ``released'' state.
408\code{Lock?} is the predicate for locks.
409
410\code{Obtain-lock} atomically checks if \cvar{lock} is in the
411``released'' state.  If it is, the lock is put into the ``obtained''
412state, and \code{obtain-lock} returns immediately.  If the lock is in
413the ``obtained'' state, the current thread is suspended and registered
414with the lock.
415\code{Maybe-obtain-lock}, like \code{obtain-lock}, checks the state of
416\cvar{lock}: if it is ``released,'' the lock is put into the
417``obtained'' state, if it is ``obtained,'' \code{maybe-obtain-lock}
418returns immediately.  \code{Maybe-obtain-lock} returns \code{\#t} if
419it was able to obtain the lock, and \code{\#f} otherwise.
420
421\code{Release-lock} does nothing if \cvar{lock} is in the ``released''
422state.  If it is in the ``obtained'' state, \code{release-lock}
423causes one of the threads suspended on an \code{obtain-lock} lock
424operation to continue execution.  If that thread is the last thread
425registered with the lock, the lock is transferred to the ``released''
426state.  In any case, \code{release-lock} returns immediately.
427
428\subsection{Placeholders}
429\label{placeholders}
430
431The \code{placeholders} structure contains bindings for
432\textit{placeholders}---thread-safe, write-once variables, akin to
433ID-90 I-structures or CML I-variables.
434
435The typical scenario for placeholders is that, say, a thread~A
436computes a value needed by another thread~B at some unspecified time.
437Both threads share access to a placeholder; when A has computed the
438value, it places it into the placeholder.  When B needs the value, it
439extracts it from placeholder, blocking if necessary.
440%
441\begin{protos}
442\proto{make-placeholder}{}{placeholder}
443\proto{make-placeholder}{ id}{placeholder}
444\proto{placeholder?}{ thing}{boolean}
445\protonoresultnoindex{placeholder-set!}{ placeholder value}\mainschindex{placeholder-set"!}
446\proto{placeholder-value}{ placeholder}{value}
447\end{protos}
448%
449\code{Make-placeholder} creates an empty placeholder.  (The optional
450\cvar{id} argument is only for debugging purposes; the discloser for
451placeholders prints it out if present.)  \code{Placeholder?} is the
452predicate for placeholders.
453
454\code{Placeholder-set!} places a value into a placeholder.  Doing this
455more than once signals an error.  \code{Placeholder-value} extracts
456the value from the placeholder and returns it.  If the placeholder is
457empty, it blocks the current thread until it becomes full.
458
459
460
461\section{Writing custom synchronization abstractions}
462
463The bindings explained in this section are part of the
464\code{threads-internal} structure.  They are concerned with suspending
465threads and making them runnable again upon some later event.
466
467Typically, a suspended thread needs to be recorded in a queue
468somewhere for later waking-up.  To allow a thread to be recorded in
469multiple queues (say, when it waits for one of a number of events),
470such \textit{thread queues} are ordinary queues containing cells that,
471in turn, contain the thread objects themselves.  Each thread has at
472most one such cell associated with it which is shared among all queues
473(or other data structures) holding on to the suspended thread.  The
474cell is cleared when the thread is woken up.
475%
476\begin{protos}
477\proto{thread-queue-empty?}{ thread-queue}{boolean}
478\protonoindex{maybe-dequeue-thread!}{ thread-queue}{boolean}\mainschindex{maybe-dequeue-thread"!}
479\end{protos}
480%
481\code{Thread-queue-empty?} atomically checks whether the
482\cvar{thread-queue} thread queue is empty, i.e., if it does not
483contain non-empty cells.  \code{Maybe-dequeue-thread!} provisionally
484dequeues a thread from \cvar{thread-queue} if it contains one.  It
485returns the dequeued thread or \code{\#f} if the queue is empty.
486%
487\begin{protos}
488\proto{maybe-commit-and-block}{ cell}{boolean}
489\proto{maybe-commit-and-block-on-queue}{ thread-queue}{boolean}
490\proto{maybe-commit-and-make-ready}{ thread-or-queue}{boolean}
491\end{protos}
492%
493\code{Maybe-commit-and-block} attempts to commit the current proposal.
494If this succeeds, the current thread is blocked, the thread's cell is
495set to \cvar{cell}, and \code{\#t} is returned.  Otherwise, \code{\#f}
496is returned.  \code{Maybe-commit-and-block-on-queue} is like
497\code{maybe-commit-and-block}, excepts that it creates a fresh cell
498for the thread and enqueues it in \cvar{thread-queue} if the commit
499succeeds.
500
501\code{Maybe-commit-and-make-ready} accepts either a thread object or a
502thread queue as an argument.  In either case,
503\code{maybe-commit-and-make-ready} tries to commit the current
504proposal.  If that succeeds, \code{maybe-commit-and-make-ready}
505makes its argument runnable: if \cvar{thread-or-queue} is a thread,
506that thread is made runnable, if it is a thread queue, all threads on
507the queue are made runnable.  (In the latter case, none of the threads
508actually runs until all have been made runnable.)
509\code{Maybe-commit-and-make-ready} returns \code{\#t} if it succeeded,
510and \code{\#f} otherwise.
511
512% \section{Writing your own schedulers}
513
514\section{Concurrent ML abstractions}
515
516The interface to the Concurrent ML abstractions in Scheme~48 is
517mostly analogous to the original implementation shipped with
518SML/NJ~\cite{Reppy:CML-book}.  Note that both the interface and
519implementation are new and may change in future releases.
520
521The main terminological difference is that CML events are called
522\textit{rendezvous} in Scheme~48.  For more information on programming
523with the CML abstractions, Reppy's book~\cite{Reppy:CML-book} is
524recommended.
525
526\subsection{Basic rendezvous combinators}
527
528The basic rendezvous combinators live in the \code{rendezvous}
529structure.
530%
531\begin{protos}
532\constproto{never-rv}{rendezvous}
533\proto{always-rv}{ value}{rendezvous}
534\end{protos}
535%
536\code{Never-rv} is a rendezvous that is never enabled for
537synchronization.  (It is the same as the \code{never} event in CML.)
538\code{Always-rv} returns a rendezvous that is always enabled for
539synchronization, and always yields the same value \cvar{value}.  (This
540is the same as the \code{alwaysEvt} function in CML.)
541%
542\begin{protos}
543\proto{choose}{ rendezvous \ldots}{rendezvous}
544\end{protos}
545%
546\code{Choose} creates a rendezvous representing the choice of its
547arguments:  Synchronization on the resulting rendezvous will
548synchronize on one of the arguments to \code{choose}, depending on
549which becomes enabled first.  (This is the same as the \code{choose}
550function in CML.)
551%
552\begin{protos}
553\proto{wrap}{ rendezvous proc}{rendezvous}
554\end{protos}
555%
556\code{Wrap} wraps a post-synchronization procedure around \cvar{rendezvous}:
557When the resulting rendezvous is synchronized, \cvar{rendezvous} is
558synchronized, and the value it yields is passed to \cvar{proc}; the
559value returned by \cvar{proc} then is the result of the
560synchronization.  (This is the same as the CML \code{wrap} function.)
561%
562\begin{protos}
563\proto{guard}{ thunk}{rendezvous}
564\end{protos}
565%
566\code{Guard} delays the creation of a rendezvous until synchronization
567time: It returns a rendezvous that will, upon synchronization, turn
568into the rendezvous returned by \cvar{thunk}.  \code{Guard} can be
569used to perform pre-synchronization actions such as resource
570allocation.  (This is the same as the CML \code{guard} function.)
571%
572\begin{protos}
573\proto{with-nack}{ proc}{rendezvous}
574\end{protos}
575%
576\code{With-nack}, like \code{guard}, creates a delayed rendezvous: Upon
577synchronization, the rendezvous actually used is the one returned by
578\cvar{proc}.  In addition to the functionality offered by
579\code{guard}, \cvar{proc} receives, as an argument, another rendezvous
580which becomes enabled when \emph{another} rendezvous involved in the
581synchronization (via \code{choose}) is picked instead of the one
582produced by \cvar{proc}.  (This is the same as the CML \code{withNack}
583function.)
584%
585\begin{protos}
586\proto{sync}{ rendezvous}{value}
587\proto{select}{ rendezvous \ldots}{value}
588\end{protos}
589%
590\code{Sync} synchronizes the current thread on rendezvous
591\cvar{rendezvous}, returning the value it yields.  \code{Select}
592synchronizes on the choice of its argument; \code{(select $r_1$ \ldots
593  $r_n$)} is semantically equivalent to \code{(sync (choose select $r_1$ \ldots
594  $r_n$))}, but may be implemented more efficiently.  (These are the
595same as the CML functions \code{sync} and \code{select}.)
596
597\subsection{Synchronous channels}
598
599The \code{rendezvous-channels} structure contains abstractions for
600bidirectional, synchronous channels for communicating between two
601threads.
602%
603\begin{protos}
604\proto{make-channel}{}{channel}
605\proto{channel?}{ x}{boolean}
606\end{protos}
607%
608\code{Make-channel} creates a new synchronous channel.  (This is the
609same as the CML \code{channel} function.)  \code{Channel?} is the
610predicate for synchronous channels.
611%
612\begin{protos}
613\proto{send-rv}{ channel value}{rendezvous}
614\protonoresult{send}{ channel value}
615\end{protos}
616%
617\code{Send-rv} creates a rendezvous that, upon synchronization, sends
618message \cvar{value} on the synchronous channel \cvar{channel}.  The
619synchronization suceeds only when another thread attempts to receive a
620message from \cvar{channel}.  (This is the same as the CML
621\code{sendEvt} function.)  \code{Send} directly sends a message
622\cvar{value} on channel \cvar{channel}; \code{(send $c$ $v$)} is
623equivalent to \code{(sync (send-rv $c$ $v$))}.  (\code{Send} is the
624same as the CML \code{send} function.)
625%
626\begin{protos}
627\proto{receive-rv}{ channel}{rendezvous}
628\protonoresult{receive}{ channel}
629\end{protos}
630%
631\code{Receive-rv} creates a rendezvous which, upon synchronization,
632receives a message on channel \cvar{channel}.  (This is the same as
633the CML \code{recEvt} function.)  \code{Receive} directly
634receives a message on channel \cvar{channel}; \code{(receive $c$ $v$)} is
635equivalent to \code{(sync (receive-rv $c$ $v$))}.  (\code{Receive} is
636the same as the CML \code{recv} function.)
637
638\subsection{Synchronous variables}
639
640Two structures contain abstractions for synchronous variables: the
641\code{rendezvous-placeholders} structure for so-called
642\textit{placeholders} (write-once variables), and the
643\code{rendezvous-jars} structure for \textit{jars} (which allow
644multiple updates.)
645
646\subsubsection{Placeholders}
647%
648Placeholders are write-once variables.  The placeholders implemented
649by the \code{rendezvous-placeholders} structure offer equivalent
650functionality to the placeholders implemented by the
651\code{placeholders} structure (see Section~\ref{placeholders}), but
652additionally allow converting a placeholder into a rendezvous.  Note,
653however, that placeholders from \code{placeholders} are different from
654and not interchangeable with placeholders from
655\code{rendezvous-placeholders}.
656%
657\begin{protos}
658\proto{make-placeholder}{}{placeholder}
659\proto{make-placeholder}{ id}{placeholder}
660\proto{placeholder?}{ x}{boolean}
661\end{protos}
662%
663\code{Make-placeholder} creates an empty placeholder.  (The optional
664\cvar{id} argument is only for debugging purposes; the discloser for
665placeholders prints it out if present.)  (This is the same as the CML
666\code{iVar} function.)  \code{Placeholder?} is the predicate for
667placeholders.
668%
669\begin{protos}
670\protonoresultnoindex{placeholder-set!}{ placeholder value}\mainschindex{placeholder-set"!}
671\end{protos}
672%
673\code{Placeholder-set!} places a value into a placeholder.  Doing this
674more than once signals an error.  (This is the same as the CML
675\code{iPut} function.)
676%
677\begin{protos}
678\proto{placeholder-value-rv}{ placeholder}{rendezvous}
679\proto{placeholder-value}{ placeholder}{value}
680\end{protos}
681%
682\code{Placeholder-value} extracts the value from the placeholder and
683returns it.  If the placeholder is empty, it blocks the current thread
684until it becomes full.  (This is the same as the CML \code{iGet}
685function.)  \code{Placeholder-value-rv} creates a rendezvous that
686will, upon synchronization, extract the value from the placeholder
687and yield it as a result.  (This is the same as the CML \code{iGetEvt}
688function.)
689
690\subsubsection{Jars}
691
692A jar is a synchronous variable which can have two states: full and
693empty.  It becomes full when a value it put into it; putting a value
694into a full jar is an error.  Conversely, it becomes empty when a
695value is taken out of it.  Trying to take a value out of an empty jar
696blocks until it becomes full.  (Jars are similar to ID-90
697M-structures.)  Jars live in the \code{rendezvous-jars} structure.
698%
699\begin{protos}
700\proto{make-jar}{}{jar}
701\proto{make-jar}{ id}{jar}
702\proto{jar?}{ x}{boolean}
703\end{protos}
704%
705\code{Make-jar} creates an empty jar.  (The optional \cvar{id}
706argument is only for debugging purposes; the discloser for jars prints
707it out if present.)  (This is the same as the CML \code{mVar}
708function.)  \code{Jar?} is the predicate for jars.
709
710\begin{protos}
711\protonoresultnoindex{jar-put!}{ jar value}\mainschindex{jar-put"!}
712\end{protos}
713%
714\code{Jar-put!} places a value into a jar if it is empty.  Applying
715\code{jar-put!} to a full jar is an error.  (This is the same as the
716CML \code{mPut} function.)
717%
718\begin{protos}
719\proto{jar-take-rv}{ placeholder}{rendezvous}
720\proto{jar-take}{ placeholder}{value}
721\end{protos}
722%
723\code{Jar-take} takes a value from a full jar, emptying it in the
724process.  If the jar is empty, \code{jar-take} blocks until it becomes
725full.  (This is the same as the CML \code{mTake} function.)
726\code{Jar-take-rv} creates a rendezvous that, upon synchronization,
727will extract the value from a jar and empty it in the process.  (This
728is the same as the CML \code{mTakeEvt} function.)
729
730\subsection{Timeouts}
731
732The \code{rendezvous-time} structure allows creating rendezvous for
733alarms and timeouts:
734%
735\begin{protos}
736\proto{after-time-rv}{ milliseconds}{rendezvous}
737\proto{at-real-time-rv}{ time}{rendezvous}
738\end{protos}
739%
740\code{After-time-rv} creates a rendezvous that becomes enabled at time
741interval \cvar{milliseconds} after synchronization.  (Actually,
742\cvar{milliseconds} is a minimum waiting time; the actual delay may be
743longer.)  (This is the same as the CML \code{timeOutEvt} function.)
744\code{At-real-time-rv} creates a rendezvous that becomes enabled at an
745absolute time specified by \cvar{time}; this absolute time is
746specified in the same way as the return value \code{real-time} from
747the \code{time} structure.  (This is the same as the CML
748\code{atTimeEvt} function.)
749
750\subsection{CML to Scheme correspondence}
751
752The following table lists the Scheme names that correspond to
753particular CML names.
754
755\texonly\begin{longtable}{ll}\endtexonly
756\htmlonly\begin{tabular}{ll}\endhtmlonly
757  CML name & Scheme name\\\hline
758  \multicolumn{2}{c}{\code{rendezvous}}\\
759  \code{never} & \code{never-rv}\\
760  \code{alwaysEvt} & \code{always-rv}\\
761  \code{choose} & \code{choose}\\
762  \code{wrap} & \code{wrap}\\
763  \code{guard} & \code{guard}\\
764  \code{withNack} & \code{with-nack}\\
765  \code{sync} & \code{sync}\\
766  \code{select} & \code{select}\\[1ex]
767  \multicolumn{2}{c}{\code{rendezvous-channels}}\\
768  \code{channel} & \code{make-channel}\\
769  \code{sendEvt} & \code{send-rv}\\
770  \code{send} & \code{send}\\
771  \code{recEvt} & \code{receive-rv}\\
772  \code{rec} & \code{receive}\\[1ex]
773  \multicolumn{2}{c}{\code{rendezvous-placeholders}}\\
774  \code{iVar} & \code{make-placeholder}\\
775  \code{iPut} & \code{placeholder-set!}\\
776  \code{iGet} & \code{placeholder-value}\\
777  \code{iGetEvt} & \code{placeholder-value-rv}\\[1ex]
778  \multicolumn{2}{c}{\code{rendezvous-jars}}\\
779  \code{mVar} & \code{make-jar}\\
780  \code{mTake} & \code{jar-take}\\
781  \code{mTakeEvt} & \code{jar-take-rv}\\
782  \code{mPut} & \code{jar-put!}\\[1ex]
783  \multicolumn{2}{c}{\code{rendezvous-time}}\\
784  \code{timeOutEvt} & \code{after-time-rv}\\
785  \code{atTimeEvt} & \code{at-real-time-rv}
786\texonly\end{longtable}\endtexonly
787\htmlonly\end{tabular}\endhtmlonly
788
789
790%%% Local Variables:
791%%% mode: latex
792%%% TeX-master: "manual"
793%%% End:
794