Update of /usr/local/src/cvs/bordeaux-mp
In directory loaclhost.telent.net:/tmp/cvs-serv15887
Modified Files:
Specification
Log Message:
Many edits in response to feedback from Robert Strandh
- Rewrite section on special variables to specify what happens to
variables which only have global bindings
- do we really want/need atomic-{inc,dec}f?
- general attention to detail re: return values and arguments
for many functions
- replaced 'thread' with 'process' in more than a few places
- some notes on condition variables, but I think that bit needs
rewriting again.
Also note that the object returned by all-processes may not be safe to
mutate.
Index: Specification
===================================================================
RCS file: /usr/local/src/cvs/bordeaux-mp/Specification,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- Specification 12 Jul 2004 01:22:01 -0000 1.4
+++ Specification 12 Jul 2004 18:45:15 -0000 1.5
@@ -40,7 +40,7 @@
that does not support multiple processes. Process creation and some
process inspection operations will not work, but the locking functions
are still present (though they may do nothing) so that thread-safe
-code can be compiled on both threaded and single-thread
+code can be compiled on both multiprocess and single-process
implementations without need of conditionals.
To avoid conflict with existing MP/threading interfaces in
@@ -52,19 +52,43 @@
make-process function &key name [Function]
-Creates a process named NAME. The new process will evaluate the
-function FUNCTION. On systems that do not support multi-processing,
-make-process will signal an error.
+Creates and returns a process named NAME, which will call the function
+FUNCTION with no arguments: when FUNCTION returns, the process
+terminates. NAME defaults to NIL if unsupplied.
+
+On systems that do not support multi-processing, MAKE-PROCESS will
+signal an error.
+
+The interaction between processes and dynamic variables is in some
+cases complex, and depends on whether the variable has only a global
+binding (as established by e.g. DEFVAR/DEFPARAMETER/top-level SETQ)
+or has been bound locally (e.g. with LET or LET*) in the calling
+process.
+
+ - Global bindings are shared between threads: the initial value of a
+ global variable in the new thread will be the same as in the
+ parent, and an assignment to such a variable in any thread will be
+ visible to all threads in which the global binding is visible.
+
+ - Local bindings are local to the thread they are introduced in,
+ except that
+
+ - Local bindings in the the caller of MAKE-PROCESS may or may not be
+ shared with the new process that it creates: this is
+ implementation-defined. Portable code should not depend on
+ particular behaviour in this case, nor should it assign to such
+ variables without first rebinding them in the new process.
*default-special-bindings*
This variable holds an alist associating special variable symbols with
forms to evaluate for binding values. Special variables named in this
-list will be locally bound in the new process.
+list will be locally bound in the new process before it begins
+executing user code.
-This may be rebound around calls to MAKE-PROCESS to add/alter default
-bindings. The effect of mutating this list is undefined, but earlier
-forms take precedence over later forms for the same symbol, so
+This variable may be rebound around calls to MAKE-PROCESS to add/alter
+default bindings. The effect of mutating this list is undefined, but
+earlier forms take precedence over later forms for the same symbol, so
defaults may be overridden by consing to the head of the list.
[ Forms are evaluated in the new thread or in the calling thread? ]
@@ -72,15 +96,6 @@
[ Standard contents of this list: print/reader control, etc. Can
borrow the franz equivalent? ]
-Initial values of other special variables are implementation-defined.
-For example, they may be the same as in the process that called
-make-process, or set from the global values of the variables.
-
-The new thread may rebind special variables: the new bindings are
-local to that thread. If it assigns to special variables that have
-not been bound (either at process creation time or subsequently), the
-effect is implementation-defined.
-
current-process [Function]
Returns the process object for the calling process. This is the same
@@ -104,6 +119,9 @@
as a single, atomic operation. If the operation would take the value
out of fixnum range, behaviour is undefined.
+[ do we really want these? is a reference a place? what's the return
+value? shouldn't they be macros anyway?]
+
* Resource contention: locks and recursive locks
make-lock &optional name [Function]
@@ -118,8 +136,11 @@
acquire-lock lock &optional (wait-p t) [Function]
-Acquire the lock LOCK for the calling process. If the lock is not
-available, and if WAIT-P is non-NIL, wait until it is.
+Acquire the lock LOCK for the calling process. WAIT-P governs what
+happens if the lock is not available: if WAIT-P is true, the calling
+process will wait until the lock is available and then acquire it; if
+WAIT-P is NIL, ACQUIRE-LOCK will return immediately. ACQUIRE-LOCK
+returns true if the lock was acquired and NIL otherwise.
This specification does not define what happens if a process attempts
to acquire a lock that it already holds. For applications that
@@ -133,24 +154,27 @@
other processes are waiting for the lock, the ACQUIRE-LOCK call in
one of them will now be able to continue.
+This function has no interesting return value.
+
with-lock-held (place) &body body [Macro]
-Evaluates BODY with the lock named by PLACE, which is a reference to a
-lock created by MAKE-LOCK. The lock will still be released even if a
-non-local control transfer (e.g. by THROW or SIGNAL) is signalled, but
-note that if the debugger is entered, the lock may only be released
-/after/ execution has been restarted.
+Evaluates BODY with the lock named by PLACE, the value of which is a
+lock created by MAKE-LOCK. Before the forms in BODY are evaluated,
+the lock is acquired as if by using ACQUIRE-LOCK. After the forms in
+BODY have been evaluated, or if a non-local control transfer is caused
+(e.g. by THROW or SIGNAL), the lock is released as if by RELEASE-LOCK.
-If the process is unable to acquire the lock, BODY will not be
-evaluated.
+Note that if the debugger is entered, it is unspecified whether the
+lock is released at debugger entry or at debugger exit when execution
+is restarted.
make-recursive-lock &optional name [Function]
-Creates a recursive lock whose name is NAME. A recursive lock differs
-from an ordinary lock in that a process that already holds the
-recursive lock can acquire it again without blocking. The process
-must then release the lock twice before it becomes available for
-another process.
+Create and return a recursive lock whose name is NAME. A recursive
+lock differs from an ordinary lock in that a process that already
+holds the recursive lock can acquire it again without blocking. The
+process must then release the lock twice before it becomes available
+for another process.
acquire-recursive-lock lock [Function]
@@ -174,6 +198,8 @@
some event. When the event occurs, the queue will be notified,
causing one or more of the stopped processes to be resumed.
+[ It's not a queue really ]
+
Condition variables are used to signal events when the state of some
shared resource changes: for example, consider a buffer with readers
and a writer, where the readers can only run when there is data in the
@@ -191,14 +217,15 @@
condition-wait (condition-variable lock) [function]
Atomically release LOCK and enqueue the calling process waiting for
-CONDITION-VARIABLE. The process will resume when another thread has
-notified it using CONDITION-NOTIFY, or we are interrupted, or in other
-implementation-dependent circumstances: the caller must always test
-on waking that it can proceed, before continuing normal processing.
+CONDITION-VARIABLE. The process will resume when another process has
+notified it using CONDITION-NOTIFY; it may also resume if interrupted
+by some external event or in other implementation-dependent
+circumstances: the caller must always test on waking that it can
+proceed, before continuing normal processing.
However and for whatever reason the process is resumed, the system
always reacquires LOCK before returning to the caller. It is an error
-to call this unless from the thread that holds LOCK.
+to call this unless from the process that holds LOCK.
In an implementation that does not support multiple processes, this
function signals an error.
@@ -209,6 +236,10 @@
The caller needs to acquire the lock associated with the condition
variable before calling this.
+[ wake-one vs wake-all: when does >1 process get woken ]
+
+
+
In an implementation that does not support multiple processes, this
function has no effect.
@@ -229,7 +260,8 @@
all-processes [Function]
-Returns a sequence of all of the processes.
+Returns a sequence of all of the processes. This may or may not be
+freshly-allocated, so the caller should not modify it.
process-interrupt process function [Function]