com-metacircles-clim-sys-mp is a proposed Standard for a minimal MP/Threading interface. It's based on the CLIM-SYS interface, with the removal of some constructs that would not be reasonably implemented on OS-scheduled implementations, and the addition of POSIX-style condition variables.

Current state: 0.1 Rename make-condition to make-condition-variable 0.2 Add optional timeout argument to condition-wait

Summary of differences from CLIM-SYS -

  • deleted process-state and process-whostate, as there was no explanation of what they do anyway

  • deleted process-wait, process-wait-with-timeout, process-interrupt, disable-process, enable-process process restart-process, without-scheduling as being probably not sensibly implementable in a OS-scheduled thread implementation

Terminology note: to remain consistent with the vocabulary of existing Lisp environments, the term process as used here describes a context of execution which shares its Lisp environment with other such processes. This is not the concept of a process in some operating systems (e.g. Unix, NT) in which each OS process has an independent address space and cannot access or alter objects in other processes. What we call a "process" here is typically known as a "thread" in those circles.

Processes (in the Lisp sense) may be implemented using whatever applicable techniques are provided by the operating system: user-space scheduling, kernel-based LWPs or anything else that does the job.

*multiprocessing-p* [Variable]

The value of *multiprocessing-p* is t if the current Lisp environment supports multi-processing, otherwise it is nil .

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.

Initial values of special variables in the new process are the same as in the process that called make-process. It may rebind special variables: the new bindings are local to that thread. The effect of assigning to these variables without rebinding them is implementation-defined.

Just to be explicit: lexical scope is shared, correct? -- Nikodemus

destroy-process process [Function]

Terminates the process process . process is an object returned by make-process. This should be used with caution in portable code: it is implementation-defined whether the process's cleanup forms run, or whether it releases locks that it may be holding.

How much implementation trouble would it cause to require the cleanup forms to run? I guessing a fair deal: in which case some way to query the implementation about it's behaviour would be nice. -- Nikodemus

current-process [Function]

Returns the currently running process, which will be the same kind of object as would be returned by make-process .

all-processes [Function]

Returns a sequence of all of the processes.

processp object [Predicate]

Returns t if object is a process, otherwise returns nil .

process-name process [Function]

Returns the name of the process, as given to make-process

process-yield [Function]

Allows other processes to run. On systems that do not support multi-processing, this does nothing.

atomic-incf reference [Function] atomic-decf reference [Function]

Increments (or decrements) the fixnum value referred to by reference as a single, atomic operation. If the operation would take the value out of fixnum range, behaviour is undefined.

make-lock &optional name [Function]

Creates a lock whose name is name . On systems that do not support locking, this will return a new list of one element, nil .

with-lock-held (place &optional state) &body body [Macro]

Evaluates body with the lock named by place. place is a reference to a lock created by make-lock .

[ Should we add a timeout argument to this? ]

On systems that do not support locking, with-lock-held is equivalent to progn .

make-recursive-lock &optional name [Function]

Creates a recursive lock whose name is name . On systems that do not support locking, this will return a new list of one element, nil . A recursive lock differs from an ordinary lock in that a process that already holds the recursive lock can call with-recursive-lock-held on the same lock without blocking.

with-recursive-lock-held (place &optional state) &body body [Macro]

Evaluates body with the recursive lock named by place . place is a reference to a recursive lock created by make-recursive-lock .

On systems that do not support locking, with-recursive-lock-held is equivalent to progn .

[ Ditto timeout question here ]

make-condition-variable () [function]

Returns a new condition-variable object for use with condition-wait and condition-notify.

condition-wait (condition-variable lock &optional timeout) [function]

Atomically release LOCK and enqueue ourselves waiting for CONDITION-VARIABLE. The process will continue running when another thread has notified us using CONDITION-NOTIFY, or we are interrupted, or the timeout expires: in every case we always reacquire LOCK before returning to the caller. It is an error to call this unless from the thread that holds LOCK.

condition-notify (condition-variable) [function]

Notify one or more of the processes waiting for CONDITION-VARIABLE