|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 an
EVALUATE!UNINTERRUPTIBLY, then that funarg 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
SEMGENis the initial value for the semaphore. Note that P busy-waits by iterating if necessary; because
EVALUATE!UNINTERRUPTIBLYuses 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 of
((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
EVALUATE!UNINTERRUPTIBLYforces 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.
AINTs, SCHEME has a class of primitives known as
AMACROs. These are similar to MacLISP
MACROs, in that they are expanded into equivalent code before being executed. Some
AMACROs supplied with the SCHEME interpreter:
- This is like the MacLISP
CONDstatement, except that singleton clauses (where the result of the predicate is the returned value) are not allowed.
- These are also as in MacLISP.