@node Processes (native threads)
@subsection Processes (native threads)

Process is a primitive representing native thread.

@node Processes dictionary
@subsection Processes dictionary

@cppindex mp_all_processes
@lspindex mp:all-processes

@deftypefun cl_object mp_all_processes ()
@end deftypefun

@defun mp:all-processes

Returns the list of processes associated to running tasks. The list is a
fresh new one and can be destructively modified. However, it may happen
that the output list is not up to date, because some of the tasks has
expired before this copy is returned.

@end defun


@cppindex mp_exit_process
@lspindex mp:exit-process

@deftypefun cl_object mp_all_processes () ecl_attr_noreturn
@end deftypefun

@defun mp:exit_process

When called from a running task, this function immediately causes the
task to finish. When invoked from the main thread, it is equivalent to
invoking @code{ext:quit} with exit code 0.

@end defun


@cppindex mp_interrupt_process
@lspindex mp:interrupt-process

@deftypefun cl_object mp_interrupt_process (cl_object process, cl_object function)
@end deftypefun

@defun mp:interrupt_process process function

Interrupt a task. This @code{function} sends a signal to a running
@code{process}. When the task is free to process that signal, it will
stop whatever it is doing and execute the given function.

@exindex Process interruption
Example:

Kill a task that is doing nothing (See @code{mp:process-kill}).

@lisp
(flet ((task-to-be-killed ()
         ;; Infinite loop
         (loop (sleep 1))))
  (let ((task (mp:process-run-function 'background #'task-to-be-killed)))
    (sleep 10)
    (mp:interrupt-process task 'mp:exit-process)))
@end lisp

@end defun


@cppindex mp_make_process
@lspindex mp:make-process

@deftypefun cl_object mp_make_process (cl_narg narg, ...)
@end deftypefun

@defun mp:make-process &key name initial-bindings

Create a new thread. This function creates a separate task with a name
set to @code {name}, set of variable bindings @code{initial-bindings}
and no function to run. See also @code{mp:process-run-function}. Returns
newly created process.

@end defun


@cppindex mp_process_active_p
@lspindex mp:process-active-p

@deftypefun cl_object mp_make_process (cl_object process)
@end deftypefun

@defun mp:process-active-p process

Returns @code{t} when @code{process} is active, @code {nil}
otherwise. Signals an error if @code{process} doesn't designate a valid
process.

@end defun


@cppindex mp_process_enable
@lspindex mp:process-enable

@deftypefun cl_object mp_process_enable (cl_object process)
@end deftypefun

@defun mp:process-enable process

The argument to this function should be a process created by
@code{mp:make-process}, which has a function associated as per
@code{mp:process-preset} but which is not yet running.  After invoking
this function a new thread will be created in which the associated
function will be executed.

@exindex Possible implementation of @code{mp:process-run-function}:

@lisp
(defun process-run-function (process-name process-function &rest args)
  (let ((process (mp:make-process name)))
    (apply #'mp:process-preset process function args)
    (mp:process-enable process)))
@end lisp
@end defun


@cppindex mp_process_yield
@lspindex mp:process_yield

@deftypefun cl_object mp_process_yield ()
@end deftypefun

@defun mp:process-yield
Yield the processor to other threads.
@end defun


@cppindex mp_process-join
@lspindex mp:process_join

@deftypefun cl_object mp_process_join (cl_object process)
@end deftypefun

@defun mp:process-join process
Suspend current thread until @code{process} exits. Return the result
values of the @code{process} function. If @code{process} is the current
thread, signal an error with.
@end defun


@cppindex mp_process_kill
@lspindex mp:process-kill

@deftypefun cl_object mp_process_kill (cl_object process)
@end deftypefun

@defun mp:process-kill process
Try to stop a running task. Killing a process may fail if the task has
disabled interrupts.

@exindex Killing process
Example:

Kill a task that is doing nothing
@lisp
(flet ((task-to-be-killed ()
         ;; Infinite loop
         (loop (sleep 1))))
  (let ((task (mp:process-run-function 'background #'task-to-be-killed)))
    (sleep 10)
    (mp:process-kill task)))
@end lisp
@end defun


@cppindex mp_process_suspend
@lspindex mp:process-suspend

@deftypefun cl_object mp_process_suspend (cl_object process)
@end deftypefun

@defun mp:process-suspend process
Suspend a running @code{process}. May be resumed with
@code{mp:process-resume}.

@exindex Suspend and resume process
Example:

@lisp
(flet ((ticking-task ()
         ;; Infinite loop
         (loop
            (sleep 1)
            (print :tick))))
  (print "Running task (one tick per second)")
  (let ((task (mp:process-run-function 'background #'ticking-task)))
    (sleep 5)
    (print "Suspending task for 5 seconds")
    (mp:process-suspend task)
    (sleep 5)
    (print "Resuming task for 5 seconds")
    (mp:process-resume task)
    (sleep 5)
    (print "Killing task")
    (mp:process-kill task)))
@end lisp
@end defun


@cppindex mp_process_resume
@lspindex mp:process-resume

@deftypefun cl_object mp_process_resume (cl_object process)
@end deftypefun

@defun mp:process-resume process
Resumes a suspended @code{process}. See example in
@code{mp:process-suspend}.
@end defun


@cppindex mp_process_name
@lspindex mp:process-name

@deftypefun cl_object mp_process_name (cl_object process)
@end deftypefun

@defun mp:process-name process
Returns the name of a @code{process} (if any).
@end defun


@cppindex mp_process_preset
@lspindex mp:process-preset

@deftypefun cl_object mp_process_preset (cl_narg narg, cl_object process, cl_object function, ...)
@end deftypefun

@defun mp:process-preset process function &rest function-args

Associates a @code{function} to call with the arguments
@code{function-args}, with a stopped @code{process}. The function will
be the entry point when the task is enabled in the future.

See @code{mp:enable-process} and @code{mp:process-run-function}.

@end defun


@cppindex mp_process_run_function
@lspindex mp:process-run-function

@deftypefun cl_object mp_process_run_function (cl_narg narg, cl_object name, cl_object function, ...)
@end deftypefun

@defun mp:process_run_function name function &rest funciton-args
Create a new process using @code{mp:make-process}, associate a function
to it and start it using @code{mp:process-preset}.

@exindex mp:process-run-funciton usage
Example:

@lisp
(flet ((count-numbers (end-number)
         (dotimes (i end-number)
	   (format t "~%;;; Counting: ~i" i)
	   (terpri)
	   (sleep 1))))
  (mp:process-run-function 'counter #'count-numbers 10))
@end lisp
@end defun


@cppindex mp_current_process
@lspindex mp:current_process

@deftypefun cl_object mp_current_process ()
@end deftypefun

@defun mp:current-process
Returns the current process of a caller.
@end defun


@cppindex mp_block_signals
@lspindex mp:block-signals

@deftypefun cl_object mp_block_signals ()
@end deftypefun

@defun mp:block-signals
Blocks process for interrupts and returns the previous sigmask.

See @code{mp:interrupt-process}.
@end defun


@cppindex mp_restore_signals
@lspindex mp:restore-signals

@deftypefun cl_object mp_restore_signals (cl_object sigmask)
@end deftypefun

@defun mp:restor-signals sigmask
Enables the interrupts from @code{sigmask}.

See @code{mp:interrupt-process}.
@end defun


@lspindex mp:without-interrupts
@lspindex allow-with-interrupts
@lspindex with-local-interrupts
@lspindex with-restored-interrupts

@defmac mp:without-interrupts &body body

Executes @code{body} with all deferrable interrupts disabled. Deferrable
interrupts arriving during execution of the @code{body} take effect
after @code{body} has been executed.

Deferrable interrupts include most blockable POSIX signals, and
@code{mp:interrupt-thread}. Does not interfere with garbage collection,
and unlike in many traditional Lisps using userspace threads, in ECL
@code{mp:without-interrupts} does not inhibit scheduling of other
threads.

Binds @code{allow-with-interrupts}, @code{with-local-interrupts} and
@code{with-restored-interrupts} as a local macros.

@code{with-restored-interrupts} executes the body with interrupts enabled if
and only if the @code{without-interrupts} was in an environment in which
interrupts were allowed.

@code{allow-with-interrupts} allows the @code{with-interrupts} to take
effect during the dynamic scope of its body, unless there is an outer
@code{without-interrupts} without a corresponding
@code{allow-with-interrupts}.

@code{with-local-interrupts} executes its body with interrupts enabled
provided that for there is an @code{allow-with-interrupts} for every
@code{without-interrupts} surrounding the current
one. @code{with-local-interrupts} is equivalent to:

@lisp
(allow-with-interrupts (with-interrupts ...))
@end lisp

Care must be taken not to let either @code{allow-with-interrupts} or
@code{with-local-interrupts} appear in a function that escapes from
inside the @code{without-interrupts} in:

@lisp
(without-interrupts
  ;; The body of the lambda would be executed with WITH-INTERRUPTS allowed
  ;; regardless of the interrupt policy in effect when it is called.
  (lambda () (allow-with-interrupts ...)))

(without-interrupts
  ;; The body of the lambda would be executed with interrupts enabled
  ;; regardless of the interrupt policy in effect when it is called.
  (lambda () (with-local-interrupts ...)))
@end lisp
@end defmac


@lspindex mp:with-interrupts
@defmac mp:with-interrupts &body body
Executes @code{body} with deferrable interrupts conditionally
enabled. If there are pending interrupts they take effect prior to
executing @code{body}.

As interrupts are normally allowed @code{with-interrupts} only makes
sense if there is an outer @code{without-interrupts} with a
corresponding @code{allow-with-interrupts}: interrupts are not enabled
if any outer @code{without-interrupts} is not accompanied by
@code{allow-with-interrupts}.
@end defmac
