Sussman and Steele | December 29, 1975 | 4 | The SCHEME Reference Manual |
- This is the synchronization primitive. It evaluates an expression uninterruptibly; i.e. no other process may run until the expression has returned a value. Note that if a
funarg
is returned from the scope of anEVALUATE!UNINTERRUPTIBLY
, then thatfunarg
will be uninterruptible when it is applied; that is, the uninterruptibility property follows the rules of variable scoping. For example, consider the following function:(DEFINE SEMGEN (LAMBDA (SEMVAL) (LIST (LAMBDA () (EVALUATE!UNINTERRUPTIBLY (ASET' SEMVAL (+ SEMVAL 1)))) (LABELS (P (LAMBDA () (EVALUATE!UNINTERRUPTIBLY (IF (PLUSP SEMVAL) (ASET' SEMVAL (- SEMVAL 1)) (P))))) P))))
This returns a pair of functions which are V and P operations on a newly created semaphore. The argument to
SEMGEN
is the initial value for the semaphore. Note that P busy-waits by iterating if necessary; becauseEVALUATE!UNINTERRUPTIBLY
uses variable-scoping rules, other processes have a chance to get in at the beginning of each iteration. This busy-wait can be made much more efficient by replacing the expression(P)
in the definition ofP
with((LAMBDA (ME) (BLOCK (START!PROCESS (CREATE!PROCESS '(START!PROCESS ME))) (STOP!PROCESS ME) (P))) **PROCESS**)
Let's see you figure this one out! Note that a
STOP!PROCESS
within anEVALUATE!UNINTERRUPTIBLY
forces the process to be swapped out even if it is the current one, and so other processes get to run; but as soon as it gets swapped in again, others are locked out as before.
Besides the AINT
s, SCHEME has a class of primitives known as AMACRO
s. These are similar to MacLISP MACRO
s, in that they are expanded into equivalent code before being executed. Some AMACRO
s supplied with the SCHEME interpreter:
COND
-
This is like the MacLISP
COND
statement, except that singleton clauses (where the result of the predicate is the returned value) are not allowed. AND
,OR
- These are also as in MacLISP.