ToC | DocOverview | CGDoc | RelNotes | FAQ | Index | PermutedIndex
| Allegro CL version 11.0

# barrier-arriver-count

Generic Function, multiprocessing package

Arguments: barrier

When barrier is a barrier object, return the number of threads that have reached the barrier at this moment.

See Barrier API in smp.html.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# barrier-change-count

Generic Function, multiprocessing package

Arguments: barrier new-count

When barrier is a barrier object, equivalent to barrier-set-count. (There are two names for this method for historic reasons.)

See Barrier API in smp.html.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# barrier-disable

Generic Function, multiprocessing package

Arguments: barrier &optional kill-waiting

When barrier is a barrier object,, equivalent to

      (barrier-unblock barrier :disable t :kill-waiting kill-waiting))

See barrier-unblock.

See Barrier API in smp.html.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# barrier-enable

Generic Function, multiprocessing package

Arguments: barrier &optional kill-waiting

When barrier is a barrier object, equivalent to

      (barrier-unblock barrier
        :disable nil :reset-count count :kill-waiting kill-waiting))

See barrier-unblock.

See Barrier API in smp.html.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# barrier-name

Generic Function, multiprocessing package

Arguments: barrier

When barrier is a barrier object, returns the name of the argument.

See Barrier API in smp.html.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# barrier-pass-through

Generic Function, multiprocessing package

Arguments: barrier

When barrier is a barrier object, equivalent to `(barrier-wait barrier :pass-through t)`. See barrier-wait.

See Barrier API in smp.html.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# barrier-set-count

Generic Function, multiprocessing package

Arguments: barrier new-count

When barrier is a barrier object, sets the value of the barrier count. The new-count argument may be a positive integer (and may not be zero), or `t` to denote most-positive-fixnum.

If the barrier is disabled, simply update the count and leave the barrier disabled.

If the barrier is enabled but still below the new-count, then simply update the count.

Otherwise the call is eqivalent to `(barrier-unblock barrier :reset-count new-count)`. See barrier-unblock.

See Barrier API in smp.html.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# barrier-unblock

Generic Function, multiprocessing package

Arguments: barrier &key disable reset-count kill-waiting

The method when barrier is a barrier object is as folows. The disable argument overrides the value of the disable-on-unblock slot in the barrier instance. If the disable argument (or slot) is non-`nil`, the barrier is disabled, otherwise leave the barrier enabled with an arriver-count of zero.

If the reset-count argument is a positive integer or `t`, set the count in the barrier to the new value.

If kill-waiting is non-`nil`, kill any threads currently waiting at the barrier.

Finally, release any threads still waiting at the barrier.

See Barrier API in smp.html.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# barrier-wait

Generic Function, multiprocessing package

Arguments: barrier &key timeout callback pass-through discount-on-abort discount-on-timeout disable-on-unblock

The method when barrier is a barrier object is as follows.

If the barrier (a barrier instance) is disabled when this function is called, then it returns `nil` immediately, and all the other arguments are ignored.

Otherwise, this is an arrival at the barrier. If this arrival is not the last, then increment the arriver-count and either pass through or block. If the pass-through argument was non-`nil`, then return `:passed-through`; otherwise block until the barrier count is reached, or the timeout expires. If the timeout expires. return `:timeout`, otherwise return `t`.

If this arrival is the last, then optionally call the callback function, unblock the barrier, and return `:unblocked`.

The callback, discount, and disable arguments, override the corresponding slots in the barrier instance.

See Barrier API in smp.html.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# cancel-process-pool-work

Function, multiprocessing package

Arguments: &rest reason-and-values

This function stops executing a `report-start` function or a work-item work function without killing the process-pool process running the work item (as cancel-process-pool-worker does).

When called from the body of a `report-start` function, the report-start function exits immediately and the work function is not called. The `report-end` function is called.

When called from the body of a work-item work function, the work function exits immediately and then the `report-end` function is called.

In either case, if any reason-and-values arguments are supplied, the first is saved in the `error` slot of work-item and a list of the remaining arguments is stored in the `values` slot.

When called in any other context, including in a `report-end` function, this function returns `nil` but does nothing else. The reason-and-values arguments, if any, are ignored.

See Process pools in multiprocessing.html for more information on process pools.

# cancel-process-pool-worker

Function, multiprocessing package

Arguments: &optional reason

When called from the body of a process-pool-work-item worker function or from the body of a report-start or report-end function (see process-pool-report-start and process-pool-report-end), the ultimate effect is to terminate the worker process. If a work-item is present (see mp:process-pool-run), the reason argument is saved in the error slot of the work-item.

When called in a report-start function while a work-item is being run, the report-start function exits immediately, the work function is not called, and the report-end function is called. When called in the work function, the work function exits immediately and the report-end function is called. When called in a report-end function, that function exits immediately.

When called in any other context, this function returns `nil` but does nothing else.

The related function cancel-process-pool-work stops running the `report-start` function or the work-item work function but does not kill the process-pool process running the work-item. That function called in a `report-end` function does nothing except return `nil`.

See Process pools in multiprocessing.html for more information on process pools.

# close-gate

Function, multiprocessing package

Arguments: gate

The gate argument must have been allocated with make-gate. Makes the state of gate closed.

See Gates in multiprocessing.html for more information. See also make-gate, open-gate, and gate-open-p.

# condition-variable-broadcast

Function, multiprocessing package

Arguments: condvar

Awaken all the processes waiting for a signal. Returns `t` if at least one process was awakened by the signal. Returns `nil` if no processes were waiting.

Any condition-variable-wait calls that are initiated after the call to condition-variable-broadcast begins will not be affected by the broadcast.

See Condition Variables in smp.html.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# condition-variable-signal

Function, multiprocessing package

Arguments: condvar

Returns `t` if a waiting process was awakened by the signal. Returns `nil` if no processes were waiting.

See Condition Variables in smp.html.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# condition-variable-wait

Function, multiprocessing package

Arguments: condvar lock &key timeout

The lock is released and the thread waits for the condition to be signaled. When the condition is signaled, the lock is re-aquired before returning to the caller. The calling program should then release the lock so that other threads may modify the data.

The lock argument must be an instance of mp:process-lock or mp:sharable-lock, and the lock must be owned by the calling thread. A sharable-lock instance must be owned in exclusive mode. If the lock is not owned or cannot be unlocked, an error is signaled.

The lock may also be `nil`. In that case, no unlocking or re-aquiring is done. This can be sufficient in very simple cases where the data is modified with atomic operations.

The timeout argument may be `nil` or a positive number of seconds to wait for the condition signal. A zero or negative timeout value will always return `nil` since a condition is signaled only if some thread is actually waiting for the signal.

The lock is re-aquired whether a signal is received or a timeout occurs.

The condition represented by the condition-variable which is the value of the condvar argument. The condition should be checked again when condition-variable-wait returns and the lock is re-aquired since the situation may have changed between the signal and the return. A non-`nil` result from condition-variable-wait indicates only that the condition was signaled once in the past; it does not say anything about the state of the condition at the moment. Checking the condition while holding the lock is needed to get a definitive answer.

Returns `t` if the condition was signalled; nil if timeout occurred first.

See Condition Variables in smp.html.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# condition-variable-wait-count

Function, multiprocessing package

Arguments: condvar

Returns the number of Lisp processes waiting for the condition variable condvar. Note that this is a very ephemeral value.

See Condition Variables in smp.html.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# dequeue

Generic Function, multiprocessing package

Arguments: queue &key wait empty-queue-result whostate

Removes the object at the head of the queued sequence queue, that is, the one that has been queued the longest, and returns that object.

If queue is empty, then the result depends on the values of the wait and empty-queue-result keyword arguments.

- If wait is `nil` (the default), then an error is signaled.

- If wait is a real number, then dequeue waits up to that many seconds for an item to be available from the queue. If an item is retrieved within that time interval, it is returned, otherwise the empty-queue-result value (default `nil`) is returned. A wait value of 0 immediately returns either a retrieved queue element or the empty-queue-result value.

- If wait is a non-real non-`nil` value then the process waits until it can successfully dequeue an object from the queue. In this case the empty-queue-result argument is ignored.

The predefined method is for the queue class.

The function queue-empty-p indicates whether the queue is empty or not (but the returned value cannot be depended upon if other processes are operating on the queue).

Interlocks ensure that no entry in the queue will be retrieved by more than one process (once the dequeuing starts, it will complete). If the process does wait, its whostate will be set from the whostate keyword argument, which defaults to the string "dequeue".

See Queues in multiprocessing.html for more information.

# discard-process-pool

Generic Function, multiprocessing package

Arguments: pool &key forget kill

This function returns `nil` after deleting the argument process-pool.

pool can be `nil` (indicating the default process-pool, see ensure-default-process-pool) or a process-pool object.

If the default process pool is deleted, there will be no default process pool available until ensure-default-process-pool is called (and so forms like `(process-pool-run nil ...)`, which try to run a process in the default pool, will fail):

    cl-user(34): (ensure-default-process-pool)
    #&lt;process-pool @ #x100034f0272>
    cl-user(35): (process-pool-run nil :function 'foo)
    :created
    cl-user(36): (discard-process-pool nil)
    nil
    cl-user(37): (process-pool-run nil :function 'foo)
    Error: There is no default process pool.

### The keyword arguments:

- forget: If non-`nil`, discard any work-items in the queue. If `nil` (the default), signal a continuable error if there are work-items in the queue.

- kill: If non-`nil`, kill any active processes still running. If `nil` (the default), leave any active processes to run to the end of their current task.

See Process pools in multiprocessing.html for more information on process pools.

# discard-process-pool-work-item

Generic Function, multiprocessing package

Arguments: work-item &key kill wait reason

This generic function allows users to stop a work-item launched with process-pool-run. As with other operators that cancel or stop running work items (cancel-process-pool-work and cancel-process-pool-worker), there is flexibility about whether to actually kill the running work item function or to let it complete and then do some clean up.

The work-item argument must be a process-pool-work-item. The kill keyword argument can be `t`, `nil`, or a function name or object. The function must run with no arguments. reason is a symbol or string which will be added to the work-item's `error` slot. It defaults to `:discard-work-item`. The wait argument can be `t` (or a non-`nil` value that is not a number), `nil`, or a number.

Here are the various cases:

### The work-item is neither running nor on a process-pool queue

The work-item may have completed running or may never have been added to a process-pool queue, either because the queue was full when process-pool-run was called or because the work-item was created with make-process-pool-work-item and never assigned to a process-pool. In either case, discard-process-pool-work-item takes no action other than returning `:idle`.

### The work-item is in a process-pool queue but is not running

The work-item is removed from the queue and discard-process-pool-work-item returns `:dequeued`.

### The work-item is running

'Running' means one of the three functions associated with the work-item (the `report-start` function, the work-item `function`, and the `report-end` function) is executing or about to execute. What happens depends on the value of the kill. The value of the wait argument is ignored when kill is either `t` or `nil`.

kill can be `t`, `nil`, or a function designator naming a function that will run with no arguments. Here are the effects of those values:

- kill is `t`: the effect is equivalent to calling cancel-process-pool-work in the work-item function or one of the report functions, whichever happens to be running at the time of the interrupt. Also, the work-item's `error` slot is set to the value of the reason keyword argument (default `:discard-work-item`), and the single value `:killed` is returned.

- kill is `nil`: the work-item is left running. discard-process-pool-work-item returns two values: `nil` and `:running`.

- kill is a function designator: this function is used as the interrupt function to mp:process-interrupt, that is, this form is evaluated:

      (mp:process-interrupt the-process-running-work-item the-value-of-kill)

  What happens next depends on the value of the wait argument. If wait is `nil`, discard-process-pool-work-item returns two values: `nil` and `:interrupted`. If wait is non-`nil` but not a number, wait until the work-item function exits and discard-process-pool-work-item returns `:killed`. If wait is a number, wait up that number of seconds. If the work-item function completes, discard-process-pool-work-item returns `:killed`; if the work-item function does not complete, discard-process-pool-work-item returns `nil` and `:running`.

See Process pools in multiprocessing.html for more information on process pools.

# do-periodically

Macro, multiprocessing package

Arguments: (seconds &key sleep-first (whostate "sleeping")) &body body

After evaluating seconds, sleep-first, and whostate (in that order), this macro repeatedly executes body while sleeping for seconds seconds between each execution. It expands into code which roughly produces the following inner loop (the actual macroexpansion is much more complicated):

       (if sleep-first (sleep seconds))
       (loop
          body
          (sleep seconds))

seconds must evaluate to a non-negative real number; sleep-first is a boolean defaulting to `nil`; whostate must evaluate to a string or `nil`. whostate defaults to "sleeping".

The purpose of this macro is to reduce consing when executing the same code repeatedly with sleeps in between. Because seconds, sleep-first, and whostate are only evaluated once, all additional consing comes from the evaluation of body and if body itself does not cons, there is no additional consing.

If sleep-first is true, the executing thread/process will sleep before the first executaion of body. If sleep-first is `nil` (the default), the thread will execute body immediately and then sleep.

The whostate of the thread/process will be changed to whostate while the thread/process is sleeping (while executing body, the whostate of the thread/process will be its original whostate -- see process-whostate).

This macro does not return of its own accord, but the execution of body is wrapped in a block named `nil`, so `(return)` will jump out of the loop (returning `nil`) and `(return &lt;form>)` will jump out of the loop returning the value of `&lt;form>` (see return).

### Example

    ;; The following example shows how this macro reduces
    ;; consing (run in Allegro CL 10.1 SMP on a Linux platform):

    (defun ltest1 ()
      (let ((ct 1000))
        (loop
          (sleep .1)
          (decf ct)
          (when (&lt;= ct 0)
        (return)))))

    (defun ltest2 ()
      (let ((ct 1000))
        (mp:do-periodically (.1 :sleep-first t)
          (decf ct)
          (when (&lt;= ct 0)
        (return)))))

    cl-user(12): (time (ltest1))
    ; cpu time (non-gc) 0.054992 sec user, 0.052992 sec system
    ; cpu time (gc)     0.001000 sec user, 0.000000 sec system
    ; cpu time (total)  0.055992 sec user, 0.052992 sec system
    ; cpu time (thread) 0.037994 sec user, 0.022997 sec system
    ; real time  100.182389 sec (00:01:40.182389) (.1088%)
    ; space allocation:
    ;  2,000 cons cells, 577,136 other bytes, 0 static bytes
    ; Page Faults: major: 0 (gc: 3), minor: 3 (gc: 3)
    nil
    cl-user(13): (time (ltest2))
    ; cpu time (non-gc) 0.045993 sec user, 0.046993 sec system
    ; cpu time (gc)     0.000000 sec user, 0.000000 sec system
    ; cpu time (total)  0.045993 sec user, 0.046993 sec system
    ; cpu time (thread) 0.020997 sec user, 0.025996 sec system
    ; real time  100.171188 sec (00:01:40.171188) (.0928%)
    ; space allocation:
    ;  2 cons cells, 368 other bytes, 0 static bytes
    ; Page Faults: major: 0 (gc: 0), minor: 0 (gc: 0)
    nil

    ;; The times are roughly the same but cons cells and other bytes
    ;; are significantly reduced with DO-PERIODICALLY.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# enqueue

Generic Function, multiprocessing package

Arguments: queue data

Adds data to the end of the sequence of objects waiting in the queue queue. data may be any Lisp object. The predefined method is for queue that is an instance of the queue class.

See Queues in multiprocessing.html for more information.

# ensure-default-process-pool

Function, multiprocessing package

Arguments: &key if-exists if-does-not-exist forget kill* [make-process-pool and set-process-pool keyword arguments]

There is no default process-pool when Lisp is started. Calling this function before the first attempt to use the default process-pool will create the initial default process-pool. (Trying to use it prior to calling this function, by, say, evaluating `(process-pool-run nil ...)` will cause and error to be signaled.)

That process pool may itself later be deleted by user action (such as calling discard-process-pool). In any case, when this function returns there will be a default process-pool.

The default process-pool is the process-pool that is used when a process-pool operator (such as process-pool-run) is called with `nil` as the value of the pool argument.

If the default process-pool exists when this function is called, the behavior depends on the value of the if-exists keyword argument. The possible values are:

- `:supersede`: Discard the current default process-pool (with discard-process-pool) and create a new one (with make-process-pool). The forget and kill keyword argument values are passed to discard-process-pool. Keyword arguments other than forget, kill, if-exists, and if-does-not-exist are passed on to make-process-pool.

- `:cerror`: Signal a continuable error. Replace the current default process-pool if that continuation is chosen.

- `:error`: Signal an error.

- Any other value: Keep and return the current default process-pool after applying set-process-pool to it, called with any set-process-pool keyword arguments passed to ensure-default-process-pool. This is the default behavior.

If no default process-pool exists when this function is called, the behavior depends on the value of the if-does-not-exist keyword argument. The possible values are:

- `:create`: Create and return a new process-pool, made with make-process-pool called with any make-process-pool keyword arguments passed to ensure-default-process-pool. This is the default behavior.
- Any other value: Signal a simple error.

See Process pools in multiprocessing.html for more information on process pools.

# exclusive-locker-count

Generic Function, multiprocessing package

Arguments: sharable-lock &optional clean-p

Query the exclusive state of a sharable-lock instance.

The returned value is zero if the lock is not owned by an exclusive user at the moment of the call.

The returned value is 1, if an exclusive user is active or pending at the moment of the call.

The returned value is 2, if an exclusive user is active and another pending at the moment of the call.

The clean-p has effect only to sharable-lock instances created with the auto-unlock-p to make-sharable-lock specified true (the default value is `nil`). In that case, when the clean-p argument is non-`nil`, the current owners of the lock are scanned to remove any dead processes associated with the lock. The returned count is the number of live processes associated with the lock.

Note that this value may be obsolete and incorrect as soon as it is returned.

See Sharable locks in smp.html.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# find-process

Function, multiprocessing package

Arguments: string

Searches the processes on *all-processes* for one whose name contains the string argument, using case-insensitive search. If there is a unique process that satisfies the test then that process is returned. If there is no process that satisfies the test, `nil` is returned. If there are multiple processes that satisfy the test, an error is signaled.

find-process is designed for forms typed to a listener prompt, such as:

    (process-interrupt (find-process "just-enough") #'interrupter)

If find-process does not find a unique process or any process, it errors rather thsn possibly doing the wrong thing (errors at the top level are easily handled, find-process is not really designed to be used in application code).

See also process-name-to-process. See multiprocessing.html for general information on multiprocessing.

# gate-open-p

Function, multiprocessing package

Arguments: gate

The gate argument must have been allocated with make-gate. Returns true if gate's state is open and returns `nil` if it is closed.

As described in the documentation for gates linked to below, gate-open-p is handled specially by process-wait, and so code which uses gates runs more efficiently. The speedup can be significant if the process often waits.

See Gates in multiprocessing.html for more information. See also make-gate, open-gate, and close-gate.

# get-semaphore

Function, multiprocessing package

Arguments: gate

Gates can be used as semaphores. Each gate created by make-gate has an associated semaphore count that starts at 0. get-semaphore waits, if necessary, until the gate's count is greater than 0 and then decrements the count. If this makes the count 0, the gate is then closed, as well. Using get-semaphore and put-semaphore can be more efficient than using a generic process lock when mediating access to a work queue processed by several threads. mp:enqueue and mp:dequeue use semaphores internally to get the improved efficiency. See put-semaphore.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# lockedp

Generic Function, multiprocessing package

Arguments: lock &optional force-memory-synch

Returns `t` if the lock is held by anyone, `nil` if it is free.

lock must be an instance of lockable-object or of a subclass of lockable-object, or an instance of excl::lockable-structure or of a structure class that inherits from excl::lockable-structure.

If the force-memory-synch argument is present and non-`nil`, a memory synchronization operation will be used to ensure that an out-of-date cached state is not erroneously consulted to determine the answer.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# make-barrier

Function, multiprocessing package

Arguments: count &key discount-on-abort discount-on-timeout callback disable-on-unblock name

Returns a freshly created barrier instance.
The new barrier is in the enabled state with an arriver-count of zero. The expected count is determined by the count argument which must be an integer greater than zero or `t`. If `t` is specified, the count is set to most-positive-fixnum; such a barrier will effectively block until it is explicitly unblocked by a call to barrier-unblock.

The two discount arguments (discount-on-abort and discount-on-timeout) specify what to do when a barrier-wait call ends abnormally. Each defaults to nil and a true value for either specifies that the arriver-count is decremented in that case.

The discount-on-timeout argument specifies the behavior if the barrier-wait call takes longer that the specified timeout. The discount-on-abort argument specifies the behavior if the barrier-wait call is ended abruptly for some other reason.

The disable-on-unblock argument specifies the behavior when barrier-unblock is called explicitly or implicitly. When `nil`, the built-in default, barrier-unblock leaves the barrier enabled and ready for a new set of arriving threads. When non-`nil`, the barrier is disabled.

The name argument should be a string that will be used in status and error messages.

The callback argument specifies a function that is called in the thread where barrier-wait detects that the arriver-count has reached the specified count. The function is called with one argument, the barrier. The function is called before the barrier is unblocked and while the barrier is still locked; consequently, this function should not perform extensive computations.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# make-condition-variable

Function, multiprocessing package

Arguments: &key name

Create an instance of condition-variable. The name may be used in error messages and whostate values.

See Condition Variables in smp.html.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# make-gate

Function, multiprocessing package

Arguments: open

Allocates and returns a gate object. The gate's initial state will be open if open is true and closed if open is `nil`.

See Gates in multiprocessing.html for more information. See also open-gate, close-gate, and gate-open-p.

# make-process

function, multiprocessing package

Arguments: &key name class reset-action run-reasons arrest-reasons priority quantum resume-hook suspend-hook initial-bindings run-immediately stack-allocation message-interrupt-function

This function returns a new process object, but does nothing about making it runnable.

#### name, class, quantum, priority, run-reasons, arrest-reasons, and reset-action keyword arguments

name must be a string. Its default value is "Anonymous".

The class keyword argument specifies the class of the process being created. The value defaults to the class mp:process. A subclass of mp:process may be specified instead, if a program has created such subclasses.

The default value of quantum is 2 and of priority is 0. run-reasons and arrest-reasons are both lists of Lisp objects. They default to `nil` (that is, the empty list). The effect of these lists being empty or not is described in multiprocessing.html. The process can run only if the arrest-reasons list is empty, and the run-reasons list is not empty. reset-action defaults to `nil`. If it is set to `t`, the process will restart if it is reset or ever completes; that is, it will once again apply its initial function to its initial arguments. Otherwise, the process will be killed when it completes.

#### No property-list keyword argument

There is no property-list keyword argument, but property lists for processes are supported and process-property-list accesses them. They can be modified in the usual property list way with getf and setf of getf and that function.

#### initial-bindings, resume-hook, and suspend-hook keyword arguments

The initial-bindings, resume-hook, and suspend-hook arguments all default to `nil` and initialize the corresponding slot values of the process object. The meanings of these slots are explained in multiprocessing.html.

#### stack-allocation keyword argument

The stack-allocation argument is only used in the :os-threads model of multiprocessing. It specifies the size to request from the OS for the thread associated with the new process. The default value is to copy the size used for the process in which the process-creating function (i.e. make-process or something that calls make-process) is running. A process's soft limit is set to a default value when the process starts. This value is 80% of the hard limit or 4 megabytes, whichever is less.

#### message-interrupt-function keyword argument

The message-interrupt-function argument is important for Windows only. In the windows environment only, it's very very bad to ignore messages for long periods of time. Some global events involve broadcasting messages to a class of threads, and some of these have to be responded to or things lock up.

To deal with this, each windows process has an attribute process-message-interrupt-function. When a process is in a non-ready state (wait function, arrest reasons, no run reasons), and a windows message appears on its message queue, then the `process-message-interrupt-function` will be run as if by process-interrupt call, if the process-message-interrupt-function is non-`nil`.

The `process-message-interrupt-function` attribute can be initialized at process creation via the message-interrupt-function keyword argument. The default value, if unspecified, is the value (at process-creation time) of the variable *default-message-interrupt-function*.

    (mp:process-message-interrupt-function p) is setfable.

The function specified as the message-interrupt handler for a process must return non-`nil` if there is any chance that it made a change in Lisp state that could free another process to run, and `nil` otherwise.

The system-provided initial value of *default-message-interrupt-function* is the function mp::process-messages-in-interrupt, a function of no arguments, that verifies the existance of messages on the queue. It returns `nil` if there are none. Otherwise it dispatches all of them and returns `t`.

#### The immigrant and run-immediately keyword arguments

The immigrant keyword argument is for internal use only. Do not specify a value for it.

The run-immediately keyword argument was designed to tell the in-Lisp scheduler to run the new process immediately (assuming it was runnable) regardless of the assigned priorities. It was never effective in threaded multiprocessing since scheduling was done by the OS. In 7.0 it is ignored and no value should be specified for it.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# make-process-lock

function, multiprocessing package

Arguments: &key name locker waiting

This function creates a new lock object. The value of the name keyword argument should be a string which is used for documentation and in the whostate of processes waiting for the lock. The waiting and locker keyword arguments are for internal use and should never be set by user code.

See multiprocessing.html for general information on multiprocessing in Allegro CL and see Process locks for more information on process locks in Allegro CL.

# make-process-pool

Function, multiprocessing package

Arguments: &key active-limit idle-limit idle-timeout name report-start report-end class process-class prime stack-allocation

Create and return a new process-pool instance. The keyword arguments specify initial values for the corresponding slots.

- active-limit: A positive integer specifying the maximum number of active processes allowed in the pool. Although permitted, it does not make sense for this value to be smaller than idle-limit, as then there would always be idle processes using resources but not running. Since this value is constrained by operating system resources, hardware configuration and application requirements, there is no reasonable built-in default. If not specified, the default value is taken from *process-pool-default-active-limit*.

- idle-limit: A positive integer specifying the maximum number of idle processes allowed in the pool. The default is the value of active-limit. Although permitted, it does not make sense for this value to be larger than active-limit, as then there would always be idle processes using resources but not running.

- class: A symbol naming a subclass of process-pool (the default).

- process-class: A symbol naming subclass of pool-process (the default).

- prime: An integer less than or equal to idle-limit or any other non-`nil` value that is not a number, or `nil`. If a positive integer, that number of pool processes will be created in idle state when the pool is created. If another non-`nil` value, idle-limit processes will be created. If `nil` (the default), no processes will be created.

- idle-timeout: The number of seconds an idle process is kept on the idle list. The default is `nil` meaning keep forever.

- name: The name of the process-pool. The name is also used for creating identifiers for certain other objects associated with the process-pool and thus helps identify which process-pool is meant in backtraces and error messages. The value must be a string. It value defaults to "ppN" where N is a unique integer. This value is not currently used for any other purpose.

- report-start: A function designator for the default `report-start` function or `nil`. When non-`nil`, the report-start function is called with a single argument, the work-item, when a process-pool-work-item is executed. The function specified here will be used if the work-item does not have its own non-`nil` `report-start` value. If you want to run a work-item with no report-start function, specifying `nil` as the report-start argument when creating the work item (directly with make-process-pool-work-item or as a side effect of calling process-pool-run) does not work as that means run this default report-start function. To have a report-start function that does nothing, define a function that does nothing and make it the report-start function for the work-item.

- report-end: A function designator for the default report-end function or `nil`. When non-`nil`, the report-end function is called with a three arguments when a process-pool-work-item is executed. The arguments are the work-item, the list of values returned by the work-item function, and the error condition if an error was signaled during the execution of the work-item. The report-end function specified here will be used if the work-item does not have its own report-end value. If you want to run a work-item with no report-end function, specifying `nil` as the report-end argument when creating the work item (directly with make-process-pool-work-item or as a side effect of calling process-pool-run) does not work as that means run this default report-end function. To have a report-end function that does nothing, define a function that does nothing and make it the report-end function for the work-item.

- stack-allocation: If specified, the value of this argument is passed to mp:make-process as the value of its stack-allocation argument when a new process is created for the process-pool. See the description of mp:make-process for complete details.

See Process pools in multiprocessing.html for more information on process pools.

# make-process-pool-work-item

Function, multiprocessing package

Arguments: &key name function arguments data report-start report-end work

This function either creates a new process-pool-work-item or modifies an existing one, depending on the value of the work keyword argument. If work is `nil` or unspecified, a new process-pool-work-item is created and returned. If it is an existing, idle process-pool-work-item, that one is modified according to the values of the other arguments and returned. Modifying a work-item that is not idle, while legal, may have unexpected results unless care is taken to ensure predictable behavior. A work-item is idle when process-pool-work-item-active-p returns `nil` when applied to the work-item.

process-pool-run will create a process-pool-work-item on its own (and either start running it or add it to its queue), so creating them using this function is not necessary.

The keyword arguments other than work (name, function, arguments, data, report-start, and report-end) define the work-item attributes. All are also arguments to process-pool-run. See the description of that function for information on these arguments. process-pool-run also accepts the keyword argument queue-p. That is not an argument to make-process-pool-work-item.

See Process pools in multiprocessing.html for more information on process pools.

# make-sharable-lock

Function, multiprocessing package

Arguments: &key name max-shared yield-rate recursive-p safe-p auto-unlock-p constructor

This function returns a fresh instance of a sharable-lock.

The name argument must be a string or `nil`. The name is used in status and error messages.

The max-shared argument must be an integer greater than zero; it specifies the maximum number of simultaneous shared users allowed at any moment. The default value is 20. The size of the instance is proportional to this number. Values as high as 1000 still perform reasonably well, but much larger values may degrade performance noticably.

The yield-rate argument must be an integer greater than zero; it specifies how often a spin loop should yield. The default value is 5. Most of the low-level locking in SMP code is done with spin loops testing control bits. Such loops are very effective for short delays since they do not involve any operating system delays. However, if longer delays can occur, especially when the number of active threads is greater than the number of available processors, then spin loops can consume large amounts of cpu time with very little benefit. When a value of n is specified for yield rate, sharable-lock spin loops yield control every n-th iteration so that other threads may run and possibly release the needed resource sooner. If the yield-rate is specified as :never, then no yield is done at all.

The recursive-p argument specifies the behavior when a lock is locked recursively or repeatedly in the same thread. The value can be specified as a list containing any of the keywords below.

A value of `nil`, ie an empty list, prevents any recursive or repeated locking.

A non-`nil` value allows recursive or repeated locking from the same thread. Each locking call increments a counter and unlock calls decrement the counter. The lock is actually released when the count is zero. Although recursive or repeated locking is labeled with a mode, it does not actually change the state of the lock in any way; any recursive code operates in the same locking environment as the outermost or initial locking call.

- `:exclusive`: allows an exclusive locking call to succeed when an exclusive lock is already held in the same thread.

- `:shared`: allows a shared locking call to succeed when a shared lock is already held in the same thread.

- `:downgrade`: allows a shared locking call to succeed when an exclusive lock is already held in the same thread. This is a potentially dangerous use of the lock since the outer exclusive locking code may have made partial inconsistent changes to some data object.

- `:upgrade`: allows an exclusive locking call to succeed when a shared lock is already held in the same thread. This use is both dangerous and of questionable utility since the strength of the lock has not changed. Any modifications made in the upgrade code will be seen by any number of shared users assuming unmutability of the data.

The default setting is `t` to denote the list `(:exclusive :shared)`. The default is thus to allow recursive or repeated access of the same mode.

If shared access is used for read-only access to a data object, recursive access is safe and meaningful. If exclusive access is used to make multiple related changes to a data object, recursive access may be meaningful, but the recursive acesses must be reviewed for possible interference.

Note also that separate counters are maintained for uses of the macros with-shared-lock and with-exclusive-lock, and uses of the sharable-lock-lock function. A call to sharable-lock-unlock cannot release a lock obtained with one of the macros.

The safe-p argument specifies the behavior if an attempt is made to unlock a lock that is already unlocked. The default value is `t`. When the value is non-`nil`, an error is signaled if an attempt is made to unlock a lock that is already unlocked. When the value is `nil`, the attempt is ignored silently.

The auto-unlock-p argument specifies the behavior if the locking process is terminated without releasing the lock. The default value is `nil`. When the value is `nil`, nothing is done. When the value is non-`nil`, a lock held by a terminated process is automatically released when competition for the lock occurs.

The constructor argument specifies the constructor used in creating a sharable-lock instance. The default constructor creates an instance of the sharable-lock struct. A user-defined sub-class must be a struct that includes sharable-lock.

See Sharable locks in smp.html.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# memlog

Function, multiprocessing package

Arguments: label &rest data

This function makes an entry in the current active memory log and returns `nil`. If there is no current active memory log, this function does nothing and returns `nil`.

The entry consists the following values, with the first 4 always recorded and as many of the rest (data arguments) as will fit in the current width specification of the memory log.

1. thread index of the current thread
2. process-name of the current thread
3. a timestamp (milliseconds since the last call to memlog-init)
4. the label
5. as many data arguments as fit in the current width specification of the memory log

The memlog function is very short and does no consing in order to minimize the disturbance caused by introducing tracing in an application. It does necessarily require a memory barrier in order to access the shared log object and this operation is likely to disturb to some extent the time behavior of a complex multi-threaded application.

Note also that if modifiable objects are recorded in the log, when the log is examined, the values seen will be the values at the time of the examination.

This function will make an entry in the log if it can gain a lock on the memory log within the limits specified when the log is initialized. If a lock cannot be obtained, the skipped count is incremented. The default setting is to iterate 5 times on the lock attempt, yield once and try 5 more iterations. This behavior is modified with the yield-rate and yield arguments to memlog-init.

See Memlog: A Facility for Minimally Intrusive Monitoring of Complex Application Behavior in smp.html for more information.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# memlog-copy

Function, multiprocessing package

Arguments: &key log stop start wait

Return a memory-log instance that contains a copy of the current memory log. Memory logging is suspended while the copy is made. This suspension is one possible cause for delays or skips in a memlog call. If a copy cannot be made, return `nil`.

If the log argument is specified, it must be a memory-log instance created in a previous call to memlog-copy. The current log is copied into the supplied object. If the current log is longer, the most recent entries are not copied.

If the stop argument is `nil`, the current log must be in the `:stopped` state. Otherwise, the current log is stopped before making the copy. The default is `t`.

The wait argument specifies how long to wait for the required state change. The default is `nil`, which means do not wait and return `nil` if a copy cannot be made. A non-negative integer means wait up to that number of seconds (no wait for 0). Any other non-`nil` value means wait as long as necessary.

The start argument specifes the state of memory logging after the copy is made. The allowed values are `nil`, `:cond`, or other non-`nil`. The default is `:cond`.

See Memlog: A Facility for Minimally Intrusive Monitoring of Complex Application Behavior in smp.html for more information.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# memlog-disable

Function, multiprocessing package

Arguments:

Disable memory logging entirely. A call to memlog-init is needed before any memlog operations will take effect again.

Any currently active memlog operations will continue to completion but their results will be lost.

See Memlog: A Facility for Minimally Intrusive Monitoring of Complex Application Behavior in smp.html for more information.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# memlog-entry

Function, multiprocessing package

Arguments: index &key return log wait

Return one entry from the current or the specified memory log. Return `nil` if an entry was not obtained.

The index argument specifes the desired entry: 0 denotes the oldest entry; -1 denotes the most recent entry.

If log is specified, return an entry from that log.

If wait is specified, it determines how long to wait in order to acquire a log on the current log (`nil` or 0 means do not wait, a positive integer means wait that number of seconds, any other non-`nil` value means wait as long as necessary).

The return argument may be `:list`, `:vector`, a list or a vector:

- `:list` -- return the log entry as a new list of 4+w elements.
- `:vector` -- return the log entry as a new vector of 4+w elements.
- a list -- copy the log entry into the given list, filling with `nil` if necessary. Copy as much as will fit.
- a vector -- copy the log entry into the given vector, filling with `nil` if necessary. Copy as much as will fit.

Note that each entry from a current and active log is fetched under a new lock. Thus two calls with the same index may not retrieve the same entry. Two calls with consecutive indices may return unrelated entries If consistent indexed access is desired, a copy of the current log must be made.

See Memlog: A Facility for Minimally Intrusive Monitoring of Complex Application Behavior in smp.html for more information.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# memlog-init

Function, multiprocessing package

Arguments: &key size width stop start wait yield-rate yield

This function initializes the current memory log with possibly new values for size and width. The return value is the new state of the initialized current log, or `nil` if nothing was done.

If the wait argument is non-`nil`, wait until the current log becomes available in the required state. If the wait argument is a number, wait that many seconds and if the time runs out, return `nil`. The default is to wait up to one second; this delay should be sufficient if an active log is in the middle of a logging call. If the wait argument is `nil`, return `nil` if the log is not in the required state.

When the stop argument is is non-`nil` (the default), stop logging when logging is active. Once logging is stopped, any current entries are discarded and the log is initialized. If the stop argument is `nil`, the log must already be stopped or `nil` is returned.

The start argument specifies the state of the current memory log after this operation:

- `nil` -- Leave the log in the `:stopped` state. This is the default.

- `:cond` -- Leave the log in the same state that was in effect on entry.

- other non-`nil` -- Leave the log in the `:ready` state.

The size argument specifes the maximum number of entries in the log. When the maximum is reached, older entries are overwritten with newer entries. If the size is not specified, the most recently used size continues in effect. The default size is 1000.

The width argument specifies the number of data values in each entry. If the width is not specified, the most recently used width continues in effect. The default width is 4.

All the memory locking operations must synchronize their behavior on a lock in memory. Spinning on the lock is most efficient in an SMP architecture, but when there are more threads than processors, spinning may be counterproductive. If a lock cannot be acquired in N attempts, the memlog operations yield to another thread and try again for N attempts. The yield-rate argument specifies a value for N. The default is 5.

The yield argument is tested by the memlog call only. If non-`nil`, the default, then one yield is performed if necessary to obtain a lock on the log object. If `nil`, then no yield call is made at all. Thus if the log is initialized with yield-rate=1 and yield=`nil`, a log entry will be made only when the log is available immediately; this is the least disruptive setting of the memory log. The skipped count returned by memlog-state increases as the waiting in memlog is made more restrictive.

See Memlog: A Facility for Minimally Intrusive Monitoring of Complex Application Behavior in smp.html for more information.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# memlog-show

Function, multiprocessing package

Arguments: &key format thread stop start wait log

Print the contents of the current memory log to *standard-output*. The printing is always done from a copy of the current log. The value is returned is the copy from which the output was printed.

If the log argument is not supplied, call memlog-copy with the supplied stop, start, and wait arguments. If the log argument is specified, it must be a memory-log instance. In that case memlog-copy is not called; the output is derived from the supplied log.

If the thread argument is supplied it may be an integer thread index or a string or symbol. Only the entries pertaining to the specified thread are printed. A string or symbol is matched to the start of a process name, ignoring case.

The format argument specifies a format for the output; the default is `:default`. The allowed values are:

- `:raw` -- print all the components of an entry on one line with the `~S` format directive for each.
- `:default` -- print a moderately readable form of each entry.
- `:logfmt` -- print the leading elements of the entry in the `:default` format. Examine elements after the fourth and treat a string containing `~` as a format string to use on the remaining parts of the entry.
- `a string` -- treat the string as a format string applied to the log entry to return a string for an output line.
- `other` -- apply other to the current log entry.

See Memlog: A Facility for Minimally Intrusive Monitoring of Complex Application Behavior in smp.html for more information.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# memlog-start

Function, multiprocessing package

Arguments: &key wait

Change the state of memory logging to `:ready`. If the current state was already `:ready`, return `t`. If the state was changed to `:ready` by this call, return `:started`.

If the wait argument is `nil` (or zero or negative), return `nil` if the state is not and cannot be immediately changed to `:ready`. If the `wait` argument is a positive integer N, wait up to N seconds. If the `wait` argument is any other non-`nil` value, wait indefinitely.

A delay may be caused by some other memlog operation in another thread.

See Memlog: A Facility for Minimally Intrusive Monitoring of Complex Application Behavior in smp.html for more information.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# memlog-state

Function, multiprocessing package

Arguments: &key log wait

Return the state of memory logging.

If the log argument is specified, return the state of the specified log.

If the wait argument is specified, it determines how long to wait in order to gain access to the log (`nil` or 0 means do not wait, a positive integer means wait that number of seconds, any other non-`nil` value means wait as long as necessary).

If memory logging is disabled, return `nil`.

Otherwise return 5 values: the current state keyword (`:stopped` or `:ready`) and 4 numbers which indicate entries, skipped, size, width.

The current memory log may be in other intermediate states but these exist only while the log is locked. Since memlog-state must acquire a lock to obtain a consistent snapshot, it can only report on the two stable unlocked states.

See Memlog: A Facility for Minimally Intrusive Monitoring of Complex Application Behavior in smp.html for more information.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# memlog-stop

Function, multiprocessing package

Arguments: &key wait

Change the state of memory logging to `:stopped`. If the current state was already `:stopped`, return `t`. If the state was changed to `:stopped` by this call, return `:stopped`.

If the wait argument is `nil` (or zero or negative), return `nil` if the state is not and cannot be immediately changed to `:stopped`. If the wait argument is a positive integer N, wait up to N seconds. If the wait argument is any other non-`nil` value, wait indefinitely.

A delay may be caused by some other memlog operation in another thread.

See Memlog: A Facility for Minimally Intrusive Monitoring of Complex Application Behavior in smp.html for more information.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# memtrace

Macro, multiprocessing package

Arguments: &rest fnspecs

This macro adds an fwrapper to each of the arguments (see fwrappers-and-advice.html). This fwrapper makes two memlog calls:

- The first call is on entry with the name of the function, a depth of recursion counter, and the arguments to this call.

- The second call is on exit with the name of the function, the negative value of the recursion counter, and any values returned by the function.

The wrapper must have been created previously by a call to memtrace-def or memtrace-do.

If a wrapper does not exist for one of the functions, a warning is signaled and adding wrappers continues with the next function.

See Memlog: A Facility for Minimally Intrusive Monitoring of Complex Application Behavior in smp.html for more information.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# memtrace-def

Macro, multiprocessing package

Arguments: &rest fnspecs

This is a top-level form such as defun and defmacro. It defines one or more wrappers that enable the memtrace feature for the given functions, but does not actually enable the wrapper (in contrast with memtrace-do which does enable the wrappers).

This call does not activate, deactivate or modify any memtrace currently in effect.

See Memlog: A Facility for Minimally Intrusive Monitoring of Complex Application Behavior in smp.html for more information.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# memtrace-do

Macro, multiprocessing package

Arguments: &rest fnspecs

This is a top-level form such as defun and defmacro. It defines one or more wrappers that enable the memtrace feature for the given functions, and enables the memtrace feature for each (in contrast with memtrace-def which simply creates the wrappers).

See Memlog: A Facility for Minimally Intrusive Monitoring of Complex Application Behavior in smp.html for more information.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# memuntrace

Macro, multiprocessing package

Arguments: &rest fnspecs

This macro removes the fwrappers created by memtrace for the specified functions. (See fwrappers-and-advice.html.) Called with no arguments, this macro removes all memtrace fwrappers (analogously with (untrace) untracing all traced operators).

See Memlog: A Facility for Minimally Intrusive Monitoring of Complex Application Behavior in smp.html for more information.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# open-gate

Function, multiprocessing package

Arguments: gate

The gate argument must have been allocated with make-gate. Makes the state of gate open.

See Gates in multiprocessing.html for more information. See also make-gate, close-gate, and gate-open-p.

# process-active-p

function, multiprocessing package

Arguments: process

This function returns `t` if process is active.

A process is active if it has been reset and not yet completed, and has at least one run reason and no arrest reasons. It is runnable (see process-runnable-p) if it is active and not waiting.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# process-add-arrest-reason

function, multiprocessing package

Arguments: process object

This function adds object to the list of arrest-reasons for process.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# process-add-run-reason

function, multiprocessing package

Arguments: process object

This function adds object to the list of run-reasons for process.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# process-alive-p

Function, multiprocessing package

Arguments: process

This function returns non-`nil` if and only if the system thinks the process has not been killed and has not finished its computation.

See multiprocessing.html for general information on multiprocessing.

# process-allow-schedule

function, multiprocessing package

Arguments: &optional process

This function allows processes other than the running (and hence calling) process to run. All other processes of equal or higher priority to the calling process will have a chance to run before the calling process is next run. This function is useful when a process seems to be using all available resources. For use in an SMP Lisp, see the notes below.

The optional process argument is ignored (in an earlier multiprocessing implementation, it specified the process to be run next). If you want a specific process to run next, you need to make sure it is the highest-priority process that is ready to run.

### process-allow-schedule and SMP

In an SMP Lisp on a machine with multiple cores, this function is less useful because multiple processes can run simultaneously. Even in an SMP lisp, there may be more Lisp processes than there are available cores. In this case process-allow-schedule calls the host OS's yield function, allowing OS to assign that core to another ready lisp thread.

Before SMP, process-allow-schedule worked on the theory that an application might have specific points in its processing cycle that were better suited to allowing another process to run than the random point selected by the quantum timeout. Points where there was a minimum of temporary data that would clog the next gc, for example, or points where a minimum number of locks were held.

In SMP, to have a successful multi-threaded app that actually uses multiple cores, these sorts of considerations need to be part of the application design. Calling process-allow-schedule in such a situation is probably benign, and may in rare cases be a help, but will not usually solve any serious problems.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# process-arrest-reasons

function, multiprocessing package

Arguments: struct

This function returns the list of arrest-reasons for process. The list can be changed with setf or related macros and this function or with process-add-arrest-reason. Any Lisp object can be on the list. A process will not run unless it has at least one run reason (see process-run-reasons) and no arrest reasons.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# process-cpu-msec-used

Generic Function, multiprocessing package

Arguments: process

Returns the total milliseconds of cpu time this process has used in lisp. (Time accrued while executing foreign code with the heap released is not counted).

See multiprocessing.html for general information on multiprocessing.

# process-cpu-msec-used-delta

Generic Function, multiprocessing package

Arguments: process

This function returns the number of milliseconds used since the last call to process-cpu-msec-used-delta. The first time this function is called, it returns what process-cpu-msec-used returns, the time used since the process started.

See multiprocessing.html for general information on multiprocessing.

# process-disable

function, multiprocessing package

Arguments: process

This function makes process inactive by revoking all its run and arrest reasons. The effect is immediate if a process disables itself.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# process-enable

function, multiprocessing package

Arguments: process

Makes process active by removing all its run and arrest reasons, then giving it a single run reason of `:enable`.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# process-exit-actions

Generic Function, multiprocessing package

Arguments: process

Returns the exit-actions for process, which must be an instance of mp:process. The value is a list whose elements are of the form `(function . arguments)`. When the process finishes, either normally or via an unwinding kill, it executes the actions by applying the functions to their argument lists. You can use setf to change the value though it is more normal to push additional actions onto it.

See multiprocessing.html for general information on multiprocessing.

# process-initial-bindings

function, multiprocessing package

Arguments: struct

This slot of a structure stores an alist of initial special bindings which are established on the process when it is started. The value may be set with setf.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# process-initial-form

function, multiprocessing package

Arguments: struct

This function returns a cons of the initial function of process and its argument list.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# process-interrupt

function, multiprocessing package

Arguments: process function &rest args

This function forces process to apply function to args when it next executes. When function returns, the original computation of process continues. If process is waiting when interrupted, it runs the interrupt function and then continues waiting. If process is not active, mp:process-interrupt makes it active for the interrupt function, then makes it inactive again. If additional interrupts are posted to a process when one is already posted, they are all run, but in undetermined order.

In order for process-interrupt to work as described, function must return normally. It cannot execute a non-local exit (via, for example, throw). If function does exit in a non-local manner, process will not continue its computation.

Processing an interrupt function can be interrupted by additional process interrupts that occur before the current one has finished executing.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# process-join

Generic Function, multiprocessing package

Arguments: *process &key (errorp t) error-values (search-list '(:current :previous :next))

Suspend the current process until mp:process-thread of process exits, and then return the list of result values of the preset function of process. If the thread does not exit normally, signal a `mp::process-join-error` if errorp is true or return error-values if errorp is `nil`.

This simple state of affairs is complicated by the fact that a process can have several threads associated with it over its lifetime. One may want (1) to wait for the current thread or (2) get the return values of the most recently finished thread of process or (3) wait for the thread to finish even if there is no current one. The search-list argument controls which threads are considered and in what order. Valid elements for search-list are `:current`, :previous, and `:next`. The list is processed in order. `:next`, if present, should always be last in the list.

If `:current` is found and there is a live thread associated with the process then it is waited for and its values returned as described above, else the processing of the list continues. If `:previous` is found and there was a thread associated with process but by now it has finished then its values are returned (no waiting is needed in this case), else the processing of the list continues. If `:next` is found then process-join waits for a thread of process to finish.

The difference between `:current` and `:next` is that `:next` will wait for a thread that has not even started while `:current` only waits if there is a live thread.

If the end of the search-list list is reached, that is considered an error and a `mp::process-join-error` is signaled if errorp is true, and error-values is returned if errorp is nil.

When successful, process-join returns a second value: the element of search-list which resulted in matching a thread and terminating the processing of the list.

This function is async unwind safe: one can wrap it in sys:with-timeout.

#### Example:

    (mp:process-join process :search-list '(:current :previous :next))

    :CURRENT makes it wait for the current thread associated with the
    process if any.

    :PREVIOUS makes it take the return values from the most recently
    finished thread that was associated with the process if any.

    :NEXT (there hasn't been a thread associated with this process) so we
    wait for the next one.

    The first of these to succeed ends the call to PROCESS-JOIN and
    returns the associated values. :NEXT, if present, should be last.  If,
    for example, :SEARCH-LIST is '(:current :previous) and there is no
    current thread and was no previous thread, an error is signaled, as in
    this case:

    cg-user(11):   (let ((process (mp:make-process)))
        (mp:process-join process :search-list '(:current :previous)))
    Error: Joining process #&lt;process Process.1> failed.

    [condition type: process-join-error]
    cg-user(12):

    Because the process created in the LET binding was never started,
    there is no current thread for it and no previous thread. Since
    :SEARCH-LIST is '(:current :previous), an error is signaled.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# process-keeps-lisp-alive-p

Generic Function, multiprocessing package

Arguments: process

Lisp cannot exit if a process is running where this slot is true (since that process keeps Lisp alive). That is normally what you want. However, if a process is purely ancillary, it is reasonable to set this slot to `nil`, so Lisp can automatically kill the process and exit when it is the only live process. setf can be used to change the value returned by this generic function.

An example is the background process set up in Emacs to debug non-listener processes that signal an error (see Debugging background processes in debugging.html). These processes are started with this slot `nil`, since it is presumed you do not want to continue with that process when all others have been killed.

When you call exit and processes (other than the listener where the call to exit was entered) are still running, if any keep Lisp alive, you are explicitly asked if you want to kill them and exit. But if processes which do not keep Lisp alive are running, they are silently killed and Lisp exits.

See multiprocessing.html for general information on multiprocessing.

# process-kill

generic function, multiprocessing package

Arguments: process &key wait

This function initiates killing the argument process (i.e. a thread). Killing a process involves unwinding it. If all goes well, process will removed from consideration for running and also be removed from the *all-processes* list, but those things typically happen after process-kill has returned, assuming wait is `nil`. That is, those actions are initiated by the call to process-kill but are completed separately (in part, by process itself). process-kill can be viewed as a request to the system to kill a process.

If the wait keyword argument is non-`nil`, the this function (and the thread that called it) wait until the killed process is really gone. process-kill signals an error if the process to be killed is an active immigrant. An inactive immigrant is one that was created to handle a lisp call from a foreign thread, and has returned from the topmost lisp call back into the foreign regime. The thread may still be processing, but it has no lisp state. This will kill the lisp process associated with that foreign thread, but will not kill the foreign thread itself. If it later calls into lisp, a new immigrant process will be created for it.

If wait is true and for some reason process is not killed, this function will not return.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# process-lock

function, multiprocessing package

Arguments: *lock &optional lock-value whostate timeout

This function seizes lock with the value lock-value. If the lock is already locked, the process calling process-lock waits for it to become free. While it waits, its whostate is temporarily replaced by the whostate argument. The default value for whostate is "Lock".

The value of the lock-value argument is stored in the locker slot of the lock (accessed by process-lock-locker). The default value for lock-value is the value of *current-process*. Note that any non-`nil` value can be specified as the value of lock-value (specifying `nil` means that the lock is not seized because a lock with `nil` in the locker slot is unlocked).

If timeout is specified and non-`nil`, it should be zero or positive number. It then specifies the maximum number of seconds to wait before abandoning the attempt to seize lock (with a value 0 meaning seize the lock if and only if it is currently free).

If process-lock suceeds in seizing the lock, it returns a non-`nil` value. If it gives up (because, e.g., it times out), `nil` is returned.

Locks are freed with process-unlock. See also with-process-lock and make-process-lock.

See multiprocessing.html for general information on multiprocessing in Allegro CL and see Process locks for more information on process locks in Allegro CL.

# process-lock-locker

function, multiprocessing package

Arguments: lock

This function returns the value of the locker slot of lock, which must be a lock object (see make-process-lock). This value is usually the process holding the lock. If the value in the slot is `nil`, the lock is free. The following idiom is useful when a process wants to seize a lock but not block if it is already seized:

      (without-interrupts
        (if (process-lock-locker lock)
            (...) ;; Lock not free
              ;; do something else.

          (process-lock lock))) ;; Seize the lock.

See process-lock, process-unlock, with-process-lock and make-process-lock.

See multiprocessing.html for general information on multiprocessing in Allegro CL and see Process locks for more information on process locks in Allegro CL.

# process-lock-p

function, multiprocessing package

Arguments: object

Returns `t` if object is a process-lock object (as returned by make-process-lock) and returns `nil` if it is not.

See multiprocessing.html for general information on multiprocessing in Allegro CL and see Process locks for more information on process locks in Allegro CL.

# process-lockedp

Generic Function, multiprocessing package

Arguments: x &optional with-barrier

Returns true if x, a lockable-object, is locked.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# process-message-interrupt-function

Generic Function, multiprocessing package

Arguments: process

Returns or sets with setf the message-interrupt-function of process. This is specified to make-process as the value of the message-interrupt-function argument. This attribute of a process is important for Windows only. In the windows environment only, it's very very bad to ignore messages for long periods of time. Some global events involve broadcasting messages to a class of threads, and some of these have to be responded to or things lock up.

To deal with this, each windows process has this attribute. When a process is in a non-ready state (wait function, arrest reasons, no run reasons), and a windows message appears on its message queue, then the process-message-interrupt-function will be run as if by process-interrupt call, if the process-message-interrupt-function is non-`nil`.

See multiprocessing.html for general information on multiprocessing.

# process-name

function, multiprocessing package

Arguments: struct

This function returns the name of process. A name must be a string. This value may be changed with setf.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# process-name-to-process

function, multiprocessing package

Arguments: *name &key abbrev (error t)

This function returns the process whose process-name is name. name must be a string or a symbol, in which case the print-name is used. If the abbrev keyword argument is specified true, then name is matched to the beginning of each process-name to find a match. The abbrev argument defaults to `nil`.

If abbrev is true and there are multiple processes whose names start with abbrev, two values are returned: one of the processes found and `t`.

If no process is found whose name is name (or, if abbrev is true, whose name begins with name), an error is signaled if error is unspecified or true, and `nil` is returned if error is specified `nil`.

See also find-process. See multiprocessing.html for general information on multiprocessing in Allegro CL.

# process-os-id

Generic Function, multiprocessing package

Arguments: process

Returns the operating system's identifier for the native thread associated with process, or `nil` if there is no current os-thread. A process that has never been enabled will have no thread and therefore return `nil` here. In a virtual threads model (non-`:os-threads`), an active process will return a non-`nil` value that will be otherwise meaningless.

See multiprocessing.html for general information on multiprocessing.

# process-p

function, multiprocessing package

Arguments: object

Returns `t` if object is a process and returns `nil` if it is not.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# process-pool-active-count

Generic Function, multiprocessing package

Arguments: process-pool

The default method for this process-pool accessor returns the value of the `active-count` slot of the argument process-pool instance.

The value of the `active-count` slot is the number of processes in the active list at the moment the call to the reader is evaluated.

See Process pools in multiprocessing.html for more information on process pools.

# process-pool-active-limit

Generic Function, multiprocessing package

Arguments: process-pool

The default method for this process-pool accessor returns the value of the `active-limit` slot of the argument process-pool instance.

The value of the `active-limit` slot is the maximum number of active processes allowed at any time. If an additional process is requested and the maximum number are already busy, the request will wait until a process becomes available.

See Process pools in multiprocessing.html for more information on process pools.

# process-pool-discarded-count

Generic Function, multiprocessing package

Arguments: process-pool

The default method for this process-pool accessor returns the value of the `discarded-count` slot of the argument process-pool instance.

The `discarded-count` slot holds the number of times any process was discarded after running a work item.

See Process pools in multiprocessing.html for more information on process pools.

# process-pool-idle-count

Generic Function, multiprocessing package

Arguments: process-pool

The default method for this process-pool accessor returns the value of the `idle-count` slot of the argument process-pool instance.

The value of the `idle-count` slot is the number of processes in the idle list at the moment the call to the reader is evaluated.

See Process pools in multiprocessing.html for more information on process pools.

# process-pool-idle-limit

Generic Function, multiprocessing package

Arguments: process-pool

The default method for this process-pool accessor returns the value of the `idle-limit` slot of the argument process-pool instance.

The value of the `idle-limit` slot is the maximum number of idle processes allowed at any time. If there are this number of processes idle and an active process completes its work and so becomes idle, a process will be killed so that only this number of idle processes will exist.

See Process pools in multiprocessing.html for more information on process pools.

# process-pool-idle-timeout

Generic Function, multiprocessing package

Arguments: process-pool

The default method for this process-pool accessor returns the value of the `idle-timeout` slot of the argument process-pool instance.

The value of the `idle-timeout` slot is the number of seconds an idle process is kept in the idle list. When this limit is exceeded, the process is killed.

See Process pools in multiprocessing.html for more information on process pools.

# process-pool-killed-count

Generic Function, multiprocessing package

Arguments: process-pool

The default method for this process-pool accessor returns the value of the `killed-count` slot of the argument process-pool instance.

The `killed-count` is the number of times any process was discarded by being terminated.

See Process pools in multiprocessing.html for more information on process pools.

# process-pool-max-active

Generic Function, multiprocessing package

Arguments: process-pool

The default method for this process-pool accessor returns the value of the `max-active` slot of the argument process-pool instance.

The value of the `max-active` slot is the cumulative maximum of the number of active processes.

See Process pools in multiprocessing.html for more information on process pools.

# process-pool-max-work

Generic Function, multiprocessing package

Arguments: process-pool

The default method for this process-pool accessor returns the value of the `max-work` slot of the argument process-pool instance.

The value of the `max-active` slot is the cumulative maximum number of work items in queue.

See Process pools in multiprocessing.html for more information on process pools.

# process-pool-new-count

Generic Function, multiprocessing package

Arguments: process-pool

The default method for this process-pool accessor returns the value of the `new-count` slot of the argument process-pool instance.

The `new-count` slot holds the number of times a new process was created. When process-pool-run is called, after perhaps waiting in the work-item queue either (1) an existing idle process is used to run the associated work-item or (2) a new process is created to do so. Whenever (2) occurs (a new process is created), the value returned by (the default method of) this generic function is increased by 1. The value also includes all processes which were primed processes created when the process pool was created. See also process-pool-reused-count.

See Process pools in multiprocessing.html for more information on process pools.

# process-pool-report-end

Generic Function, multiprocessing package

Arguments: process-pool

The default method for this process-pool accessor returns the value of the `report-end` slot of the argument process-pool instance.

The `report-end` slot holds the default report-end function applied to work-items run in process-pool. The report-end function must accept three arguments: the work-item being run, the list of values returned by the work-item function, and the error signaled when running the function (if any).

A different report-end function can be specified when a work-item is created by a call to process-pool-run and that report-end function will run instaed of this default report-end function. If no report-end value is specified in the process-pool-run, it is this default function that will be run. If you want the report-end function to do nothing, define a function that does nothing and make it the work-item's report-end function in the call to process-pool-run.

See Process pools in multiprocessing.html for more information on process pools.

# process-pool-report-start

Generic Function, multiprocessing package

Arguments: process-pool

The default method for this process-pool accessor returns the value of the `report-start` slot of the argument process-pool instance. The value must be a function designator or `nil`. When called, a report-start function will be passed one argument, the work-item being run.

The `report-start` is the default report-start function applied to work-items run in process-pool. A different report-start function can be specified when a work-item is created by a call to process-pool-run and it will override this default report-start function. If no report-start value is specified then, it is this default function that will be run. If you want the report-start function to do nothing, define a function that does nothing and make it the work-item's report-start function in the call to process-pool-run.

See Process pools in multiprocessing.html for more information on process pools.

# process-pool-reused-count

Generic Function, multiprocessing package

Arguments: process-pool

The default method for this process-pool accessor returns the value of the `reused-count` slot of the argument process-pool instance.

The `reused-count` is the number of times an idle process was re-used. When process-pool-run is called, after perhaps waiting in the work-item queue either (1) an existing idle process is used to run the associated work-item or (2) a new process is created to do so. Whenever (1) occurs (an idle process is used), the value returned by (the default method of) this generic function is increased by 1. Note this occurs even if the process was created as a primed process when the process-pool was created and thus has not yet run a work item. See also process-pool-new-count.

See Process pools in multiprocessing.html for more information on process pools.

# process-pool-run

Generic Function, multiprocessing package

Arguments: pool &key work function arguments name report-start report-end data (queue-p t)

The default method of this generic function (specializing on `nil` and process-pool objects) does two things:

1. Creates a new process-pool-work-item if the work argument is `nil`, or modfies the process-pool-work-item specified by the work argument.

2. Processes that work-item if possible. Processing means running it in the pool specified by the pool argument if that pool has an available idle process or can create a new process, or queueing it in that pool if no idle process is available. If there is no idle process and the queue is full (see process-pool-work-limit which specifies the maximum queue size), then nothing is further is done to the work-item.

Two values are returned:

1. The result of attempting to run or queue the work item. This returned value is one of: `:created` (meaning the work-item started to run in a newly-created pool process); `:started` (meaning the work-item started to run in an existing idle pool process); `:queued` (meaning the work-item was added to the queue of unrun work-items for the pool); or `nil` (meaning the work-item was neither run nor queued).

2. The newly-created or modified process-pool-work-item. While this operator does typically modify work-items passed in as the value of the work argument, it can return the work-item unmodified if the keyword arguments passed in do not necessitate modification. If the first value is `nil`, meaning the work-item was neither run nor queued, the work-item can be later passed as the work keyword argument to process-pool-run in order to attempt to run or queue it again.

Here are the arguments and their meanings:

- pool: This required argument must be a process-pool instance or `nil`. If it is a process-pool instance, the system will try to start running a process-pool-work-item in one of the pool's processes. If it is `nil`, the system will try to start running a process-pool-work-item in the default process-pool (see ensure-default-process-pool). It is an error to specify `nil` when there is no default process-pool. The work-item to be run is either created using the keyword arguments to process-pool-run or is an existing work-item specified by the work keyword argument, possibly modified by the other keyword arguments.
- work: The value of this keyword argument should be either `nil` or an existing process-pool-work-item. If the value is `nil` (which is the default), a new process-pool-work-item will be created with slots specified by the additional keyword arguments to process-pool-run. If the value is an existing work-item (created either by make-process-pool-work-item or by a previous call to process-pool-run), that work-item will be modified by supplied process-pool-run keyword arguments. Note that unsupplied keyword arguments to process-pool-run do not modify the corresponding slot values of an existing work-item.
- function: The actual work of a process-pool-work-item is performed by applying the work-item function, the value of this argument, to the work-item arguments, described below. If supplied, the `function` slot of the supplied (by the work argument) or newly-created process-pool-work-item will be set to the value of this argument. If unsupplied, the `function` slot will be `nil` in a newly-created process-pool-work-item and unchanged in one supplied as the value of the work argument. When the function is `nil`, the work-item does nothing except run the report-start and report-end functions.
- arguments: The actual work of a process-pool-work-item is performed by applying the work-item function (described above) to the work-item arguments, the value of this argument. If supplied, the `arguments` slot of the supplied (by the work argument) or newly-created process-pool-work-item will be set to the value of this argument. If unsupplied, the `data` slot will be `nil` in a newly-created process-pool-work-item and unchanged in one supplied as the value of the work argument.
- name: The value of this keyword argument provides the name that will be used as the process name when the work item is run in a process. If supplied, the `name` slot of the supplied (by the work argument) or newly-created process-pool-work-item will be set to the value of this argument. If unsupplied, the `name` slot will be created by the system in a newly-created process-pool-work-item and unchanged in one supplied as the value of the work argument.
- report-start: If supplied, the `report-start` slot of the supplied (by the work argument) or newly-created process-pool-work-item will be set to the value of this argument. If unsupplied, the `report-start` slot will be `nil` in a newly-created process-pool-work-item and unchanged in one supplied as the value of the work argument. A value of `nil` for the `report-start` slot means the process-pool report-start function will be run at the beginning of running the work-item. It does not mean that no report-start function will be run.
- report-end: If supplied, the `report-end` slot of the supplied (by the work argument) or newly-created process-pool-work-item will be set to the value of this argument. If unsupplied, the `report-end` slot will be `nil` in a newly-created process-pool-work-item and unchanged in one supplied as the value of the work argument. A value of `nil` for the `report-end` slot means the process-pool report-end function will be run at the end of running the work-item. It does not mean that no report-end function will be run.
- data: If supplied, the `data` slot of the supplied (by the work argument) or newly-created process-pool-work-item will be set to the value of this argument. If unsupplied, the `data` slot will be `nil` in a newly-created process-pool-work-item and unchanged in one supplied as the value of the work argument.
- queue-p: If the value of this keyword argument is non-`nil` (the default), then if the work-item cannot be run immediately because the maximum number of active processes in the pool are already running (see process-pool-active-limit), then the work-item will be added to the pool queue if possible (see process-pool-work-limit). If queue-p is `nil`, the work-item will not be queued if it cannot immediately be run and process-pool-run will return `nil` as its first return value.

See Process pools in multiprocessing.html for more information on process pools.

# process-pool-saved-count

Generic Function, multiprocessing package

Arguments: process-pool

The default method for this process-pool accessor returns the value of the `saved-count` slot of the argument process-pool instance.

The `saved-count` slot holds the number of times a process was added to the idle list. When a process finishes running a process-pool-work-item, the process is typically added to the list of idle processes so it is available to run another work item. When that happens, the `saved-count` is incremented by one.

The process may not be added to the idle list under certain circumstances. If the process was killed (perhaps because discard-process-pool was called with the kill argument true), it cannot be added to the idle list. If there are already process-pool-idle-limit idle processes, then the process will be discarded.

See Process pools in multiprocessing.html for more information on process pools.

# process-pool-stack-allocation

Generic Function, multiprocessing package

Arguments: process-pool

The default method for this process-pool accessor returns the value of the `stack-allocation` slot of the argument process-pool instance.

The value of the `stack-allocation` slot is what is passed to mp:make-process as the value of its stack-allocation argument when a new process is created for the process-pool. See the description of mp:make-process for complete details.

See Process pools in multiprocessing.html for more information on process pools.

# process-pool-waiting

Generic Function, multiprocessing package

Arguments: process-pool

The default method for this process-pool accessor returns the value of the `waiting` slot of the argument process-pool instance.

The value of the `waiting` slot is the number of work-items in the queue at the moment the call to the reader is evaluated.

See Process pools in multiprocessing.html for more information on process pools.

# process-pool-work-item-active-p

Generic Function, multiprocessing package

Arguments: work-item

Return true when the work-item (which must be a process-pool-work-item) is in a pool work queue or the work function is running.

See Process pools in multiprocessing.html for more information on process pools.

# process-pool-work-item-data

Function, multiprocessing package

Arguments: process-pool-work-item

The function returns the value of the `data` slot of the argument process-pool-work-item.

See the description of process-pool-work-item for information on this slot.

See Process pools in multiprocessing.html for more information on process pools.

# process-pool-work-item-end-time

Function, multiprocessing package

Arguments: process-pool-work-item

The function returns the value of the `end-time` slot of the argument process-pool-work-item.

See the description of process-pool-work-item for information on this slot.

See Process pools in multiprocessing.html for more information on process pools.

# process-pool-work-item-error

Function, multiprocessing package

Arguments: process-pool-work-item

The function returns the value of the `error` slot of the argument process-pool-work-item.

See the description of process-pool-work-item for information on this slot.

See Process pools in multiprocessing.html for more information on process pools.

# process-pool-work-item-property-list

Function, multiprocessing package

Arguments: process-pool-work-item

The function returns the value of the `property-list` slot of the argument process-pool-work-item.

See the description of process-pool-work-item for information on this slot.

See Process pools in multiprocessing.html for more information on process pools.

# process-pool-work-item-queued-time

Function, multiprocessing package

Arguments: process-pool-work-item

The function returns the value of the `queued-time` slot of the argument process-pool-work-item.

See the description of process-pool-work-item for information on this slot.

See Process pools in multiprocessing.html for more information on process pools.

# process-pool-work-item-start-time

Function, multiprocessing package

Arguments: process-pool-work-item

The function returns the value of the `start-time` slot of the argument process-pool-work-item.

See the description of process-pool-work-item for information on this slot.

See Process pools in multiprocessing.html for more information on process pools.

# process-pool-work-item-values

Function, multiprocessing package

Arguments: process-pool-work-item

The function returns the value of the `values` slot of the argument process-pool-work-item.

See the description of process-pool-work-item for information on this slot.

See Process pools in multiprocessing.html for more information on process pools.

# process-pool-work-limit

Generic Function, multiprocessing package

Arguments: process-pool

The default method for this process-pool accessor returns the value of the `work-limit` slot of the argument process-pool instance.

The value of the `work-limit` slot is the maximum number of pending work items allowed in the queue. When this limit is reached, process-pool-run returns `nil`.

See Process pools in multiprocessing.html for more information on process pools.

# process-preset

function, multiprocessing package

Arguments: process initial-function &rest initial-args

This function sets the initial function and arguments of process, then resets any computation in progress in it. This does not make process active if it was not already active.

process-preset will signal an error if process is an immigrant process.

process-preset is an extended operation that is not atomic in Allegro CL implementations.
process-preset is implemented with a process-interrupt call that causes a throw past the current initial-function of the process. Another process-interrupt call, or any unwind-protect clauses in the current call chain can interrupt this throw and cancel or modify the effect of the process-preset. Therefore, only a cooperating process can be expected to complete a process-preset call in all cases. An application cannot assume that a process-preset will always be effective if the target process is not expecting it.

Example:

    Process A:  (with-timeout (2 (do-something)) (work))

    Process B: Calls (process-preset A 'foo) while A is in (work).

The timeout in A can interrupt a process-preset and leave A in do-something with the process-initial-function set to foo, but foo is never called.

Solution:

    Process B:
      ;; Notify A that a process-preset is needed.
      (setf (getf (process-property-list A) 'preset-in-progress)
            (list 'foo))
      (process-preset A 'foo)

    Process A:
      (with-timeout (2
                     (let ((preset (getf (process-property-list
                                          *current-process*)
                                         'preset-in-progress)))
                        (when preset
                  ;; If a process-preset was interrupted by the
                  ;; timeout, resume the process-preset operation.
                          (apply #'process-preset *current-process* preset)))
                     (do-something))
                (work))

The above example is only an outline that illustrates the kind of action that must be taken. Additional interlocks and bookkeeping may be needed to make this solution totally bomb-proof.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# process-priority

function, multiprocessing package

Arguments: struct

Returns the priority of process, which must be an instance of mp:process. Priority may be any real number. It defaults to 0. It may be reset with setf and this function.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# process-progn

Macro, multiprocessing package

Arguments: process-form &body body

Evaluates the process-form to get a process which will be interrupted to run the body code. The process evaluating the process-progn form waits for the result(s) and returns it/them as the result of the process-progn form.

See multiprocessing.html for general information on multiprocessing.

# process-property-list

function, multiprocessing package

Arguments: process

Returns the property-list of process, which must be an instance of mp:process. The property-list slot of a process implements a generalized property list as a convenient place to store additional information about a process. This slot may be changed with setf, although it is more usual to use the generalized property list functions on it.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# process-quantum

function, multiprocessing package

Arguments: process

This function and its associated value are ignored in SMP images.

Returns the quantum of process, which must be an instance of mp:process. The value is the number of seconds this process can hold the lisp heap before it will allow other ready processes a chance to run. Each time this process runs, the system should grant it at least this amount of time before preempting execution for another process. Currently defaults to 2, and may be set to any number greater than or equal to 0.1 and less than or equal to 20 with setf. The units are seconds.

In both process implementations, when a process starts running a timer interrupt is scheduled to go off after the quantum (real-time) expires. The process might block for some reason before the timer interrupt comes in, and in that case the interrupt is canceled. There are also reasons why the timer interrupt might be ignored for some time after it comes in: fast code (that does not check for interrupts, see generate-interrupt-checks-switch), atomic code (that explicitly ignores interrupts -- see without-interrupts, e.g.), and garbage collection are three examples. But once the timer interrupt is noticed, the process will quit running so other processes can get a chance.

On :os-threads implementations, all other processes will get a chance to run. On non :os-threads implementations, all processes with equal or higher priority get a chance to run.

In :os-threads implementations, a foreign call that releases the heap allows other processes to grab the heap. The process that made the call is still facing the interrupt-after-quantum, even though it may block on heap access when it returns from the foreign call.

If Lisp as a whole isn't getting many cycles, the cpu time corresponding to the real-time quantum may be pretty small, leading to virtual process thrashing.

Thus, there isn't too much we can say for sure about how much time the process will get to run before being preempted, except that for well behaved Lisp processes, it will normally be approximately equal to the process quantum.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# process-queue-interrupt

Generic Function, multiprocessing package

Arguments: process function &rest args

Like mp:process-interrupt (see that function for a description of the arguments) but calls the interruptions with with-delayed-interrupts being in effect which guarantees order of arrival processing.

Let us say we have three processes, p1, p2, and p3. p2 evaluates

       (mp:process-queue-interrupt p1 #'(lambda ()
         (format t "p2 interrupt processed!~%")))

p3 evaluates

       (mp:process-queue-interrupt p1 #'(lambda ()
         (format t "p3 interrupt processed!~%")))

Then when p1 next runs, it will run those functions in the order in which the interrupts arrived (whatever that is) rather than in a random order.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# process-reset

function, multiprocessing package

Arguments: [for non-OS-threds] process &optional no-unwind kill

Arguments: [for OS-threds] process &optional no-unwind

This function causes process when it next runs to throw out to its present computation, if any, then apply its initial function to its initial argument. The no-unwind argument controls what happens to process' present computation, if it has one. `nil` (the default) or `:unless-current` cause the process to be unwound unless it is the current process. `t` unconditionally skips the unwind. Any other value is equivalent to `t`, causing an unconditional unwind, which will throw out of the caller even if the process being reset is current.

The argument kill must be `nil`. (It is maintained only for backward compatibility). An error is signaled if it is not.

If process is an immigrant process, an error is signaled.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# process-resume-hook

function, multiprocessing package

Arguments: struct

It is normal for the system to interrupt execution of a process many times during its execution. This is transparent to the process and usually it is not necessary for the process to know when its execution is suspended and resumed. However, if the resume-hook and the suspend-hook (accessed by process-suspend-hook) are true, they should be functions of no arguments which are called on process each time the scheduler resumes or suspends its execution.

In the native threads implementation, a process can release the heap for another process to run even though the first process is not truly suspending. A foreign call can release the heap, after which it may block, e.g., in a GetMessage call in windows, or continue to process in the background outside the lisp heap. In the native-threads model the suspend-hook is called whenever a process releases the heap and the resume-hook is called whenever it reacquires the heap.

Note that the resume hook is not called when a process is first started, nor the suspend hook when its computation completes. If execution of the hooks at these times is needed, they must be called explicitly by the process' computation.

These hooks are primarily intended for window systems which may need to be informed about process switches in order to track changes of I/O streams. Use for other purposes may conflict with this usage.

#### process-suspend-hook and process-resume-hook will go away soon

Currently a programmer can set a process's process-suspend-hook and be sure that whenever the process's execution is interrupted and another process allowed to run, the hook will get executed. Similarly, when a process regains control after another process has been running, its process-resume-hook, if any, will be run before its execution continues.

Unfortunately, suspend-hooks and resume-hooks cause problems for native thread implementations and other proposed enhancements in the multiprocessing model.

Therefore, these features will likely be removed in the next release. If you use these features, please contact support@franz.com so we can assist you in providing alternatives when these features are removed.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# process-revoke-arrest-reason

function, multiprocessing package

Arguments: process object

This function removes object from the list of arrest reasons for process.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# process-revoke-run-reason

function, multiprocessing package

Arguments: process object

This function removes object from the list of run reasons for process.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# process-run-function

function, multiprocessing package

Arguments: name-or-options preset-function &rest preset-arguments

This function does a make-process, then presets the new process with preset-function and preset-arguments. The first argument is either a string, which is the name of the process, or is a list of keyword arguments accepted by make-process. Note the new class keyword argument to make-process. That can be one of the arguments and specifies the class of process to create. The default for class is mp:process.

The new process is returned. By default, the process is killed when and if it completes. See also process-run-restartable-function.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# process-run-reasons

function, multiprocessing package

Arguments: struct

This function returns the list of run-reasons for process. The list can be changed with setf or related macros and this function or with process-add-run-reason. Any Lisp object can be on the list. A process will not run unless it has at least one run reason and no arrest reasons (see process-arrest-reasons).

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# process-run-restartable-function

function, multiprocessing package

Arguments: name-or-options preset-function &rest preset-arguments

This function is just like process-run-function, but automatically provides a reset-action argument of `t` in the call to make-process. The process thus started will restart if it is reset or completes.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# process-runnable-p

function, multiprocessing package

Arguments: process

This function returns `t` if process is runnable.

A process is active (see process-active-p) if it has been reset and not yet completed, and has at least one run reason and no arrest reasons. It is runnable if it is active and not waiting.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# process-sequence

Function, multiprocessing package

Arguments: process

The default method for this generic function returns a unique integer assigned when the process is created. This value can be used to identify the process to other operators and to top-level commands.

# process-sleep

function, multiprocessing package

Arguments: seconds &optional whostate

process-sleep suspends the current process for at least the number of seconds specified. That number may be any non-negative, non-complex number. While the process sleeps, other processes are allowed to run. The whostate (default "Sleep") is a string which temporarily replaces the process' whostate during the sleep.

When multiprocessing is enabled in the Lisp world (perhaps with a call to start-scheduler), the standard Common Lisp function sleep is changed to be equivalent to process-sleep. Instead of causing the entire Lisp world to suspend execution for the indicated time, only the executing process is suspended. This is usually the desired action.

There is a certain amount of overhead in time and space every time process-sleep is called. A loop that includes a sleep of constant length might be made more efficient by using the macro do-periodically.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# process-suspend-hook

function, multiprocessing package

Arguments: struct

It is normal for the scheduler or the operating system to interrupt execution of a process many times during its execution. This is transparent to the process and usually it is not necessary for the process to know when its execution is suspended and resumed. However, if the resume-hook (accessed by process-resume-hook) and the suspend-hook are true, they should be functions of no arguments which are called on process' stack-group each time the scheduler resumes or suspends its execution.

Note that the resume hook is not called when a process is first started, nor the suspend hook when its computation completes. If execution of the hooks at these times is needed, they must be called explicitly by the process' computation.

In the native threads implementation, a process can release the heap for another process to run even though the first process is not truly suspending. A foreign call can release the heap, after which it may block, e.g., in a GetMessage call in windows, or continue to process in the background outside the lisp heap. In the native-threads model the suspend-hook is called whenever a process releases the heap and the resume-hook is called whenever it reacquires the heap.

These hooks are primarily intended for window systems which may need to be informed about process switches in order to track changes of I/O streams. Use for other purposes may conflict with this usage.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

#### process-suspend-hook and process-resume-hook will go away soon

Currently a programmer can set a process's process-suspend-hook and be sure that whenever the process's execution is interrupted and another process allowed to run, the hook will get executed. Similarly, when a process regains control after another process has been running, its process-resume-hook, if any, will be run before its execution continues.

Unfortunately, suspend-hooks and resume-hooks cause problems for native thread implementations and other proposed enhancements in the multiprocessing model.

Therefore, these features will likely be removed in the next release. If you use these features, please contact support@franz.com so we can assist you in providing alternatives when these features are removed.

# process-terminate

Generic Function, multiprocessing package

Arguments: process

This generic function is called on every process that terminates normally (i.e., not killed with :no-unwind). The primary method defined on process objects, which should not be displaced, executes all the process-exit-actions.

See multiprocessing.html for general information on multiprocessing.

# process-thread

Generic Function, multiprocessing package

Arguments: process

Returns the thread of process, which must be an instance of mp:process.

In earlier releases, this operator only worked in :os-threads implementations and process-stack-group was used in non-:os-threads implementations. process-stack-group has been removed and this operator works in all implementations now.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# process-times-resumed

Function, multiprocessing package

Arguments: process

Returns the number of times the argument process acquired ownership of the heap.

See multiprocessing.html for general information on multiprocessing.

# process-times-resumed-delta

Generic Function, multiprocessing package

Arguments: process

Returns the change in process-times-resumed since the last call of process-times-resumed. When process-times-resumed has never been called on process, returns what process-times-resumed would return.

See multiprocessing.html for general information on multiprocessing.

# process-unlock

function, multiprocessing package

Arguments: lock &optional lock-value

This function unlocks lock. If lock is not locked, or the supplied lock-value does not agree with the value stored in the locker slot of lock, an error is signaled. The default value for lock-value is the value of *current-process*.

See also process-lock, process-lock-locker (which accesses the value in the locker slot), with-process-lock, and make-process-lock.

See multiprocessing.html for general information on multiprocessing in Allegro CL and see Process locks for more information on process locks in Allegro CL.

# process-wait

function, multiprocessing package

Arguments: whostate function &rest arguments

This function suspends the current process (the value of *current-process*) until applying the wait function function to arguments yields true. The whostate argument must be a string which temporarily replaces the process' whostate for the duration of the wait. This function returns `nil`.

If the wait function, function, is one of these:

- gate-open-p or `(symbol-function 'gate-open-p)`
- read-no-hang-p or `(symbol-function 'read-no-hang-p)`
- write-no-hang-p or `(symbol-function 'write-no-hang-p)`
- stream-listen or `(symbol-function 'stream-listen)`

then the wait can be scheduled without any additional effort. If a more general wait funtion is used, then in the native threads model Allegro CL starts a non-process support thread to make sure the general wait conditions are tested periodically. They will be tested in any event before the lisp goes idle, but the general-wait-tester, as it's called, ensures that the tests are made at reasonable intervals. See also *general-wait-delay*.

See Gates in multiprocessing.html for a discussion of gates, one of the efficient choices.

Wait functions get called arbitrarily many times and they may be called in a dynamic state (and in a thread) other than that of the waiting thread that specified it. They are typically also called even after they have returned non-`nil` (that is, after they have already indicated the wait is over). Because of this, wait functions with side effects should be coded very carefully so that the multiple calls and calls after they have returned non-`nil` do not cause problems. And all wait funcions:

- should be fast
- must do no i/o
- in a non-SMP Lisp, should not reference dynamic-extent data, as such data may not be visible from a thread other than the one which allocated the data while the wait function may be called from any thread. (In SMP Lisps not only is all stack-allocated data visible to all threads, but wait functions are always run on the thread doing the wait, within the dynamic environment of the wait, so all stack-allocated data is still valid.)
- must not process windows messages
- must not wait on anything (directly or indirectly, so no calls to sys:with-timeout or with-process-lock, for example)
- must not contain without-interrupts or without-scheduling forms

If a wait function signals an error, the waiting thread will no longer be waiting; it will call the wait function again, outside the scheduling regime, and react there to the signalled error.

See the discussion in the following sections in multiprocessing.html for information on why not to use this function when waiting for input from a file.

- Waiting for input from a stream
- mp:process-wait vs mp:wait-for-input-available

See also wait-for-input-available and waiting-for-input-available.

See About design considerations for event-driven applications in cgide.html and post-funcall-in-cg-process if you intend to call this function is a Common Graphics process.

### Arbitrary wait functions in non-SMP Lisps

Handling arbitrary wait functions may require a heartbeat process must be running (one is already running in SMP Lisps). You can do this be evaluating:

    (mp:process-run-function "heartbeat" #'(lambda () (loop (sleep 1))))

If no heartbeat is running, you may get a bus error with an arbitrary wait function.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# process-wait-args

function, multiprocessing package

Arguments: struct

This function returns the list of arguments passed to the wait function (see process-wait-function) when determining when a waiting process becomes runnable. See process-wait.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# process-wait-function

function, multiprocessing package

Arguments: process

This function returns the function used to determine when a waiting process becomes runnable. The function is the one specified to the currently active call to process-wait on process. Wait functions are fully described in the process-waitdescription.

(If process is not waiting, process-wait-function returns `nil`.)

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# process-wait-with-timeout

function, multiprocessing package

Arguments: whostate seconds function &rest args

This function is similar to process-wait, but with a timeout. The units of time are seconds. The value of seconds may be any real number. Negative values are treated the same as 0. The wait will timeout if function does not return true before the timeout period expires.

Like process-wait, function will be repeatedly applied to args. process-wait-with-timeout will return `t` if the result of the call to function is non-`nil`. process-wait-with-timeout returns `nil` if it timed out before detecting that function applied to args returned true.

The whostate argument must be a string which temporarily replaces the process' whostate for the duration of the wait.

The time granularity is system dependent. As a very rough guide, we can say that many Unix systems show a granularity of 0.08 but the value on your system may be different. You should test your own system if you want to call this function with small values of seconds. Values smaller than the granularity value may timeout immediately.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# process-whostate

function, multiprocessing package

Arguments: struct

This function returns the current who-line string of process. This string can be used by a window system, for example, as a prompt or to indicate something about the status of the process. May be set with setf.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# profile-process-p

function, multiprocessing package

Arguments: process

This function returns the value of the profile-process-p flag for the thread/process specified by process. If the value of the flag is true, then the space and time runtime analyzers will collect samples when this process is executing.

This value may be changed with setf.

See multiprocessing.html for general information on multiprocessing in Allegro CL. See also Processes and the runtime analyzer in that document and runtime-analyzer.html.

# put-semaphore

Function, multiprocessing package

Arguments: gate

Gates can be used as semaphores. Each gate created by make-gate has an associated semaphore count that starts at 0. put-semaphore increments the gate's semaphore count, opens the gate, and then releases just one of the threads waiting on that gate, if there are any. This differs from a call to open-gate, which releases all threads waiting on the gate. This can be more efficient than open-gate when several threads are processing a work queue. mp:enqueue and mp:dequeue use semaphores internally to get the improved efficiency. See get-semaphore.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# query-process-pool

Generic Function, multiprocessing package

Arguments: pool &key stream

Display on stream information about the specified process-pool. If pool is `nil`, displays information about the default process-pool (see ensure-default-process-pool). The default for stream is *standard-output*.

The stream argument may also be `nil` to return the status output in a new string, or a string with fill pointer to be updated with the output.

### Example:

    ;; Here is part of the information printed about the default process-pool
    ;; (specified by NIL as the value of the POOL argument):
    ;;
    cl-user(166): (query-process-pool nil)

    ;;; Process Pool  Default process pool  Status
    ;;         Work items waiting for a process: 0
    ;;     Idle processes waiting to be re-used: 1
    ;;                 Active processes running: 0

    ;;;    Process Pool Parameters
    ;;                   Limit to number of retained idle processes: nil
    ;;                  Limit to number of active processes running: nil
    ;;                 Idle processes retained forever
    ;;               Limit to number of queued work items: none
    [...]

See Process pools in multiprocessing.html for more information on process pools.

# queue-empty-p

Generic Function, multiprocessing package

Arguments: queue

The default method (specialized on queues that are an instances of the queue) returns true when queue has no queued data.

See Queues in multiprocessing.html for more information.

# queue-length

Generic Function, multiprocessing package

Arguments: queue

Returns the current size of the queue specified by the argument. Note that in a multiprocessing environment, the return value may no longer be valid after this function returns.

See Queues in multiprocessing.html for more information.

# set-process-pool

Generic Function, multiprocessing package

Arguments: pool &key work-limit process-limit active-limit idle-limit idle-timeout name report-start report-end

This generic function modifies a process-pool object with the values supplied by the keyword arguments. pool must be a process-pool or `nil`, with `nil` indicating the default process-pool (see ensure-default-process-pool).

If an argument is not specified, then the associated slot of the process-pool being modfied is left unchanged. So, for example, if the process-pool's `report-start` slot has value my-report-start-function and the report-start argument is not specified, the slot value will still be my-report-start-function when set-process-pool returns.

See make-process-pool for the meanings of the arguments.

See Process pools in multiprocessing.html for more information on process pools.

# sharable-lock-idle-p

Generic Function, multiprocessing package

Arguments: sharable-lock &optional modifier whostate

The method defined when the first argument is a sharable-lock instance examines the state of the lock and returns `t` if the lock is idle, or `nil` if it is not. The optional arguments add some additional behavior.

modifier | whostate | Behavior
`nil` | [ignored] | Test the lock and return immediately.
`n` <= 0 | [ignored] | Test the lock and return immediately.
`n` > 0 | A string, will be the whostate while waiting. Default is "sharable-lock-idle-p" in modern Lisps and "SHARABLE-LOCK-IDLE-P" in ANSI Lisps. | Test the lock, and if not idle, wait at most n seconds. n may be any real number.
`:show` | [ignored] | Print messages detailing the lock state, and return `t` or `nil`.
`:show-if-not` | [ignored] | Like `:show` but print details only if the lock is not idle.
`:wait` | A string, will be the whostate while waiting. Default is "sharable-lock-idle-p" in modern Lisps and "SHARABLE-LOCK-IDLE-P" in ANSI Lisps. | Test the lock and, if not idle, wait indefinitely until it is idle.
Other non-nil | [ignored] | Test the lock and return immediately.

As in all cases where objects may be modified by multiple threads, the returned value is obsolete the moment it is returned.

See Sharable locks in smp.html.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# sharable-lock-lock

Generic Function, multiprocessing package

Arguments: sharable-lock mode &key yield-rate timeout recursive-p whostate

Acquire a sharable-lock in the specified mode.

If the lock was acquired, The single value returned is one of the keywords:

- `:locked`: the lock was acquired in the requested mode.
- `:recursive`: the lock is already owned in the requested mode. An additional access of the same mode is recorded for this thread.
- `:downgrade`: the lock is already held in exclusive mode, but a shared access from the same thread is recorded as well.
- `:upgrade`: the lock is already held in shared mode; and additional shared access from the same thread is recorded.

If the call fails to acquire the lock, two values are returned. The first value is `nil` to indicate failure. The second value is a keyword that describes the reason:

- `:timeout`: a timeout occurred before the lock could be acquired.
- `:exclusive`: an exclusive locker prevented access.
- `:shared`: one or more shared lockers prevented access. An exclusive lock is delayed by any shared lockers. A shared lock is delayed if max-shared lockers are already locking.
- `:busy`: one or more other lockers prevented access but it was not possible to tell which case. Another attempt to acquire the lock is likely to give another answer.
- `:recursive-error`: a recursive locking attempt is not allowed because of the recursive-p setting.
- `:downgrade-error`: a downgrade is not allowed because of the recursive-p setting.
- `:upgrade-error`: an upngrade is not allowed because of the recursive-p setting.
- `:interrupting`: the locking call is in a process-interrupt function that has interrupted another locking attempt in a place that does not allow any recursion. Another attempt is likely to succeed, but the attempt must be made with a new call to process-interrupt. Looping or waiting in the process-interrupt function is futile and counterproductive.
- `:downgrade-state-error`: probably an implementation error
- `:upgrade-state-error`: probably an implementation error

The mode argument must be one of the keywords `:shared` or `:exclusive`.

The yield-rate argument, if specified, must be a positive integer, or the keyword `:never`. The specified value overrides the value in the lock instance. If the argument is omitted, or specified as `nil`, than the value in the lock instance is used.

The timeout argument, if specified, must be a non-negative number of seconds. The value determines how long the program will wait if the lock is not immediately available. A timeout value of zero specifies that that the lock must be available immediately only.

The recursive-p argument may be used to override the recursion specification in the sharable-lock instance. If omitted, `nil` or `:default`, the value in the lock instance is used. Otherwise, the value must be `t`, one of the keywords allowed in make-sharable-lock, or a list of these keywords. If the recursive-p setting does not allow a recursive or repeated call, the behavior is determined by the timeout argument. If the timeout argument is omitted, or non-zero, an error of type sharable-lock-recursion-error is signaled; otherwise one of the above keywords is returned as the second value.

When the timeout value is greater than zero, and a timeout occurs, the second value is `:timeout`.

When the timeout value is zero, the lock is acquired only if there is no delay. If there would be a delay, the second value is one of the keywords listed above.

The whostate argument is passed to process-wait if it must be called while acquiring the lock. If the caller does not provide a value for this argument, a built-in value is used. It typically describes the internal reason for the wait operation.

See Sharable locks in smp.html.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# sharable-lock-unlock

Generic Function, multiprocessing package

Arguments: sharable-lock mode

Release a sharable-lock in the specified mode.

The value returned is `nil` or one of the keywords `:unlocked` or `:recursive`.

The mode argument must be one of the keywords `:shared` or `:exclusive`.

If the lock is locked in the specifed mode, the locker count is decremented. If the count is still not zero, the keyword `:recursive` is returned. If the count is zero, the keyword `:unlocked` is returned.

If the lock is not locked, and safe-p (when the lock was created with make-sharable-lock) is `nil`, `nil` is returned.

Note that a call to sharable-lock-unlock can only release a lock acquired with a call to sharable-lock-lock. The locks established with the with-shared-lock and with-exclusive-lock macros can only be released by exiting the dynamic context of the macro calls.

See Sharable locks in smp.html.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# shared-locker-count

Generic Function, multiprocessing package

Arguments: sharable-lock &optional clean-p

Return the number of shared users locking a sharable-lock at some instant.

The clean-p has effect only to sharable-lock instances created with the auto-unlock-p to make-sharable-lock specified true (the default value is `nil`). In that case, when the clean-p argument is non-`nil`, the current owners of the lock are scanned to remove any dead processes associated with the lock. The returned count is the number of live processes associated with the lock.

Note that this value may be obsolete and incorrect as soon as it is returned.

See Sharable locks in smp.html.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# start-customs

function, multiprocessing package

Arguments: &optional name

This function ignores its argument and simply calls start-scheduler if necessary. Calls to start-customs are deprecated and should be replaced with calls to start-scheduler.

In earlier releases, if non-lisp threads were going to use callback functions to invoke lisp code, then a "customs" process had to be running to assign each such thread a lisp process, when the thread first tries to invoke lisp code. start-customs started such a process. However, now this is all handled automatically and tranparently to the programmer. Thus this function is no longer needed. It is kept (and calls start-scheduler) because there may be applications that call start-customs to start multiprocessing as well as to perform the (no longer necessary) task of handling the call backs described above.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# start-scheduler

function, multiprocessing package

Arguments:

Multiprocessing is not automatically started in the default Allegro CL environment.

This function starts multiprocessing, which is also started automatically the first time a process is started by process-reset, directly or indirectly (as by process-run-function). There is in fact no scheduler process. In a virtual thread Lisp, runnable processes are queued by priority and run (for a quantum of time) according to the queue. In os-thread and SMP Lisps, the OS decides what processes to run. The name start-scheduler dates from earlier releases where there was an actual scheduler process.

Even in an SMP Lisp, it is possible to start Lisp without the multiprocessing module loaded. A call to start-scheduler ensures the mp module is loaded. (Other functionality has the same effect, but calling start-scheduler guarantees things.) Also, if you use immigrant threads in a non-SMP Lisp, you might want to call start-scheduler to be sure the system is initialized properly for the immigrant threads.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# symeval-in-process

function, multiprocessing package

Arguments: symbol process

This function returns two values. The first is the value of the special symbol in the given process (which may be the current process). It only looks for actual bindings on the process; if the symbol has a global value but is not bound on the process, the global value is not returned.

The second returned value describes the status of the binding. t is returned if the symbol is bound on the process, `nil` if the symbol has no binding, and `:unbound` if there is a binding which has been subjected to makunbound. In the latter two cases, the first returned value is `nil`.

setf understands this function. An error is signaled if the symbol has no binding on the process, i.e., if symeval-in-process would return `nil` as the second value.

It is only possible to retrieve or set the innermost (most-recent) binding of a special symbol. This function is intended for use by debuggers and is not appropriate for normal programming.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# wait-for-input-available

function, multiprocessing package

Arguments: *stream-or-fds &key wait-function whostate timeout

This lower-level function extends the capabilities of mp:process-wait and mp:process-wait-with-timeout to allow a process to wait for input from multiple streams and to wait for input from a file.

The stream-or-fds argument may be a single element or a list of elements. Each element may be a stream object or a file descriptor obtained from the operating system (typically a small non-negative integer).

This function waits for input to become available on any of the streams, and when that happens a list of streams/fds (some subset of the given stream-or-fds argument) that have input available is returned. Here have input available means (when the default wait-function is used) that a subsequent call to read-char or read-byte will immediately return without blocking. (It might return end-of-file status, however).

The wait-function argument should be a function that accepts one argument. If a single stream-or-fd is passed as the stream-or-fds argument, then the wait function will be called with that stream-or-fd. If a list of stream-or-fds is supplied to wait-for-input-available then the wait function will be called on each of those stream-or-fds in turn until it returns non-`nil`. If the wait function returns `nil` when applied to every one of the stream-or-fds on the first pass, then this process goes into a wait, with enough information handy to let us do an appropriate select-equivalent OS call when there are no processes ready to run.

The default value for the wait-function keyword argument is `#'stream-listen`. This generic function has methods defined both for integer file descriptors and for terminal, socket, or other "interactive'' streams. This function may be applied to streams that do not have a corresponding file descriptor, such as a window-stream (in Common Windows on Unix).

If you supply your own wait-function, it must determine whether input is available for there is no additional test made by wait-for-input-available beyond the value returned by the wait function.

While waiting, the current process's whostate is set to the value specified for the whostate keyword argument, defaulting to "waiting for input", as if a process-wait or process-wait-with-timeout were being called. If a value is specified for the timeout keyword argument and no stream has input available before the timeout occurs, `nil` is returned. The value of the timeout argument (if it is specified) should be a non-negative real number. The units are seconds. Note that a value less than the granularity of the system will timeout immediately.

See the discussion in the following sections in multiprocessing.html for information on why to use this function rather than process-wait when waiting for input from a file. Note that the :os-threads and non :os-threads versions are discussed in different sections.

- Waiting for input from a stream
- mp:process-wait vs mp:wait-for-input-available

See also process-wait and waiting-for-input-available.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# wait-for-io-available

Function, multiprocessing package

Arguments: input-streams output-streams &key input-wait-function output-wait-function whostate timeout

This function is similar to wait-for-input-available but allows an application to wait for output possible on one set of streams as well as for input availble on another set.

The function returns `nil` or a list of items of the form `(stream . status)` where `stream` is a stream from one of the lists in the first two arguments and `status` is one of the following keywords:

- `:in`: the associated `stream` is one of the input-streams and the input-wait-function returned a non-`nil` value.
- `:in-error`: the associated `stream` is one of the input-streams and the input-wait-function signaled an error.
- `:out`: the associated `stream` is one of the output-streams and the output-wait-function returned a non-`nil` value.
- `:out-error`: the associated `stream` is one of the output-streams and the output-wait-function signaled an error.

The input-streams and output-streams arguments must be lists of streams or file descriptor integers or a single stream or file descriptor integer or `nil`. If both are `nil`, wait-for-io-available returns `nil` immediately.

The input-wait-function argument, if supplied, must be name a function which accepts one argument, which is applied to each item in the input-streams list before a system wait is initiated, and after a system wait returns. The default function is stream-listen.

The output-wait-function argument, if supplied, must name a function which accepts one argument, which is applied to each item in the output-streams list before a system wait is initiated, and after a system wait returns. The default function is an internal function that attempts to write an empty array of octets to the stream.

The whostate argument is used as the whostate during a system wait. The default value is "waiting for i/o".

The timeout argument must be `nil` or a number. `nil` specifies an indefinite wait, a number specifies a number of seconds.

When called, this function applies input-wait-function to every element of input-streams and output-wait-function to every element of output-streams. If any application errors or returns non-`nil`, then a list of all cases of erroring or returning non-`nil` is collected and returned, the list being as described above. (Of course, the information is based on when the functions are applied to the streams and the state may changed even before wait-for-io-available returns.)

If all applications of the functions return `nil`, a system wait is called that monitors all the specified I/O devices. When the system wait returns, the wait functions are again applied as above with a result being returned if any function call errors or returns non-`nil`. If timeout is a number, wait-for-io-available returns `nil` after that number of seconds. If timeout is `nil`, wait-for-io-available returns only when some application of a wait function errors or returns non-`nil`.

# waiting-for-input-available

macro, multiprocessing package

Arguments: (stream-or-fd) &body body

stream-or-fd must be a form evaluating to an input stream or to an integer input-file descriptor.

The forms in the body are evaluated inside an environment that places the file or descriptor on a list of "interesting" objects. If the lisp process executing this form goes into a wait while executing the body, and data becomes available on any of the "interesting" files, the process's wait function will be run to see if the wait has been satisfied. This macro is not required if doing simple lisp reads from a file or socket. Special circumstances are required to make this form necessary in application code.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# with-exclusive-lock

Macro, multiprocessing package

Arguments: (sharable-lock &key yield-rate timeout recursive-p) &body body

This macro was part of an early implementation of sharable locks. The values returned are not consistent with other with-XXX macros in Common Lisp. (with-exclusive-lock returns `t` rather than the value of the last body form when the associated lock is acquired.) It is included for compatibility with earlier versions. The recommended macro is with-sharable-lock.

Evaluate a body of code in the context of a sharable-lock acquired in exclusive mode.

The yield-rate argument, if specified, must be a positive integer, or the keyword `:never`. The specified value overrides the value in the lock instance. If the argument is omitted, or specified as `nil`, than the value in the lock instance is used.

The timeout argument, if specified, must be a non-negative number of seconds. The value determines how long the program will wait if the lock is not immediately available. A timeout value of zero specifies that that the lock must be available immediately only.

The recursive-p argument may be used to override the recursion specification in the sharable-lock instance. If omitted, `nil` or :default, the value in the lock instance is used. Otherwise, the value must be `t`, one of the keywors allowed in make-sharable-lock, or a list of these keywords.

The body expressions are evaluated as a progn body. If the lock is acquired, the body forms are evaluated, and the with-exclusive-lock expression returns a single value, `t`. If the lock is not acquired, the with-exclusive-lock expression returns two values as described in sharable-lock-lock.

See Sharable locks in smp.html.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# with-message-interrupts-disabled

Macro, multiprocessing package

Arguments: &body body

Executes the forms of body as a progn inside an environment that has disabled message interrupt processing for this process. The form returns the value or values returned by the last form in the body.

The MS Windows operating system sometimes sends messages to threads and requires a timely response. Failure to respond can degrade system performance or even cause a deadlock.

Because of this, Allegro CL processes (threads) running on a Windows host will watch for messages, even when they are sleeping or are non-dispatchable because of arrest or run reasons. When a message arrives while the process is sleeping, the process's message-interrupt-function (see process-message-interrupt-function) is called as if by a process-interrupt. After the message-interrupt-function returns, the wait state is reentered.

This is the normal state of things, and usually does all that is needed. However, if some function processing a windows message should sleep or otherwise wait, it becomes possible for the message-interrupt-function to get invoked and process the next message before the current message has been fully processed. This can cause serious problems.

The mp:with-message-interrupts-disabled macro allows message-handling code to wait or sleep without risking out-of-sequence message processing.

See multiprocessing.html for general information on multiprocessing.

# with-process-lock

macro, multiprocessing package

Arguments: (lock &key timeout norecursive seized whostate) &body body

This macro executes the body with lock seized. Unlike process-lock, with-process-lock protects against a single process trying to seize a lock it already owns. If executed dynamically inside another with-process-lock for the same lock, and if norecursive is `nil`, with-process-lock behaves as if the lock was seized successfully, and the body is executed. If norecursive is `t`, an error is signaled. The default value of norecursive is `nil`.

If a timeout is specified and non-`nil`, the value should be an integer; the units are seconds. Non-positive timeout values time out immediately. A value of `nil` is equivalent to an unspecified timeout argument.

If the form times out before the lock is available, the with-process-lock form returns `nil` without the body being executed. If you want to take specific action if the lock does not become available when timeout is specified, use a form like this:

    (block ok
      (with-process-lock (lock :timeout 10)
        (return-from ok (progn body-forms ...)))
      (... action if lock never becomes available ...))

If there is a non-local exit from body. the release of the lock is taken care of in an unwind-protect.

See also process-unlock, process-lock-locker, and make-process-lock.

See About design considerations for event-driven applications in cgide.html and post-funcall-in-cg-process if you intend to call this function is a Common Graphics process.

See multiprocessing.html for general information on multiprocessing in Allegro CL and see Process locks for more information on process locks in Allegro CL.

# with-sharable-lock

Macro, multiprocessing package

Arguments: (mode lock &key recursive-p yield-rate timeout timeout-body whostate) &body body

Evaluate a body of code in the context of a sharable-lock acquired in the specified mode. This macro allows more control of the behavior than with-shared-lock or with-exclusive-lock and the values returned by this macro (the value of the last body form when the lock is successfully acquired) is consistent with other with-XXX macros in Common Lisp, unlike with-shared-lock or with-exclusive-lock which return `t`.

This macro is in the `smputil` module and may not be included in the image util `(require :smputil)` is evaluated.

The mode argument must evaluate to one of the keywords `:exclusive` or `:shared`.

The lock argument must evaluate to an instance of sharable-lock.

The yield-rate argument, if specified, must evaluate to a positive integer, or the keyword `:never`. The specified value overrides the value in the lock instance. If the argument is omitted, or specified as `nil`, than the value in the lock instance is used.

The timeout argument, if specified, must evaluate to `nil` or a number of seconds. The value determines how long the program will wait if the lock is not immediately available. A timeout value of zero (or a negative value) specifies that the lock must be available immediately.

The recursive-p argument can be used to override the recursive-p specification in the sharable-lock instance. See make-sharable-lock.

The body expressions are evaluated as a progn body and the returned values are the values of the progn when the lock is successfully acquired. (The return values when the lock is not acquired are described below.)

The timeout-body argument specified the behavior when a timout is requested. The timeout-body argument must be a list of expressions beginning with `nil` or a bound variable list. The default timeout behavior is `((x) (values nil x))`

If a timeout occurs, or when timout is zero or negative and the lock is not available immediately, the first variable in the list of bound variables is bound to the reason for the timeout and the remainder of the timout-body is evaluated as a let body. The values returned by the timeout-body forms are the values returned from the with-sharable-lock form. In the event of a true timeout, the reason is always :timeout, but when timout is zero or negative, the reason may be one of the keywords returned by sharable-lock-lock.

If the timeout does not occur, the timeout-body argument is never evaluated, and the values of the body forms are returned.

The whostate argument is passed to process-wait if it must be called while acquiring the lock. If the caller does not provide a value for this argument, a built-in value is used. It typically describes the internal reason for the wait operation.

See Sharable locks in smp.html.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# with-shared-lock

Macro, multiprocessing package

Arguments: (sharable-lock &key yield-rate timeout recursive-p) &body body

This macro was part of an early implementation of sharable locks. The values returned are not consistent with other with-XXX macros in Common Lisp. (with-shared-lock returns `t` rather than the value of the last body form when the associated lock is acquired.) It is included for compatibility with earlier versions. The recommended macro is with-sharable-lock.

Evaluate a body of code in the context of a sharable-lock acquired in shared mode. This macro is in the `smputil` module and may not be included in the image until `(require :smputil)` is evaluated.

The yield-rate argument, if specified, must be a positive integer, or the keyword `:never`. The specified value overrides the value in the lock instance. If the argument is omitted, or specified as `nil`, than the value in the lock instance is used.

The timeout argument, if specified, must be a non-negative number of seconds. The value determines how long the program will wait if the lock is not immediately available. A timeout value of zero specifies that that the lock must be available immediately only.

The recursive-p argument may be used to override the recursion specification in the sharable-lock instance. If omitted, `nil` or `:default`, the value in the lock instance is used. Otherwise, the value must be `t`, one of the keywords allowed in make-sharable-lock, or a list of these keywords.

The body expressions are evaluated as a progn body. If the lock is acquired, the body forms are evaluated, and the with-shared-lock expression returns a single value, `t`. If the lock is not acquired, the with-shared-lock expression returns two values as described in sharable-lock-lock.

Note that the return value when the lock is acquired is not what is typically returned by with-XXX macros. `t` is returned, not the value of the last body form. As said at the beginning, this macro was part of an early implementation of sharable locks. It is included for compatibility with earlier versions. The recommended macro is with-sharable-lock.

See Sharable locks in smp.html.

See multiprocessing.html for general information on multiprocessing in Allegro CL.

# with-virtual-timeout

macro, multiprocessing package

Arguments: (mode seconds &body timeout-body) &body body

This macro is simlar to sys:with-timeout with the addition of a mode argument. mode must be `:process` or `:thread`. The `:thread` option is only valid in SMP lisps.

When mode is `:process`, the timeout occurs after the specified time (in seconds as for sys:with-timeout) has been used by the cpu when running the Lisp process, not counting time spent doing garbage collection.

When mode is `:thread` (which is allowed in SMP Lisps only), the timeout occurs after the specified time (in seconds as for sys:with-timeout) has been used by the cpu when running thread executing the body code, not counting time spent doing garbage collection.

Contrast this behavior with sys:with-timeout, which times out after time real time seconds. See sys:with-timeout for more information on the other arguments.

Here is an example of code using with-virtual-timeout. We define a variant of y-or-n-p which times out after a specified number of seconds, taking the default value specified in the arguments.

    (defun y-or-n-p-with-virtual-timeout (seconds default &amp;rest args)
      (mp:with-virtual-timeout (:process seconds (format t "[Timed out] ~a~%" default)
             default)
         (apply #'y-or-n-p args)))

See multiprocessing.html for general information on multiprocessing in Allegro CL.

Copyright (c) Franz Inc. Lafayette, CA., USA. All rights reserved.

ToC | DocOverview | CGDoc | RelNotes | FAQ | Index | PermutedIndex
| Allegro CL version 11.0