1
0
Fork 0
cl-sites/ecl.common-lisp.dev/static/manual/Native-threads.html

1628 lines
121 KiB
HTML
Raw Permalink Normal View History

2024-12-24 19:15:49 +01:00
<!DOCTYPE html>
<html>
<!-- Created by GNU Texinfo 7.0.3, https://www.gnu.org/software/texinfo/ -->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Native threads (ECL Manual)</title>
<meta name="description" content="Native threads (ECL Manual)">
<meta name="keywords" content="Native threads (ECL Manual)">
<meta name="resource-type" content="document">
<meta name="distribution" content="global">
<meta name="Generator" content="makeinfo">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link href="index.html" rel="start" title="Top">
<link href="Indexes.html" rel="index" title="Indexes">
<link href="index.html#SEC_Contents" rel="contents" title="Table of Contents">
<link href="Extensions.html" rel="up" title="Extensions">
<link href="Signals-and-Interrupts.html#Signals-and-Interrupts" rel="next" title="Signals and Interrupts">
<link href="Foreign-Function-Interface.html#Foreign-Function-Interface" rel="prev" title="Foreign Function Interface">
<style type="text/css">
<!--
/* colors */
a.copiable-link {visibility: hidden; text-decoration: none; line-height: 0em}
div.example {margin-left: 3.2em}
span.r {font-family: initial; font-weight: normal; font-style: normal}
span:hover a.copiable-link {visibility: visible}
strong.def-name {font-family: monospace; font-weight: bold; font-size: larger}
ul.mark-bullet {list-style-type: disc}
@media (prefers-color-scheme: dark) {
/* dark theme */
html { color: seashell;
background: #1A1A1A; }
body { background: #1A1A1A; }
th { border-bottom: 2px solid lightgray; }
h1, h2, h3, h4, h5 { background-image: linear-gradient(to left, #202020, #3A3A3A); }
code, var, code a { color: darkorange;
background: #2A2A2A; }
a { color: seashell; }
pre { background: #2A2A2A;
color: seashell;
/* mark longer code block with stripe on the left */
border-left: 5px solid darkorange;
padding-left: 10px; }
pre.screen { background: #2A2A2A;
border: 1px solid lightgray; }
pre.programlisting { background: #2A2A2A;
border-left: 1px solid lightgray;
border-top: 1px solid lightgray; }
/* we need a light background in order for the images to be readable */
img { background: white }
}
@media (prefers-color-scheme: light) {
/* light theme */
html { background: white }
body { background: white }
th { border-bottom: 2px solid gray; }
h1, h2, h3, h4, h5 { background: lightgray; }
code, var, code a { color: darkred;
background: whitesmoke; }
a { color: #000; }
pre { background: whitesmoke;
color: black;
/* mark longer code block with stripe on the left */
border-left: 5px solid darkred;
padding-left: 10px; }
pre.screen { background: #EEE;
border: 1px solid black; }
pre.programlisting { background: #EEEEEE;
border-left: 1px solid black;
border-top: 1px solid black; }
}
body {
margin: 1em 125px 0 10%;
line-height: 1.5em;
padding: 0 2em 1em 2em;
font: 13px Verdana,Arial, sans-serif
}
ul, dd, dl, dt { margin-top: 0; margin-bottom: 0; }
p, code, td, dl, dt {
line-height: 1.5em;
}
table {
font: inherit;
border-collapse: collapse;
}
th, td {
vertical-align: top;
}
h1, h2, h3 { padding-left: 15px; }
h4, h5 { padding-left: 5px; }
code, pre {
font-size: 1em;
font-family: monospace;
}
var {
font-size: 1em;
}
/* links inside code appear the same as the code itself */
code a {
font-weight: normal;
text-decoration: none;
}
/* but get an underline when hovering */
code a:hover {
text-decoration: underline;
}
/* ordinary links appear in bold */
a { font-weight: bold; }
pre.verbatim {
margin: 0 0 0 0;
}
pre {
overflow: auto;
}
pre.screen {
font-weight: bold;
padding: 0.5em;
}
pre.programlisting {
padding: 0.5em;
}
div p { padding: 0 2em }
li p { padding: 0; margin: 0 }
hr { display: none; }
div.funcsynopsis p {
text-indent: -2em;
}
div.variablelist {
padding: 0 2em;
}
.type, .funcsynopsis, .symbol {
font-family: monospace;
}
.type, .symbol, .replaceable {
white-space: nowrap;
}
-->
</style>
</head>
<body lang="en">
<div class="section-level-extent" id="Native-threads">
<div class="nav-panel">
<p>
Next: <a href="Signals-and-Interrupts.html#Signals-and-Interrupts" accesskey="n" rel="next">Signals and Interrupts</a>, Previous: <a href="Foreign-Function-Interface.html#Foreign-Function-Interface" accesskey="p" rel="prev">Foreign Function Interface</a>, Up: <a href="Extensions.html" accesskey="u" rel="up">Extensions</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h3 class="section" id="Native-threads-1">3.4 Native threads</h3>
<a class="index-entry-id" id="index-Native-threads"></a>
<a class="index-entry-id" id="index-THREADS"></a>
<a class="index-entry-id" id="index-_002d_002denable_002dthreads-_005byes_007cno_007cAUTO_005d"></a>
<ul class="mini-toc">
<li><a href="Native-threads.html#Introduction-to-native-threads" accesskey="1">Tasks, threads or processes</a></li>
<li><a href="Native-threads.html#Processes-_0028native-threads_0029" accesskey="2">Processes (native threads)</a></li>
<li><a href="Native-threads.html#Processes-dictionary" accesskey="3">Processes dictionary</a></li>
<li><a href="Native-threads.html#Locks-_0028mutexes_0029" accesskey="4">Locks (mutexes)</a></li>
<li><a href="Native-threads.html#Locks-dictionary" accesskey="5">Locks dictionary</a></li>
<li><a href="Native-threads.html#Readers_002dwriter-locks" accesskey="6">Readers-writer locks</a></li>
<li><a href="Native-threads.html#Readers_002dwriter-locks-dictionary" accesskey="7">Read-Write locks dictionary</a></li>
<li><a href="Native-threads.html#Condition-variables" accesskey="8">Condition variables</a></li>
<li><a href="Native-threads.html#Condition-variables-dictionary" accesskey="9">Condition variables dictionary</a></li>
<li><a href="Native-threads.html#Semaphores">Semaphores</a></li>
<li><a href="Native-threads.html#Semaphores-dictionary">Semaphores dictionary</a></li>
<li><a href="Native-threads.html#Barriers">Barriers</a></li>
<li><a href="Native-threads.html#Barriers-dictionary">Barriers dictionary</a></li>
<li><a href="Native-threads.html#Atomic-operations">Atomic operations</a></li>
<li><a href="Native-threads.html#Atomic-operations-dictionary">Atomic operations dictionary</a></li>
</ul>
<hr>
<div class="subsection-level-extent" id="Introduction-to-native-threads">
<div class="nav-panel">
<p>
Next: <a href="Native-threads.html#Processes-_0028native-threads_0029" accesskey="n" rel="next">Processes (native threads)</a>, Up: <a href="Native-threads.html#Native-threads" accesskey="u" rel="up">Native threads</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsection" id="Tasks_002c-threads-or-processes">3.4.1 Tasks, threads or processes</h4>
<p>On most platforms, ECL supports native multithreading. That means there
can be several tasks executing lisp code on parallel and sharing memory,
variables and files. The interface for multitasking in ECL, like those
of most other implementations, is based on a set of functions and types
that resemble the multiprocessing capabilities of old Lisp Machines.
</p>
<p>This backward compatibility is why tasks or threads are called
&quot;processes&quot;. However, they should not be confused with operating system
processes, which are made of programs running in separate contexts and
without access to each other&rsquo;s memory.
</p>
<p>The implementation of threads in ECL is purely native and based on Posix
Threads wherever available. The use of native threads has
advantages. For instance, they allow for non-blocking file operations,
so that while one task is reading a file, a different one is performing
a computation.
</p>
<p>As mentioned above, tasks share the same memory, as well as the set of
open files and sockets. This manifests on two features. First of all,
different tasks can operate on the same lisp objects, reading and
writing their slots, or manipulating the same arrays. Second, while
threads share global variables, constants and function definitions they
can also have thread-local bindings to special variables that are not
seen by other tasks.
</p>
<p>The fact that different tasks have access to the same set of data allows
both for flexibility and a greater risk. In order to control access to
different resources, ECL provides the user with locks, as explained in
the next section.
</p>
<hr>
</div>
<div class="subsection-level-extent" id="Processes-_0028native-threads_0029">
<div class="nav-panel">
<p>
Next: <a href="Native-threads.html#Processes-dictionary" accesskey="n" rel="next">Processes dictionary</a>, Previous: <a href="Native-threads.html#Introduction-to-native-threads" accesskey="p" rel="prev">Tasks, threads or processes</a>, Up: <a href="Native-threads.html#Native-threads" accesskey="u" rel="up">Native threads</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsection" id="Processes-_0028native-threads_0029-1">3.4.2 Processes (native threads)</h4>
<p>Process is a primitive representing native thread.
</p>
<hr>
</div>
<div class="subsection-level-extent" id="Processes-dictionary">
<div class="nav-panel">
<p>
Next: <a href="Native-threads.html#Locks-_0028mutexes_0029" accesskey="n" rel="next">Locks (mutexes)</a>, Previous: <a href="Native-threads.html#Processes-_0028native-threads_0029" accesskey="p" rel="prev">Processes (native threads)</a>, Up: <a href="Native-threads.html#Native-threads" accesskey="u" rel="up">Native threads</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsection" id="Processes-dictionary-1">3.4.3 Processes dictionary</h4>
<a class="anchor" id="mp_005fall_005fprocesses"></a><a class="index-entry-id" id="index-mp_005fall_005fprocesses"></a>
<a class="anchor" id="mp_003aall_002dprocesses"></a><a class="index-entry-id" id="index-mp_003aall_002dprocesses-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005fall_005fprocesses-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_all_processes</strong> <code class="def-code-arguments">()</code><a class="copiable-link" href='Native-threads.html#index-mp_005fall_005fprocesses-1'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003aall_002dprocesses"><span class="category-def">Function: </span><span><strong class="def-name">mp:all-processes</strong><a class="copiable-link" href='Native-threads.html#index-mp_003aall_002dprocesses'> &para;</a></span></dt>
<dd>
<p>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 have
expired before this copy is returned.
</p>
</dd></dl>
&#12;
<a class="anchor" id="mp_005fexit_005fprocess"></a><a class="index-entry-id" id="index-mp_005fexit_005fprocess"></a>
<a class="anchor" id="mp_003aexit_002dprocess"></a><a class="index-entry-id" id="index-mp_003aexit_002dprocess-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005fexit_005fprocess-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_exit_process</strong> <code class="def-code-arguments">() ecl_attr_noreturn</code><a class="copiable-link" href='Native-threads.html#index-mp_005fexit_005fprocess-1'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003aexit_002dprocess"><span class="category-def">Function: </span><span><strong class="def-name">mp:exit-process</strong><a class="copiable-link" href='Native-threads.html#index-mp_003aexit_002dprocess'> &para;</a></span></dt>
<dd>
<p>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 class="code"><a class="ref" href="Operating-System-Interface.html#ext_003aquit">ext:quit</a></code> with exit code 0.
</p>
</dd></dl>
&#12;
<a class="anchor" id="mp_005finterrupt_005fprocess"></a><a class="index-entry-id" id="index-mp_005finterrupt_005fprocess"></a>
<a class="anchor" id="mp_003ainterrupt_002dprocess"></a><a class="index-entry-id" id="index-mp_003ainterrupt_002dprocess-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005finterrupt_005fprocess-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_interrupt_process</strong> <code class="def-code-arguments">(cl_object process, cl_object function)</code><a class="copiable-link" href='Native-threads.html#index-mp_005finterrupt_005fprocess-1'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003ainterrupt_002dprocess"><span class="category-def">Function: </span><span><strong class="def-name">mp:interrupt-process</strong> <var class="def-var-arguments">process function</var><a class="copiable-link" href='Native-threads.html#index-mp_003ainterrupt_002dprocess'> &para;</a></span></dt>
<dd>
<p>Interrupt a task. This function sends a signal to a running
<var class="var">process</var>. When the task is free to process that signal, it will
stop whatever it is doing and execute the given function.
</p>
<p><strong class="strong">WARNING:</strong> Use with care! Interrupts can happen anywhere,
except in code regions explicitely protected with
<code class="code"><a class="ref" href="Native-threads.html#mp_003awithout_002dinterrupts">mp:without-interrupts</a></code>. This can lead to dangerous situations
when interrupting functions which are not thread safe. In particular,
one has to consider:
</p><ul class="itemize mark-bullet">
<li>Reentrancy: Functions, which usually are not called recursively can be re-entered during execution of the interrupt.
</li><li>Stack unwinding: Non-local jumps like <code class="code">throw</code> or <code class="code">return-from</code> in the interrupting code will handle <code class="code">unwind-protect</code> forms like usual. However, the cleanup forms of an <code class="code">unwind-protect</code> can still be interrupted. In that case the execution flow will jump to the next <code class="code">unwind-protect</code>.
</li></ul>
<p>Note also that no guarantees are made that functions from the Common
Lisp standard or ECL extensions are interrupt safe (although most of
them will be). In particular, the compiler (<code class="code">compile</code> and
<code class="code">compile-file</code> functions), FFI calls and aquire/release functions
for multithreading synchronization objects like mutexes or condition
variables should not be interrupted by <code class="code"><a class="ref" href="Native-threads.html#mp_003ainterrupt_002dprocess">mp:interrupt-process</a></code>.
</p>
<a class="index-entry-id" id="index-Process-interruption"></a>
<p>Example:
</p>
<p>Kill a task that is doing nothing (See <code class="code"><a class="ref" href="Native-threads.html#mp_003aprocess_002dkill">mp:process-kill</a></code>).
</p>
<div class="example lisp">
<pre class="lisp-preformatted">(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)))
</pre></div>
</dd></dl>
&#12;
<a class="anchor" id="mp_005fmake_005fprocess"></a><a class="index-entry-id" id="index-mp_005fmake_005fprocess"></a>
<a class="anchor" id="mp_003amake_002dprocess"></a><a class="index-entry-id" id="index-mp_003amake_002dprocess-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005fmake_005fprocess-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_make_process</strong> <code class="def-code-arguments">(cl_narg narg, ...)</code><a class="copiable-link" href='Native-threads.html#index-mp_005fmake_005fprocess-1'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003amake_002dprocess"><span class="category-def">Function: </span><span><strong class="def-name">mp:make-process</strong> <var class="def-var-arguments">&amp;key name initial-bindings</var><a class="copiable-link" href='Native-threads.html#index-mp_003amake_002dprocess'> &para;</a></span></dt>
<dd>
<p>Create a new thread. This function creates a separate task with a name
set to <var class="var">name</var> and no function to run. See also
<code class="code"><a class="ref" href="Native-threads.html#mp_003aprocess_002drun_002dfunction">mp:process-run-function</a></code>. Returns newly created process.
</p>
<p>If <var class="var">initial-bindings</var> is false, the new process inherits local
bindings to special variables (i.e. binding a special variable with
<code class="code">let</code> or <code class="code">let*</code>) from the current thread, otherwise the new
thread possesses no local bindings.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005fprocess_005factive_005fp"></a><a class="index-entry-id" id="index-mp_005fprocess_005factive_005fp"></a>
<a class="anchor" id="mp_003aprocess_002dactive_002dp"></a><a class="index-entry-id" id="index-mp_003aprocess_002dactive_002dp-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005fprocess_005factive_005fp-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_process_active_p</strong> <code class="def-code-arguments">(cl_object process)</code><a class="copiable-link" href='Native-threads.html#index-mp_005fprocess_005factive_005fp-1'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003aprocess_002dactive_002dp"><span class="category-def">Function: </span><span><strong class="def-name">mp:process-active-p</strong> <var class="def-var-arguments">process</var><a class="copiable-link" href='Native-threads.html#index-mp_003aprocess_002dactive_002dp'> &para;</a></span></dt>
<dd>
<p>Returns <code class="code">t</code> when <var class="var">process</var> is active, <code class="code">nil</code>
otherwise. Signals an error if <var class="var">process</var> doesn&rsquo;t designate a valid
process.
</p>
</dd></dl>
&#12;
<a class="anchor" id="mp_005fprocess_005fenable"></a><a class="index-entry-id" id="index-mp_005fprocess_005fenable"></a>
<a class="anchor" id="mp_003aprocess_002denable"></a><a class="index-entry-id" id="index-mp_003aprocess_002denable-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005fprocess_005fenable-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_process_enable</strong> <code class="def-code-arguments">(cl_object process)</code><a class="copiable-link" href='Native-threads.html#index-mp_005fprocess_005fenable-1'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003aprocess_002denable"><span class="category-def">Function: </span><span><strong class="def-name">mp:process-enable</strong> <var class="def-var-arguments">process</var><a class="copiable-link" href='Native-threads.html#index-mp_003aprocess_002denable'> &para;</a></span></dt>
<dd>
<p>The argument to this function should be a process created by
<code class="code"><a class="ref" href="Native-threads.html#mp_003amake_002dprocess">mp:make-process</a></code>, which has a function associated as per
<code class="code"><a class="ref" href="Native-threads.html#mp_003aprocess_002dpreset">mp:process-preset</a></code> but which is not yet running. After invoking
this function a new thread will be created in which the associated
function will be executed. Returns <var class="var">process</var> if the thread
creation was successful and <code class="code">nil</code> otherwise.
</p>
<a class="index-entry-id" id="index-Possible-implementation-of-html_003a"></a>
<div class="example lisp">
<pre class="lisp-preformatted">(defun process-run-function (process-name process-function &amp;rest args)
(let ((process (mp:make-process name)))
(apply #'mp:process-preset process function args)
(mp:process-enable process)))
</pre></div>
</dd></dl>
&#12;
<a class="anchor" id="mp_005fprocess_005fyield"></a><a class="index-entry-id" id="index-mp_005fprocess_005fyield"></a>
<a class="anchor" id="mp_003aprocess_002dyield"></a><a class="index-entry-id" id="index-mp_003aprocess_002dyield-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005fprocess_005fyield-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_process_yield</strong> <code class="def-code-arguments">()</code><a class="copiable-link" href='Native-threads.html#index-mp_005fprocess_005fyield-1'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003aprocess_002dyield"><span class="category-def">Function: </span><span><strong class="def-name">mp:process-yield</strong><a class="copiable-link" href='Native-threads.html#index-mp_003aprocess_002dyield'> &para;</a></span></dt>
<dd><p>Yield the processor to other threads.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005fprocess_002djoin"></a><a class="index-entry-id" id="index-mp_005fprocess_002djoin"></a>
<a class="anchor" id="mp_003aprocess_002djoin"></a><a class="index-entry-id" id="index-mp_003aprocess_002djoin-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005fprocess_005fjoin"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_process_join</strong> <code class="def-code-arguments">(cl_object process)</code><a class="copiable-link" href='Native-threads.html#index-mp_005fprocess_005fjoin'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003aprocess_002djoin"><span class="category-def">Function: </span><span><strong class="def-name">mp:process-join</strong> <var class="def-var-arguments">process</var><a class="copiable-link" href='Native-threads.html#index-mp_003aprocess_002djoin'> &para;</a></span></dt>
<dd><p>Suspend current thread until <var class="var">process</var> exits. Return the result
values of the <var class="var">process</var> function.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005fprocess_005fkill"></a><a class="index-entry-id" id="index-mp_005fprocess_005fkill"></a>
<a class="anchor" id="mp_003aprocess_002dkill"></a><a class="index-entry-id" id="index-mp_003aprocess_002dkill-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005fprocess_005fkill-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_process_kill</strong> <code class="def-code-arguments">(cl_object process)</code><a class="copiable-link" href='Native-threads.html#index-mp_005fprocess_005fkill-1'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003aprocess_002dkill"><span class="category-def">Function: </span><span><strong class="def-name">mp:process-kill</strong> <var class="def-var-arguments">process</var><a class="copiable-link" href='Native-threads.html#index-mp_003aprocess_002dkill'> &para;</a></span></dt>
<dd><p>Try to stop a running task. Killing a process may fail if the task has
disabled interrupts.
</p>
<a class="index-entry-id" id="index-Killing-process"></a>
<p>Example:
</p>
<p>Kill a task that is doing nothing
</p><div class="example lisp">
<pre class="lisp-preformatted">(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)))
</pre></div>
</dd></dl>
&#12;
<a class="anchor" id="mp_005fprocess_005fsuspend"></a><a class="index-entry-id" id="index-mp_005fprocess_005fsuspend"></a>
<a class="anchor" id="mp_003aprocess_002dsuspend"></a><a class="index-entry-id" id="index-mp_003aprocess_002dsuspend-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005fprocess_005fsuspend-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_process_suspend</strong> <code class="def-code-arguments">(cl_object process)</code><a class="copiable-link" href='Native-threads.html#index-mp_005fprocess_005fsuspend-1'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003aprocess_002dsuspend"><span class="category-def">Function: </span><span><strong class="def-name">mp:process-suspend</strong> <var class="def-var-arguments">process</var><a class="copiable-link" href='Native-threads.html#index-mp_003aprocess_002dsuspend'> &para;</a></span></dt>
<dd><p>Suspend a running <var class="var">process</var>. May be resumed with
<code class="code"><a class="ref" href="Native-threads.html#mp_003aprocess_002dresume">mp:process-resume</a></code>.
</p>
<a class="index-entry-id" id="index-Suspend-and-resume-process"></a>
<p>Example:
</p>
<div class="example lisp">
<pre class="lisp-preformatted">(flet ((ticking-task ()
;; Infinite loop
(loop
(sleep 1)
(print :tick))))
(print &quot;Running task (one tick per second)&quot;)
(let ((task (mp:process-run-function 'background #'ticking-task)))
(sleep 5)
(print &quot;Suspending task for 5 seconds&quot;)
(mp:process-suspend task)
(sleep 5)
(print &quot;Resuming task for 5 seconds&quot;)
(mp:process-resume task)
(sleep 5)
(print &quot;Killing task&quot;)
(mp:process-kill task)))
</pre></div>
</dd></dl>
&#12;
<a class="anchor" id="mp_005fprocess_005fresume"></a><a class="index-entry-id" id="index-mp_005fprocess_005fresume"></a>
<a class="anchor" id="mp_003aprocess_002dresume"></a><a class="index-entry-id" id="index-mp_003aprocess_002dresume-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005fprocess_005fresume-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_process_resume</strong> <code class="def-code-arguments">(cl_object process)</code><a class="copiable-link" href='Native-threads.html#index-mp_005fprocess_005fresume-1'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003aprocess_002dresume"><span class="category-def">Function: </span><span><strong class="def-name">mp:process-resume</strong> <var class="def-var-arguments">process</var><a class="copiable-link" href='Native-threads.html#index-mp_003aprocess_002dresume'> &para;</a></span></dt>
<dd><p>Resumes a suspended <var class="var">process</var>. See example in
<code class="code"><a class="ref" href="Native-threads.html#mp_003aprocess_002dsuspend">mp:process-suspend</a></code>.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005fprocess_005fname"></a><a class="index-entry-id" id="index-mp_005fprocess_005fname"></a>
<a class="anchor" id="mp_003aprocess_002dname"></a><a class="index-entry-id" id="index-mp_003aprocess_002dname-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005fprocess_005fname-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_process_name</strong> <code class="def-code-arguments">(cl_object process)</code><a class="copiable-link" href='Native-threads.html#index-mp_005fprocess_005fname-1'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003aprocess_002dname"><span class="category-def">Function: </span><span><strong class="def-name">mp:process-name</strong> <var class="def-var-arguments">process</var><a class="copiable-link" href='Native-threads.html#index-mp_003aprocess_002dname'> &para;</a></span></dt>
<dd><p>Returns the name of a <var class="var">process</var> (if any).
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005fprocess_005fpreset"></a><a class="index-entry-id" id="index-mp_005fprocess_005fpreset"></a>
<a class="anchor" id="mp_003aprocess_002dpreset"></a><a class="index-entry-id" id="index-mp_003aprocess_002dpreset-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005fprocess_005fpreset-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_process_preset</strong> <code class="def-code-arguments">(cl_narg narg, cl_object process, cl_object function, ...)</code><a class="copiable-link" href='Native-threads.html#index-mp_005fprocess_005fpreset-1'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003aprocess_002dpreset"><span class="category-def">Function: </span><span><strong class="def-name">mp:process-preset</strong> <var class="def-var-arguments">process function &amp;rest function-args</var><a class="copiable-link" href='Native-threads.html#index-mp_003aprocess_002dpreset'> &para;</a></span></dt>
<dd>
<p>Associates a <var class="var">function</var> to call with the arguments
<var class="var">function-args</var>, with a stopped <var class="var">process</var>. The function will
be the entry point when the task is enabled in the future.
</p>
<p>See <code class="code"><a class="ref" href="Native-threads.html#mp_003aprocess_002denable">mp:process-enable</a></code> and <code class="code"><a class="ref" href="Native-threads.html#mp_003aprocess_002drun_002dfunction">mp:process-run-function</a></code>.
</p>
</dd></dl>
&#12;
<a class="anchor" id="mp_005fprocess_005frun_005ffunction"></a><a class="index-entry-id" id="index-mp_005fprocess_005frun_005ffunction"></a>
<a class="anchor" id="mp_003aprocess_002drun_002dfunction"></a><a class="index-entry-id" id="index-mp_003aprocess_002drun_002dfunction-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005fprocess_005frun_005ffunction-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_process_run_function</strong> <code class="def-code-arguments">(cl_narg narg, cl_object name, cl_object function, ...)</code><a class="copiable-link" href='Native-threads.html#index-mp_005fprocess_005frun_005ffunction-1'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003aprocess_002drun_002dfunction"><span class="category-def">Function: </span><span><strong class="def-name">mp:process-run-function</strong> <var class="def-var-arguments">name function &amp;rest function-args</var><a class="copiable-link" href='Native-threads.html#index-mp_003aprocess_002drun_002dfunction'> &para;</a></span></dt>
<dd><p>Create a new process using <code class="code"><a class="ref" href="Native-threads.html#mp_003amake_002dprocess">mp:make-process</a></code>, associate a function
to it and start it using <code class="code"><a class="ref" href="Native-threads.html#mp_003aprocess_002dpreset">mp:process-preset</a></code>.
</p>
<a class="index-entry-id" id="index-mp_003aprocess_002drun_002dfunction-usage"></a>
<p>Example:
</p>
<div class="example lisp">
<pre class="lisp-preformatted">(flet ((count-numbers (end-number)
(dotimes (i end-number)
(format t &quot;~%;;; Counting: ~i&quot; i)
(terpri)
(sleep 1))))
(mp:process-run-function 'counter #'count-numbers 10))
</pre></div>
</dd></dl>
&#12;
<a class="anchor" id="mp_005fcurrent_005fprocess"></a><a class="index-entry-id" id="index-mp_005fcurrent_005fprocess"></a>
<a class="anchor" id="mp_003a_002acurrent_002dprocess_002a"></a><a class="index-entry-id" id="index-mp_003a_002acurrent_002dprocess_002a"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005fcurrent_005fprocess-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_current_process</strong> <code class="def-code-arguments">()</code><a class="copiable-link" href='Native-threads.html#index-mp_005fcurrent_005fprocess-1'> &para;</a></span></dt>
</dl>
<dl class="first-defvr">
<dt class="defvr" id="index-mp_003a_002acurrent_002dprocess_002a-1"><span class="category-def">Variable: </span><span><strong class="def-name">mp:*current-process*</strong><a class="copiable-link" href='Native-threads.html#index-mp_003a_002acurrent_002dprocess_002a-1'> &para;</a></span></dt>
<dd><p>Returns/holds the current process of a caller.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005fblock_005fsignals"></a><a class="index-entry-id" id="index-mp_005fblock_005fsignals"></a>
<a class="anchor" id="mp_003ablock_002dsignals"></a><a class="index-entry-id" id="index-mp_003ablock_002dsignals-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005fblock_005fsignals-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_block_signals</strong> <code class="def-code-arguments">()</code><a class="copiable-link" href='Native-threads.html#index-mp_005fblock_005fsignals-1'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003ablock_002dsignals"><span class="category-def">Function: </span><span><strong class="def-name">mp:block-signals</strong><a class="copiable-link" href='Native-threads.html#index-mp_003ablock_002dsignals'> &para;</a></span></dt>
<dd><p>Blocks process for interrupts and returns the previous sigmask.
</p>
<p>See <code class="code"><a class="ref" href="Native-threads.html#mp_003ainterrupt_002dprocess">mp:interrupt-process</a></code>.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005frestore_005fsignals"></a><a class="index-entry-id" id="index-mp_005frestore_005fsignals"></a>
<a class="anchor" id="mp_003arestore_002dsignals"></a><a class="index-entry-id" id="index-mp_003arestore_002dsignals-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005frestore_005fsignals-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_restore_signals</strong> <code class="def-code-arguments">(cl_object sigmask)</code><a class="copiable-link" href='Native-threads.html#index-mp_005frestore_005fsignals-1'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003arestore_002dsignals"><span class="category-def">Function: </span><span><strong class="def-name">mp:restore-signals</strong> <var class="def-var-arguments">sigmask</var><a class="copiable-link" href='Native-threads.html#index-mp_003arestore_002dsignals'> &para;</a></span></dt>
<dd><p>Enables the interrupts from <var class="var">sigmask</var>.
</p>
<p>See <code class="code"><a class="ref" href="Native-threads.html#mp_003ainterrupt_002dprocess">mp:interrupt-process</a></code>.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_003awithout_002dinterrupts"></a><a class="index-entry-id" id="index-mp_003awithout_002dinterrupts-2"></a>
<a class="anchor" id="mp_003aallow_002dwith_002dinterrupts"></a><a class="index-entry-id" id="index-mp_003aallow_002dwith_002dinterrupts"></a>
<a class="anchor" id="mp_003awith_002dlocal_002dinterrupts"></a><a class="index-entry-id" id="index-mp_003awith_002dlocal_002dinterrupts"></a>
<a class="anchor" id="mp_003awith_002drestored_002dinterrupts"></a><a class="index-entry-id" id="index-mp_003awith_002drestored_002dinterrupts"></a>
<dl class="first-deffn first-defmac-alias-first-deffn">
<dt class="deffn defmac-alias-deffn" id="index-mp_003awithout_002dinterrupts"><span class="category-def">Macro: </span><span><strong class="def-name">mp:without-interrupts</strong> <var class="def-var-arguments">&amp;body body</var><a class="copiable-link" href='Native-threads.html#index-mp_003awithout_002dinterrupts'> &para;</a></span></dt>
<dd>
<p>Executes <var class="var">body</var> with all deferrable interrupts disabled. Deferrable
interrupts arriving during execution of the <var class="var">body</var> take effect
after <var class="var">body</var> has been executed.
</p>
<p>Deferrable interrupts include most blockable POSIX signals, and
<code class="code"><a class="ref" href="Native-threads.html#mp_003ainterrupt_002dprocess">mp:interrupt-process</a></code>. Does not interfere with garbage
collection, and unlike in many traditional Lisps using userspace
threads, in ECL <code class="code"><a class="ref" href="Native-threads.html#mp_003awithout_002dinterrupts">mp:without-interrupts</a></code> does not inhibit
scheduling of other threads.
</p>
<p>Binds <code class="code"><a class="ref" href="Native-threads.html#mp_003aallow_002dwith_002dinterrupts">mp:allow-with-interrupts</a></code>,
<code class="code"><a class="ref" href="Native-threads.html#mp_003awith_002dlocal_002dinterrupts">mp:with-local-interrupts</a></code> and
<code class="code"><a class="ref" href="Native-threads.html#mp_003awith_002drestored_002dinterrupts">mp:with-restored-interrupts</a></code> as a local macros.
</p>
<p><code class="code"><a class="ref" href="Native-threads.html#mp_003awith_002drestored_002dinterrupts">mp:with-restored-interrupts</a></code> executes the body with interrupts
enabled if and only if the <code class="code"><a class="ref" href="Native-threads.html#mp_003awithout_002dinterrupts">mp:without-interrupts</a></code> was in an
environment in which interrupts were allowed.
</p>
<p><code class="code"><a class="ref" href="Native-threads.html#mp_003aallow_002dwith_002dinterrupts">mp:allow-with-interrupts</a></code> allows the
<code class="code"><a class="ref" href="Native-threads.html#mp_003awith_002dinterrupts">mp:with-interrupts</a></code> to take effect during the dynamic scope of
its body, unless there is an outer <code class="code"><a class="ref" href="Native-threads.html#mp_003awithout_002dinterrupts">mp:without-interrupts</a></code>
without a corresponding <code class="code"><a class="ref" href="Native-threads.html#mp_003aallow_002dwith_002dinterrupts">mp:allow-with-interrupts</a></code>.
</p>
<p><code class="code"><a class="ref" href="Native-threads.html#mp_003awith_002dlocal_002dinterrupts">mp:with-local-interrupts</a></code> executes its body with interrupts
enabled provided that there is an <code class="code"><a class="ref" href="Native-threads.html#mp_003aallow_002dwith_002dinterrupts">mp:allow-with-interrupts</a></code> for
every <code class="code"><a class="ref" href="Native-threads.html#mp_003awithout_002dinterrupts">mp:without-interrupts</a></code> surrounding the current one.
<code class="code"><a class="ref" href="Native-threads.html#mp_003awith_002dlocal_002dinterrupts">mp:with-local-interrupts</a></code> is equivalent to:
</p>
<div class="example lisp">
<pre class="lisp-preformatted">(mp:allow-with-interrupts (mp:with-interrupts ...))
</pre></div>
<p>Care must be taken not to let either <code class="code"><a class="ref" href="Native-threads.html#mp_003aallow_002dwith_002dinterrupts">mp:allow-with-interrupts</a></code>
or <code class="code"><a class="ref" href="Native-threads.html#mp_003awith_002dlocal_002dinterrupts">mp:with-local-interrupts</a></code> appear in a function that escapes
from inside the <code class="code"><a class="ref" href="Native-threads.html#mp_003awithout_002dinterrupts">mp:without-interrupts</a></code> in:
</p>
<div class="example lisp">
<pre class="lisp-preformatted">(mp: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 () (mp:allow-with-interrupts ...)))
(mp: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 () (mp:with-local-interrupts ...)))
</pre></div>
</dd></dl>
&#12;
<a class="anchor" id="mp_003awith_002dinterrupts"></a><a class="index-entry-id" id="index-mp_003awith_002dinterrupts-2"></a>
<dl class="first-deffn first-defmac-alias-first-deffn">
<dt class="deffn defmac-alias-deffn" id="index-mp_003awith_002dinterrupts"><span class="category-def">Macro: </span><span><strong class="def-name">mp:with-interrupts</strong> <var class="def-var-arguments">&amp;body body</var><a class="copiable-link" href='Native-threads.html#index-mp_003awith_002dinterrupts'> &para;</a></span></dt>
<dd><p>Executes <var class="var">body</var> with deferrable interrupts conditionally
enabled. If there are pending interrupts they take effect prior to
executing <var class="var">body</var>.
</p>
<p>As interrupts are normally allowed <code class="code"><a class="ref" href="Native-threads.html#mp_003awith_002dinterrupts">mp:with-interrupts</a></code> only
makes sense if there is an outer <code class="code"><a class="ref" href="Native-threads.html#mp_003awithout_002dinterrupts">mp:without-interrupts</a></code> with a
corresponding <code class="code"><a class="ref" href="Native-threads.html#mp_003aallow_002dwith_002dinterrupts">mp:allow-with-interrupts</a></code>: interrupts are not
enabled if any outer <code class="code"><a class="ref" href="Native-threads.html#mp_003awithout_002dinterrupts">mp:without-interrupts</a></code> is not accompanied
by <code class="code"><a class="ref" href="Native-threads.html#mp_003aallow_002dwith_002dinterrupts">mp:allow-with-interrupts</a></code>.
</p></dd></dl>
<hr>
</div>
<div class="subsection-level-extent" id="Locks-_0028mutexes_0029">
<div class="nav-panel">
<p>
Next: <a href="Native-threads.html#Locks-dictionary" accesskey="n" rel="next">Locks dictionary</a>, Previous: <a href="Native-threads.html#Processes-dictionary" accesskey="p" rel="prev">Processes dictionary</a>, Up: <a href="Native-threads.html#Native-threads" accesskey="u" rel="up">Native threads</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsection" id="Locks-_0028mutexes_0029-1">3.4.4 Locks (mutexes)</h4>
<p>Locks are used to synchronize access to the shared data. Lock may be
owned only by a single thread at any given time. Recursive locks may be
re-acquired by the same thread multiple times (and non-recursive locks
can&rsquo;t).
</p>
<hr>
</div>
<div class="subsection-level-extent" id="Locks-dictionary">
<div class="nav-panel">
<p>
Next: <a href="Native-threads.html#Readers_002dwriter-locks" accesskey="n" rel="next">Readers-writer locks</a>, Previous: <a href="Native-threads.html#Locks-_0028mutexes_0029" accesskey="p" rel="prev">Locks (mutexes)</a>, Up: <a href="Native-threads.html#Native-threads" accesskey="u" rel="up">Native threads</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsection" id="Locks-dictionary-1">3.4.5 Locks dictionary</h4>
&#12;
<a class="anchor" id="ecl_005fmake_005flock"></a><a class="index-entry-id" id="index-ecl_005fmake_005flock"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-ecl_005fmake_005flock-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">ecl_make_lock</strong> <code class="def-code-arguments">(cl_object name, bool recursive)</code><a class="copiable-link" href='Native-threads.html#index-ecl_005fmake_005flock-1'> &para;</a></span></dt>
<dd><p>C/C++ equivalent of <code class="code"><a class="ref" href="Native-threads.html#mp_003amake_002dlock">mp:make-lock</a></code> without <var class="var">key</var> arguments.
</p>
<p>See <code class="code"><a class="ref" href="Native-threads.html#mp_003amake_002dlock">mp:make-lock</a></code>.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_003amake_002dlock"></a><a class="index-entry-id" id="index-mp_003amake_002dlock-1"></a>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003amake_002dlock"><span class="category-def">Function: </span><span><strong class="def-name">mp:make-lock</strong> <var class="def-var-arguments">&amp;key name (recursive nil)</var><a class="copiable-link" href='Native-threads.html#index-mp_003amake_002dlock'> &para;</a></span></dt>
<dd><p>Creates a lock named <var class="var">name</var>. If <var class="var">recursive</var> is true, a recursive
lock is created that can be locked multiple times by the same thread.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005frecursive_005flock_005fp"></a><a class="index-entry-id" id="index-mp_005frecursive_005flock_005fp"></a>
<a class="anchor" id="mp_003arecursive_002dlock_002dp"></a><a class="index-entry-id" id="index-mp_003arecursive_002dlock_002dp-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005frecursive_005flock_005fp-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_recursive_lock_p</strong> <code class="def-code-arguments">(cl_object lock)</code><a class="copiable-link" href='Native-threads.html#index-mp_005frecursive_005flock_005fp-1'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003arecursive_002dlock_002dp"><span class="category-def">Function: </span><span><strong class="def-name">mp:recursive-lock-p</strong> <var class="def-var-arguments">lock</var><a class="copiable-link" href='Native-threads.html#index-mp_003arecursive_002dlock_002dp'> &para;</a></span></dt>
<dd><p>Predicate verifying if <var class="var">lock</var> is recursive.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005fholding_005flock_005fp"></a><a class="index-entry-id" id="index-mp_005fholding_005flock_005fp"></a>
<a class="anchor" id="mp_003aholding_002dlock_002dp"></a><a class="index-entry-id" id="index-mp_003aholding_002dlock_002dp-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005fholding_005flock_005fp-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_holding_lock_p</strong> <code class="def-code-arguments">(cl_object lock)</code><a class="copiable-link" href='Native-threads.html#index-mp_005fholding_005flock_005fp-1'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003aholding_002dlock_002dp"><span class="category-def">Function: </span><span><strong class="def-name">mp:holding-lock-p</strong> <var class="def-var-arguments">lock</var><a class="copiable-link" href='Native-threads.html#index-mp_003aholding_002dlock_002dp'> &para;</a></span></dt>
<dd><p>Predicate verifying if the current thread holds <var class="var">lock</var>.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005flock_005fname"></a><a class="index-entry-id" id="index-mp_005flock_005fname"></a>
<a class="anchor" id="mp_003alock_002dname"></a><a class="index-entry-id" id="index-mp_003alock_002dname"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005flock_005fname-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_lock_name</strong> <code class="def-code-arguments">(cl_object lock)</code><a class="copiable-link" href='Native-threads.html#index-mp_005flock_005fname-1'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003alock_005fname"><span class="category-def">Function: </span><span><strong class="def-name">mp:lock_name</strong> <var class="def-var-arguments">lock</var><a class="copiable-link" href='Native-threads.html#index-mp_003alock_005fname'> &para;</a></span></dt>
<dd><p>Returns the name of <var class="var">lock</var>.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005flock_005fowner"></a><a class="index-entry-id" id="index-mp_005flock_005fowner-1"></a>
<a class="anchor" id="mp_003alock_002downer"></a><a class="index-entry-id" id="index-mp_003alock_002downer-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005flock_005fowner"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_lock_owner</strong> <code class="def-code-arguments">(cl_object lock)</code><a class="copiable-link" href='Native-threads.html#index-mp_005flock_005fowner'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003alock_002downer"><span class="category-def">Function: </span><span><strong class="def-name">mp:lock-owner</strong> <var class="def-var-arguments">lock</var><a class="copiable-link" href='Native-threads.html#index-mp_003alock_002downer'> &para;</a></span></dt>
<dd><p>Returns the process owning <var class="var">lock</var> or <code class="code">nil</code> if the mutex is not
owned by any process. For testing whether the current thread
is holding a lock see <code class="code"><a class="ref" href="Native-threads.html#mp_003aholding_002dlock_002dp">mp:holding-lock-p</a></code>.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005flock_005fcount"></a><a class="index-entry-id" id="index-mp_005flock_005fcount"></a>
<a class="anchor" id="mp_003alock_002dcount"></a><a class="index-entry-id" id="index-mp_003alock_002dcount-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005flock_005fcount-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_lock_count</strong> <code class="def-code-arguments">(cl_object lock)</code><a class="copiable-link" href='Native-threads.html#index-mp_005flock_005fcount-1'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003alock_002dcount"><span class="category-def">Function: </span><span><strong class="def-name">mp:lock-count</strong> <var class="def-var-arguments">lock</var><a class="copiable-link" href='Native-threads.html#index-mp_003alock_002dcount'> &para;</a></span></dt>
<dd><p>Returns number of times <var class="var">lock</var> has been locked.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005fget_005flock_005fwait"></a><a class="index-entry-id" id="index-mp_005fget_005flock_005fwait"></a>
<a class="anchor" id="mp_005fget_005flock_005fnowait"></a><a class="index-entry-id" id="index-mp_005fget_005flock_005fnowait"></a>
<a class="anchor" id="mp_003aget_002dlock"></a><a class="index-entry-id" id="index-mp_003aget_002dlock-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005fget_005flock_005fwait-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_get_lock_wait</strong> <code class="def-code-arguments">(cl_object lock)</code><a class="copiable-link" href='Native-threads.html#index-mp_005fget_005flock_005fwait-1'> &para;</a></span></dt>
<dd><p>Grabs a lock (blocking if <var class="var">lock</var> is already taken). Returns
<code class="code">ECL_T</code>.
</p></dd></dl>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005fget_005flock_005fnowait-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_get_lock_nowait</strong><a class="copiable-link" href='Native-threads.html#index-mp_005fget_005flock_005fnowait-1'> &para;</a></span></dt>
<dd><p>Grabs a lock if free (non-blocking). If <var class="var">lock</var> is already taken
returns <code class="code">ECL_NIL</code>, otherwise <code class="code">ECL_T</code>.
</p></dd></dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003aget_002dlock"><span class="category-def">Function: </span><span><strong class="def-name">mp:get-lock</strong> <var class="def-var-arguments">lock &amp;optional (wait t)</var><a class="copiable-link" href='Native-threads.html#index-mp_003aget_002dlock'> &para;</a></span></dt>
<dd><p>Tries to acquire a lock. <var class="var">wait</var> indicates whether function should
block or give up if <var class="var">lock</var> is already taken. If <var class="var">wait</var> is
<code class="code">nil</code>, immediately return, if <var class="var">wait</var> is a real number
<var class="var">wait</var> specifies a timeout in seconds and otherwise block until the
lock becomes available. If <var class="var">lock</var> can&rsquo;t be acquired return
<code class="code">nil</code>. Successful operation returns <code class="code">t</code>. Will signal an error
if the mutex is non-recursive and current thread already owns the lock.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005fgiveup_005flock"></a><a class="index-entry-id" id="index-mp_005fgiveup_005flock"></a>
<a class="anchor" id="mp_003agiveup_002dlock"></a><a class="index-entry-id" id="index-mp_003agiveup_002dlock-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005fgiveup_005flock-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_giveup_lock</strong> <code class="def-code-arguments">(cl_object lock)</code><a class="copiable-link" href='Native-threads.html#index-mp_005fgiveup_005flock-1'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003agiveup_002dlock"><span class="category-def">Function: </span><span><strong class="def-name">mp:giveup-lock</strong> <var class="def-var-arguments">lock</var><a class="copiable-link" href='Native-threads.html#index-mp_003agiveup_002dlock'> &para;</a></span></dt>
<dd><p>Releases <var class="var">lock</var> and returns <code class="code">t</code>. May signal an error if the
lock is not owned by the current thread.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_003awith_002dlock"></a><a class="index-entry-id" id="index-mp_003awith_002dlock-1"></a>
<dl class="first-deffn first-defmac-alias-first-deffn">
<dt class="deffn defmac-alias-deffn" id="index-mp_003awith_002dlock"><span class="category-def">Macro: </span><span><strong class="def-name">mp:with-lock</strong> <var class="def-var-arguments">(lock-form) &amp;body body</var><a class="copiable-link" href='Native-threads.html#index-mp_003awith_002dlock'> &para;</a></span></dt>
<dd><p>Acquire lock for the dynamic scope of <var class="var">body</var>, which is executed with
the lock held by current thread. Returns the values of
body.
</p>
</dd></dl>
<hr>
</div>
<div class="subsection-level-extent" id="Readers_002dwriter-locks">
<div class="nav-panel">
<p>
Next: <a href="Native-threads.html#Readers_002dwriter-locks-dictionary" accesskey="n" rel="next">Read-Write locks dictionary</a>, Previous: <a href="Native-threads.html#Locks-dictionary" accesskey="p" rel="prev">Locks dictionary</a>, Up: <a href="Native-threads.html#Native-threads" accesskey="u" rel="up">Native threads</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsection" id="Readers_002dwriter-locks-1">3.4.6 Readers-writer locks</h4>
<a class="index-entry-id" id="index-ecl_002dread_002dwrite_002dlock"></a>
<a class="index-entry-id" id="index-Readers_002dwriter-locks"></a>
<a class="index-entry-id" id="index-Shared_002dexclusive-locks"></a>
<p>Readers-writer (or shared-exclusive ) locks allow concurrent access
for read-only operations, while write operations require exclusive
access. <code class="code">mp:rwlock</code> is non-recursive and cannot be used together
with condition variables.
</p>
<hr>
</div>
<div class="subsection-level-extent" id="Readers_002dwriter-locks-dictionary">
<div class="nav-panel">
<p>
Next: <a href="Native-threads.html#Condition-variables" accesskey="n" rel="next">Condition variables</a>, Previous: <a href="Native-threads.html#Readers_002dwriter-locks" accesskey="p" rel="prev">Readers-writer locks</a>, Up: <a href="Native-threads.html#Native-threads" accesskey="u" rel="up">Native threads</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsection" id="Read_002dWrite-locks-dictionary">3.4.7 Read-Write locks dictionary</h4>
&#12;
<a class="anchor" id="ecl_005fmake_005frwlock"></a><a class="index-entry-id" id="index-ecl_005fmake_005frwlock"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-ecl_005fmake_005frwlock-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">ecl_make_rwlock</strong> <code class="def-code-arguments">(cl_object name)</code><a class="copiable-link" href='Native-threads.html#index-ecl_005fmake_005frwlock-1'> &para;</a></span></dt>
<dd><p>C/C++ equivalent of <code class="code"><a class="ref" href="Native-threads.html#mp_003amake_002drwlock">mp:make-rwlock</a></code> without <code class="code">key</code> arguments.
</p>
<p>See <code class="code"><a class="ref" href="Native-threads.html#mp_003amake_002drwlock">mp:make-rwlock</a></code>.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_003amake_002drwlock"></a><a class="index-entry-id" id="index-mp_003amake_002drwlock-1"></a>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003amake_002drwlock"><span class="category-def">Function: </span><span><strong class="def-name">mp:make-rwlock</strong> <var class="def-var-arguments">&amp;key name</var><a class="copiable-link" href='Native-threads.html#index-mp_003amake_002drwlock'> &para;</a></span></dt>
<dd><p>Creates a rwlock named <var class="var">name</var>.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005frwlock_005fname"></a><a class="index-entry-id" id="index-mp_005frwlock_005fname"></a>
<a class="anchor" id="mp_003arwlock_002dname"></a><a class="index-entry-id" id="index-mp_003arwlock_002dname-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005frwlock_005fname-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_rwlock_name</strong> <code class="def-code-arguments">(cl_object lock)</code><a class="copiable-link" href='Native-threads.html#index-mp_005frwlock_005fname-1'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003arwlock_002dname"><span class="category-def">Function: </span><span><strong class="def-name">mp:rwlock-name</strong> <var class="def-var-arguments">lock</var><a class="copiable-link" href='Native-threads.html#index-mp_003arwlock_002dname'> &para;</a></span></dt>
<dd><p>Returns the name of <var class="var">lock</var>.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005fget_005frwlock_005fread_005fwait"></a><a class="index-entry-id" id="index-mp_005fget_005frwlock_005fread_005fwait"></a>
<a class="anchor" id="mp_005fget_005frwlock_005fread_005fnowait"></a><a class="index-entry-id" id="index-mp_005fget_005frwlock_005fread_005fnowait"></a>
<a class="anchor" id="mp_003aget_002drwlock_002dread"></a><a class="index-entry-id" id="index-mp_003aget_002drwlock_002dread-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005fget_005frwlock_005fread_005fwait-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_get_rwlock_read_wait</strong> <code class="def-code-arguments">(cl_object lock)</code><a class="copiable-link" href='Native-threads.html#index-mp_005fget_005frwlock_005fread_005fwait-1'> &para;</a></span></dt>
<dd><p>Acquires <var class="var">lock</var> (blocks if <var class="var">lock</var> is already taken with
<code class="code"><a class="ref" href="Native-threads.html#mp_003aget_002drwlock_002dwrite">mp:get-rwlock-write</a></code>. Lock may be acquired by multiple
readers). Returns <code class="code">ECL_T</code>.
</p></dd></dl>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005fget_005frwlock_005fread_005fnowait-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_get_rwlock_read_nowait</strong><a class="copiable-link" href='Native-threads.html#index-mp_005fget_005frwlock_005fread_005fnowait-1'> &para;</a></span></dt>
<dd><p>Tries to acquire <var class="var">lock</var>. If <var class="var">lock</var> is already taken with
<code class="code"><a class="ref" href="Native-threads.html#mp_003aget_002drwlock_002dwrite">mp:get-rwlock-write</a></code> returns <code class="code">ECL_NIL</code>, otherwise
<code class="code">ECL_T</code>.
</p></dd></dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003aget_002drwlock_002dread"><span class="category-def">Function: </span><span><strong class="def-name">mp:get-rwlock-read</strong> <var class="def-var-arguments">lock &amp;optional (wait t)</var><a class="copiable-link" href='Native-threads.html#index-mp_003aget_002drwlock_002dread'> &para;</a></span></dt>
<dd><p>Tries to acquire <var class="var">lock</var>. <var class="var">wait</var> indicates whenever function
should block or give up if <var class="var">lock</var> is already taken with
<code class="code"><a class="ref" href="Native-threads.html#mp_003aget_002drwlock_002dwrite">mp:get-rwlock-write</a></code>.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005fget_005frwlock_005fwrite_005fwait"></a><a class="index-entry-id" id="index-mp_005fget_005frwlock_005fwrite_005fwait"></a>
<a class="anchor" id="mp_005fget_005frwlock_005fwrite_005fnowait"></a><a class="index-entry-id" id="index-mp_005fget_005frwlock_005fwrite_005fnowait"></a>
<a class="anchor" id="mp_003aget_002drwlock_002dwrite"></a><a class="index-entry-id" id="index-mp_003aget_002drwlock_002dwrite-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005fget_005frwlock_005fwrite_005fwait-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_get_rwlock_write_wait</strong> <code class="def-code-arguments">(cl_object lock)</code><a class="copiable-link" href='Native-threads.html#index-mp_005fget_005frwlock_005fwrite_005fwait-1'> &para;</a></span></dt>
<dd><p>Acquires <var class="var">lock</var> (blocks if <var class="var">lock</var> is already taken). Returns
<code class="code">ECL_T</code>.
</p></dd></dl>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005fget_005frwlock_005fwrite_005fnowait-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_get_rwlock_write_nowait</strong><a class="copiable-link" href='Native-threads.html#index-mp_005fget_005frwlock_005fwrite_005fnowait-1'> &para;</a></span></dt>
<dd><p>Tries to acquire <var class="var">lock</var>. If <var class="var">lock</var> is already taken returns
<code class="code">ECL_NIL</code>, otherwise <code class="code">ECL_T</code>.
</p></dd></dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003aget_002drwlock_002dwrite"><span class="category-def">Function: </span><span><strong class="def-name">mp:get-rwlock-write</strong> <var class="def-var-arguments">lock &amp;optional (wait t)</var><a class="copiable-link" href='Native-threads.html#index-mp_003aget_002drwlock_002dwrite'> &para;</a></span></dt>
<dd><p>Tries to acquire <var class="var">lock</var>. <var class="var">wait</var> indicates whenever function
should block or give up if <var class="var">lock</var> is already taken.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005fgiveup_005frwlock_005fread"></a><a class="index-entry-id" id="index-mp_005fgiveup_005frwlock_005fread"></a>
<a class="anchor" id="mp_005fgiveup_005frwlock_005fwrite"></a><a class="index-entry-id" id="index-mp_005fgiveup_005frwlock_005fwrite"></a>
<a class="anchor" id="mp_003agiveup_002drwlock_002dread"></a><a class="index-entry-id" id="index-mp_003agiveup_002drwlock_002dread-1"></a>
<a class="anchor" id="mp_003agiveup_002drwlock_002dwrite"></a><a class="index-entry-id" id="index-mp_003agiveup_002drwlock_002dwrite-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005fgiveup_005frwlock_005fread-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_giveup_rwlock_read</strong> <code class="def-code-arguments">(cl_object lock)</code><a class="copiable-link" href='Native-threads.html#index-mp_005fgiveup_005frwlock_005fread-1'> &para;</a></span></dt>
<dt class="deftypefnx deftypefunx-alias-deftypefnx def-cmd-deftypefn" id="index-mp_005fgiveup_005frwlock_005fwrite-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_giveup_rwlock_write</strong> <code class="def-code-arguments">(cl_object lock)</code><a class="copiable-link" href='Native-threads.html#index-mp_005fgiveup_005frwlock_005fwrite-1'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003agiveup_002drwlock_002dread"><span class="category-def">Function: </span><span><strong class="def-name">mp:giveup-rwlock-read</strong> <var class="def-var-arguments">lock</var><a class="copiable-link" href='Native-threads.html#index-mp_003agiveup_002drwlock_002dread'> &para;</a></span></dt>
<dt class="deffnx defunx-alias-deffnx def-cmd-deffn" id="index-mp_003agiveup_002drwlock_002dwrite"><span class="category-def">Function: </span><span><strong class="def-name">mp:giveup-rwlock-write</strong> <var class="def-var-arguments">lock</var><a class="copiable-link" href='Native-threads.html#index-mp_003agiveup_002drwlock_002dwrite'> &para;</a></span></dt>
<dd><p>Release <var class="var">lock</var>.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_003awith_002drwlock"></a><a class="index-entry-id" id="index-mp_003awith_002drwlock-1"></a>
<dl class="first-deffn first-defmac-alias-first-deffn">
<dt class="deffn defmac-alias-deffn" id="index-mp_003awith_002drwlock"><span class="category-def">Macro: </span><span><strong class="def-name">mp:with-rwlock</strong> <var class="def-var-arguments">(lock operation) &amp;body body</var><a class="copiable-link" href='Native-threads.html#index-mp_003awith_002drwlock'> &para;</a></span></dt>
<dd><p>Acquire rwlock for the dynamic scope of <var class="var">body</var> for operation
<var class="var">operation</var>, which is executed with the lock held by current
thread. Returns the values of body.
</p>
<p>Valid values of argument <var class="var">operation</var> are <code class="code">:read</code> or
<code class="code">:write</code> (for reader and writer access accordingly).
</p></dd></dl>
<hr>
</div>
<div class="subsection-level-extent" id="Condition-variables">
<div class="nav-panel">
<p>
Next: <a href="Native-threads.html#Condition-variables-dictionary" accesskey="n" rel="next">Condition variables dictionary</a>, Previous: <a href="Native-threads.html#Readers_002dwriter-locks-dictionary" accesskey="p" rel="prev">Read-Write locks dictionary</a>, Up: <a href="Native-threads.html#Native-threads" accesskey="u" rel="up">Native threads</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsection" id="Condition-variables-1">3.4.8 Condition variables</h4>
<p>Condition variables are used to wait for a particular condition becoming
true (e.g new client connects to the server).
</p>
<hr>
</div>
<div class="subsection-level-extent" id="Condition-variables-dictionary">
<div class="nav-panel">
<p>
Next: <a href="Native-threads.html#Semaphores" accesskey="n" rel="next">Semaphores</a>, Previous: <a href="Native-threads.html#Condition-variables" accesskey="p" rel="prev">Condition variables</a>, Up: <a href="Native-threads.html#Native-threads" accesskey="u" rel="up">Native threads</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsection" id="Condition-variables-dictionary-1">3.4.9 Condition variables dictionary</h4>
&#12;
<a class="anchor" id="mp_005fmake_005fcondition_005fvariable"></a><a class="index-entry-id" id="index-mp_005fmake_005fcondition_005fvariable"></a>
<a class="anchor" id="mp_003amake_002dcondition_002dvariable"></a><a class="index-entry-id" id="index-mp_003amake_002dcondition_002dvariable-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005fmake_005fcondition_005fvariable-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_make_condition_variable</strong> <code class="def-code-arguments">()</code><a class="copiable-link" href='Native-threads.html#index-mp_005fmake_005fcondition_005fvariable-1'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003amake_002dcondition_002dvariable"><span class="category-def">Function: </span><span><strong class="def-name">mp:make-condition-variable</strong><a class="copiable-link" href='Native-threads.html#index-mp_003amake_002dcondition_002dvariable'> &para;</a></span></dt>
<dd><p>Creates a condition variable.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005fcondition_005fvariable_005fwait"></a><a class="index-entry-id" id="index-mp_005fcondition_005fvariable_005fwait"></a>
<a class="anchor" id="mp_003acondition_002dvariable_002dwait"></a><a class="index-entry-id" id="index-mp_003acondition_002dvariable_002dwait-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005fcondition_005fvariable_005fwait-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_condition_variable_wait</strong> <code class="def-code-arguments">(cl_object cv, cl_object lock)</code><a class="copiable-link" href='Native-threads.html#index-mp_005fcondition_005fvariable_005fwait-1'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003acondition_002dvariable_002dwait"><span class="category-def">Function: </span><span><strong class="def-name">mp:condition-variable-wait</strong> <var class="def-var-arguments">cv lock</var><a class="copiable-link" href='Native-threads.html#index-mp_003acondition_002dvariable_002dwait'> &para;</a></span></dt>
<dd><p>Release <var class="var">lock</var> and suspend thread until
<code class="code"><a class="ref" href="Native-threads.html#mp_003acondition_002dvariable_002dsignal">mp:condition-variable-signal</a></code> or
<code class="code"><a class="ref" href="Native-threads.html#mp_003acondition_002dvariable_002dbroadcast">mp:condition-variable-broadcast</a></code> is called on <var class="var">cv</var>. When
thread resumes re-aquire <var class="var">lock</var>. Always returns <code class="code">t</code>. May signal
an error if <var class="var">lock</var> is not owned by the current thread.
</p>
<p><strong class="strong">Note:</strong> In some circumstances, the thread may wake up even if no
call to <code class="code"><a class="ref" href="Native-threads.html#mp_003acondition_002dvariable_002dsignal">mp:condition-variable-signal</a></code> or
<code class="code"><a class="ref" href="Native-threads.html#mp_003acondition_002dvariable_002dbroadcast">mp:condition-variable-broadcast</a></code> has happened. It is
recommended to check for the condition that triggered the wait in a loop
around any <code class="code">mp:condition-variable-wait</code> call.
</p>
<p><strong class="strong">Note:</strong> While the condition variable is blocked waiting for a
signal or broadcast event, calling <code class="code">mp:condition-variable-wait</code>
from further threads must be done using the same mutex as that used by
the threads that are already waiting on this condition variable. The
behaviour is undefined if this constraint is violated.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005fcondition_005fvariable_005ftimedwait"></a><a class="index-entry-id" id="index-mp_005fcondition_005fvariable_005ftimedwait"></a>
<a class="anchor" id="mp_003acondition_002dvariable_002dtimedwait"></a><a class="index-entry-id" id="index-mp_003acondition_002dvariable_002dtimedwait-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005fcondition_005fvariable_005ftimedwait-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_condition_variable_timedwait</strong> <code class="def-code-arguments">(cl_object cv, cl_object lock, cl_object seconds)</code><a class="copiable-link" href='Native-threads.html#index-mp_005fcondition_005fvariable_005ftimedwait-1'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003acondition_002dvariable_002dtimedwait"><span class="category-def">Function: </span><span><strong class="def-name">mp:condition-variable-timedwait</strong> <var class="def-var-arguments">cv lock seconds</var><a class="copiable-link" href='Native-threads.html#index-mp_003acondition_002dvariable_002dtimedwait'> &para;</a></span></dt>
<dd><p><code class="code"><a class="ref" href="Native-threads.html#mp_003acondition_002dvariable_002dwait">mp:condition-variable-wait</a></code> which timeouts after <var class="var">seconds</var>
seconds. Returns <code class="code">nil</code> on timeout and <code class="code">t</code> otherwise. May
signal an error if <var class="var">lock</var> is not owned by the current thread.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005fcondition_005fvariable_005fsignal"></a><a class="index-entry-id" id="index-mp_005fcondition_005fvariable_005fsignal"></a>
<a class="anchor" id="mp_003acondition_002dvariable_002dsignal"></a><a class="index-entry-id" id="index-mp_003acondition_002dvariable_002dsignal-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005fcondition_005fvariable_005fsignal-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_condition_variable_signal</strong> <code class="def-code-arguments">(cl_object cv)</code><a class="copiable-link" href='Native-threads.html#index-mp_005fcondition_005fvariable_005fsignal-1'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003acondition_002dvariable_002dsignal"><span class="category-def">Function: </span><span><strong class="def-name">mp:condition-variable-signal</strong> <var class="def-var-arguments">cv</var><a class="copiable-link" href='Native-threads.html#index-mp_003acondition_002dvariable_002dsignal'> &para;</a></span></dt>
<dd><p>Wake up at least one of the waiters of <var class="var">cv</var>. Usually, this will wake
up only a single thread, but it may also wake up multiple threads.
Always returns <code class="code">t</code>.
</p>
<p>See <code class="code"><a class="ref" href="Native-threads.html#mp_003acondition_002dvariable_002dwait">mp:condition-variable-wait</a></code>.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005fcondition_005fvariable_002dbroadcast"></a><a class="index-entry-id" id="index-mp_005fcondition_005fvariable_002dbroadcast"></a>
<a class="anchor" id="mp_003acondition_002dvariable_002dbroadcast"></a><a class="index-entry-id" id="index-mp_003acondition_002dvariable_002dbroadcast-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005fcondition_005fvariable_005fbroadcast"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_condition_variable_broadcast</strong> <code class="def-code-arguments">(cl_object cv)</code><a class="copiable-link" href='Native-threads.html#index-mp_005fcondition_005fvariable_005fbroadcast'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003acondition_002dvariable_002dbroadcast"><span class="category-def">Function: </span><span><strong class="def-name">mp:condition-variable-broadcast</strong> <var class="def-var-arguments">cv</var><a class="copiable-link" href='Native-threads.html#index-mp_003acondition_002dvariable_002dbroadcast'> &para;</a></span></dt>
<dd><p>Wake up all waiters of <var class="var">cv</var>. Always returns <code class="code">t</code>.
</p>
<p>See <code class="code"><a class="ref" href="Native-threads.html#mp_003acondition_002dvariable_002dwait">mp:condition-variable-wait</a></code>.
</p></dd></dl>
<hr>
</div>
<div class="subsection-level-extent" id="Semaphores">
<div class="nav-panel">
<p>
Next: <a href="Native-threads.html#Semaphores-dictionary" accesskey="n" rel="next">Semaphores dictionary</a>, Previous: <a href="Native-threads.html#Condition-variables-dictionary" accesskey="p" rel="prev">Condition variables dictionary</a>, Up: <a href="Native-threads.html#Native-threads" accesskey="u" rel="up">Native threads</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsection" id="Semaphores-1">3.4.10 Semaphores</h4>
<a class="index-entry-id" id="index-Semaphores-_0028synchronization_0029"></a>
<p>Semaphores are objects which allow an arbitrary resource
count. Semaphores are used for shared access to resources where number
of concurrent threads allowed to access it is limited.
</p>
<hr>
</div>
<div class="subsection-level-extent" id="Semaphores-dictionary">
<div class="nav-panel">
<p>
Next: <a href="Native-threads.html#Barriers" accesskey="n" rel="next">Barriers</a>, Previous: <a href="Native-threads.html#Semaphores" accesskey="p" rel="prev">Semaphores</a>, Up: <a href="Native-threads.html#Native-threads" accesskey="u" rel="up">Native threads</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsection" id="Semaphores-dictionary-1">3.4.11 Semaphores dictionary</h4>
&#12;
<a class="anchor" id="ecl_005fmake_005fsemaphore"></a><a class="index-entry-id" id="index-ecl_005fmake_005fsemaphore"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-ecl_005fmake_005fsemaphore-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">ecl_make_semaphore</strong> <code class="def-code-arguments">(cl_object name, cl_fixnum count)</code><a class="copiable-link" href='Native-threads.html#index-ecl_005fmake_005fsemaphore-1'> &para;</a></span></dt>
<dd><p>C/C++ equivalent of <code class="code"><a class="ref" href="Native-threads.html#mp_003amake_002dsemaphore">mp:make-semaphore</a></code> without <code class="code">key</code>
arguments.
</p>
<p>See <code class="code"><a class="ref" href="Native-threads.html#mp_003amake_002dsemaphore">mp:make-semaphore</a></code>.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005fmake_005fsemaphore"></a><a class="index-entry-id" id="index-mp_005fmake_005fsemaphore"></a>
<a class="anchor" id="mp_003amake_002dsemaphore"></a><a class="index-entry-id" id="index-mp_003amake_002dsemaphore-1"></a>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003amake_002dsemaphore"><span class="category-def">Function: </span><span><strong class="def-name">mp:make-semaphore</strong> <var class="def-var-arguments">&amp;key name count</var><a class="copiable-link" href='Native-threads.html#index-mp_003amake_002dsemaphore'> &para;</a></span></dt>
<dd><p>Creates a counting semaphore <var class="var">name</var> with a resource count
<var class="var">count</var>.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005fsemaphore_005fname"></a><a class="index-entry-id" id="index-mp_005fsemaphore_005fname"></a>
<a class="anchor" id="mp_003asemaphore_002dname"></a><a class="index-entry-id" id="index-mp_003asemaphore_002dname-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005fsemaphore_005fname-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_semaphore_name</strong> <code class="def-code-arguments">(cl_object semaphore)</code><a class="copiable-link" href='Native-threads.html#index-mp_005fsemaphore_005fname-1'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003asemaphore_002dname"><span class="category-def">Function: </span><span><strong class="def-name">mp:semaphore-name</strong> <var class="def-var-arguments">semaphore</var><a class="copiable-link" href='Native-threads.html#index-mp_003asemaphore_002dname'> &para;</a></span></dt>
<dd><p>Returns the name of <var class="var">semaphore</var>.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005fsemaphore_005fcount"></a><a class="index-entry-id" id="index-mp_005fsemaphore_005fcount"></a>
<a class="anchor" id="mp_003asemaphore_002dcount"></a><a class="index-entry-id" id="index-mp_003asemaphore_002dcount-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005fsemaphore_005fcount-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_semaphore_count</strong> <code class="def-code-arguments">(cl_object semaphore)</code><a class="copiable-link" href='Native-threads.html#index-mp_005fsemaphore_005fcount-1'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003asemaphore_002dcount"><span class="category-def">Function: </span><span><strong class="def-name">mp:semaphore-count</strong> <var class="def-var-arguments">semaphore</var><a class="copiable-link" href='Native-threads.html#index-mp_003asemaphore_002dcount'> &para;</a></span></dt>
<dd><p>Returns the resource count of <var class="var">semaphore</var>.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005fsemaphore_005fwait_005fcount"></a><a class="index-entry-id" id="index-mp_005fsemaphore_005fwait_005fcount"></a>
<a class="anchor" id="mp_003asemaphore_002dwait_002dcount"></a><a class="index-entry-id" id="index-mp_003asemaphore_002dwait_002dcount-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005fsemaphore_005fwait_005fcount-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_semaphore_wait_count</strong> <code class="def-code-arguments">(cl_object semaphore)</code><a class="copiable-link" href='Native-threads.html#index-mp_005fsemaphore_005fwait_005fcount-1'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003asemaphore_002dwait_002dcount"><span class="category-def">Function: </span><span><strong class="def-name">mp:semaphore-wait-count</strong> <var class="def-var-arguments">semaphore</var><a class="copiable-link" href='Native-threads.html#index-mp_003asemaphore_002dwait_002dcount'> &para;</a></span></dt>
<dd><p>Returns the number of threads waiting on <var class="var">semaphore</var>.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005fsemaphore_005fwait"></a><a class="index-entry-id" id="index-mp_005fsemaphore_005fwait"></a>
<a class="anchor" id="mp_003asemaphore_002dwait"></a><a class="index-entry-id" id="index-mp_003asemaphore_002dwait-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005fsempahore_005fwait_0028cl_005fobject"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_sempahore_wait(cl_object</strong> <code class="def-code-arguments">semaphore, cl_object count, cl_object timeout)</code><a class="copiable-link" href='Native-threads.html#index-mp_005fsempahore_005fwait_0028cl_005fobject'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003asemaphore_002dwait"><span class="category-def">Function: </span><span><strong class="def-name">mp:semaphore-wait</strong> <var class="def-var-arguments">semaphore count timeout</var><a class="copiable-link" href='Native-threads.html#index-mp_003asemaphore_002dwait'> &para;</a></span></dt>
<dd><p>Decrement the count of <var class="var">semaphore</var> by <var class="var">count</var> if the count
would not be negative.
</p>
<p>Else blocks until the semaphore can be decremented. Returns the old
count of <var class="var">semaphore</var> on success.
</p>
<p>If timeout is not <code class="code">nil</code>, it is the maximum number of seconds to
wait. If the count cannot be decremented in that time, returns
<code class="code">nil</code> without decrementing the count.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005fwait_005fon_005fsemaphore"></a><a class="index-entry-id" id="index-mp_005fwait_005fon_005fsemaphore"></a>
<a class="anchor" id="mp_003await_002don_002dsemaphore"></a><a class="index-entry-id" id="index-mp_003await_002don_002dsemaphore-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005fwait_005fon_005fsemaphore-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_wait_on_semaphore</strong> <code class="def-code-arguments">(cl_narg n, cl_object sem, ...)</code><a class="copiable-link" href='Native-threads.html#index-mp_005fwait_005fon_005fsemaphore-1'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003await_002don_002dsemaphore"><span class="category-def">Function: </span><span><strong class="def-name">mp:wait-on-semaphore</strong> <var class="def-var-arguments">semaphore &amp;key count timeout</var><a class="copiable-link" href='Native-threads.html#index-mp_003await_002don_002dsemaphore'> &para;</a></span></dt>
<dd><p>Waits on semaphore until it can grab <var class="var">count</var> resources.
</p>
<p>Returns resource count before semaphore was acquired.
</p>
<p>This function is equivalent to <code class="code">(mp:semaphore-wait semaphore count timeout)</code>
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005ftry_005fget_005fsemaphore"></a><a class="index-entry-id" id="index-mp_005ftry_005fget_005fsemaphore"></a>
<a class="anchor" id="mp_003atry_002dget_002dsemaphore"></a><a class="index-entry-id" id="index-mp_003atry_002dget_002dsemaphore-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005ftry_005fget_005fsemaphore-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_try_get_semaphore</strong> <code class="def-code-arguments">(cl_narg n, cl_object sem, ...)</code><a class="copiable-link" href='Native-threads.html#index-mp_005ftry_005fget_005fsemaphore-1'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003atry_002dget_002dsemaphore"><span class="category-def">Function: </span><span><strong class="def-name">mp:try-get-semaphore</strong> <var class="def-var-arguments">semaphore &amp;optional count</var><a class="copiable-link" href='Native-threads.html#index-mp_003atry_002dget_002dsemaphore'> &para;</a></span></dt>
<dd><p>Tries to get a semaphore (non-blocking).
</p>
<p>If there is no enough resource returns <code class="code">nil</code>, otherwise returns
resource count before semaphore was acquired.
</p>
<p>This function is equivalent to <code class="code">(mp:semaphore-wait semaphore count 0)</code>
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005fsignal_005fsemaphore"></a><a class="index-entry-id" id="index-mp_005fsignal_005fsemaphore"></a>
<a class="anchor" id="mp_003asignal_002dsemaphore"></a><a class="index-entry-id" id="index-mp_003asignal_002dsemaphore-1"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-mp_005fsignal_005fsemaphore-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">mp_signal_semaphore</strong> <code class="def-code-arguments">(cl_narg n, cl_object sem, ...);</code><a class="copiable-link" href='Native-threads.html#index-mp_005fsignal_005fsemaphore-1'> &para;</a></span></dt>
</dl>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003asignal_002dsemaphore"><span class="category-def">Function: </span><span><strong class="def-name">mp:signal-semaphore</strong> <var class="def-var-arguments">semaphore &amp;optional (count 1)</var><a class="copiable-link" href='Native-threads.html#index-mp_003asignal_002dsemaphore'> &para;</a></span></dt>
<dd><p>Releases <var class="var">count</var> units of a resource on <var class="var">semaphore</var>. Returns no
values.
</p></dd></dl>
<hr>
</div>
<div class="subsection-level-extent" id="Barriers">
<div class="nav-panel">
<p>
Next: <a href="Native-threads.html#Barriers-dictionary" accesskey="n" rel="next">Barriers dictionary</a>, Previous: <a href="Native-threads.html#Semaphores-dictionary" accesskey="p" rel="prev">Semaphores dictionary</a>, Up: <a href="Native-threads.html#Native-threads" accesskey="u" rel="up">Native threads</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsection" id="Barriers-1">3.4.12 Barriers</h4>
<a class="index-entry-id" id="index-Barriers-_0028synchronization_0029"></a>
<p>Barriers are objects which for a group of threads make them stop and
they can&rsquo;t proceed until all other threads reach the barrier.
</p>
<hr>
</div>
<div class="subsection-level-extent" id="Barriers-dictionary">
<div class="nav-panel">
<p>
Next: <a href="Native-threads.html#Atomic-operations" accesskey="n" rel="next">Atomic operations</a>, Previous: <a href="Native-threads.html#Barriers" accesskey="p" rel="prev">Barriers</a>, Up: <a href="Native-threads.html#Native-threads" accesskey="u" rel="up">Native threads</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsection" id="Barriers-dictionary-1">3.4.13 Barriers dictionary</h4>
&#12;
<a class="anchor" id="ecl_005fmake_005fbarrier"></a><a class="index-entry-id" id="index-ecl_005fmake_005fbarrier"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-ecl_005fmake_005fbarrier-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">ecl_make_barrier</strong> <code class="def-code-arguments">(cl_object name, cl_index count)</code><a class="copiable-link" href='Native-threads.html#index-ecl_005fmake_005fbarrier-1'> &para;</a></span></dt>
<dd><p>C/C++ equivalent of <code class="code"><a class="ref" href="Native-threads.html#mp_003amake_002dbarrier">mp:make-barrier</a></code> without <code class="code">key</code>
arguments.
</p>
<p>See <code class="code"><a class="ref" href="Native-threads.html#mp_003amake_002dbarrier">mp:make-barrier</a></code>.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005fmake_005fbarrier"></a><a class="index-entry-id" id="index-mp_005fmake_005fbarrier"></a>
<a class="anchor" id="mp_003amake_002dbarrier"></a><a class="index-entry-id" id="index-mp_003amake_002dbarrier-1"></a>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003amake_002dbarrier"><span class="category-def">Function: </span><span><strong class="def-name">mp:make-barrier</strong> <var class="def-var-arguments">count &amp;key name</var><a class="copiable-link" href='Native-threads.html#index-mp_003amake_002dbarrier'> &para;</a></span></dt>
<dd><p>Creates a barrier <var class="var">name</var> with a thread count <var class="var">count</var>.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005fbarrier_005fcount"></a><a class="index-entry-id" id="index-mp_005fbarrier_005fcount"></a>
<a class="anchor" id="mp_003abarrier_002dcount"></a><a class="index-entry-id" id="index-mp_003abarrier_002dcount-1"></a>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003abarrier_002dcount"><span class="category-def">Function: </span><span><strong class="def-name">mp:barrier-count</strong> <var class="def-var-arguments">barrier</var><a class="copiable-link" href='Native-threads.html#index-mp_003abarrier_002dcount'> &para;</a></span></dt>
<dd><p>Returns the count of <var class="var">barrier</var>.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005fbarrier_005fname"></a><a class="index-entry-id" id="index-mp_005fbarrier_005fname"></a>
<a class="anchor" id="mp_003abarrier_002dname"></a><a class="index-entry-id" id="index-mp_003abarrier_002dname-1"></a>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003abarrier_002dname"><span class="category-def">Function: </span><span><strong class="def-name">mp:barrier-name</strong> <var class="def-var-arguments">barrier</var><a class="copiable-link" href='Native-threads.html#index-mp_003abarrier_002dname'> &para;</a></span></dt>
<dd><p>Returns the name of <var class="var">barrier</var>.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005fbarrier_005farrivers_005fcount"></a><a class="index-entry-id" id="index-mp_005fbarrier_005farrivers_005fcount"></a>
<a class="anchor" id="mp_003abarrier_002darrivers_002dcount"></a><a class="index-entry-id" id="index-mp_003abarrier_002darrivers_002dcount-1"></a>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003abarrier_002darrivers_002dcount"><span class="category-def">Function: </span><span><strong class="def-name">mp:barrier-arrivers-count</strong> <var class="def-var-arguments">barrier</var><a class="copiable-link" href='Native-threads.html#index-mp_003abarrier_002darrivers_002dcount'> &para;</a></span></dt>
<dd><p>Returns the number of threads waiting on <var class="var">barrier</var>.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005fbarrier_005fwait"></a><a class="index-entry-id" id="index-mp_005fbarrier_005fwait"></a>
<a class="anchor" id="mp_003abarrier_002dwait"></a><a class="index-entry-id" id="index-mp_003abarrier_002dwait-1"></a>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003abarrier_002dwait"><span class="category-def">Function: </span><span><strong class="def-name">mp:barrier-wait</strong> <var class="def-var-arguments">barrier</var><a class="copiable-link" href='Native-threads.html#index-mp_003abarrier_002dwait'> &para;</a></span></dt>
<dd><p>The caller thread waits on <var class="var">barrier</var>. When the barrier is saturated
then all threads waiting on it are unblocked. Returns <code class="code">t</code> if the
calling thread had to wait to pass the barrier, <code class="code">:unblocked</code> if the
barrier is enabled but could be passed without waiting and <code class="code">nil</code> if
the barrier is disabled.
</p></dd></dl>
&#12;
<a class="anchor" id="mp_005fbarrier_005funblock"></a><a class="index-entry-id" id="index-mp_005fbarrier_005funblock"></a>
<a class="anchor" id="mp_003abarrier_002dunblock"></a><a class="index-entry-id" id="index-mp_003abarrier_002dunblock-1"></a>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003abarrier_002dunblock"><span class="category-def">Function: </span><span><strong class="def-name">mp:barrier-unblock</strong> <var class="def-var-arguments">barrier &amp;key reset-count disable kill-waiting</var><a class="copiable-link" href='Native-threads.html#index-mp_003abarrier_002dunblock'> &para;</a></span></dt>
<dd><p>Forcefully wakes up all processes waiting on the barrier.
</p>
<p><var class="var">reset-count</var> when used resets <var class="var">barrier</var> counter.
</p>
<p><var class="var">disable</var> disables or enables <var class="var">barrier</var>. When a barrier is
disabled then all calls to <code class="code"><a class="ref" href="Native-threads.html#mp_003abarrier_002dwait">mp:barrier-wait</a></code> immedietely
return.
</p>
<p><var class="var">kill-waiting</var> is used to kill all woken threads.
</p>
<p>Returns no values.
</p></dd></dl>
<hr>
</div>
<div class="subsection-level-extent" id="Atomic-operations">
<div class="nav-panel">
<p>
Next: <a href="Native-threads.html#Atomic-operations-dictionary" accesskey="n" rel="next">Atomic operations dictionary</a>, Previous: <a href="Native-threads.html#Barriers-dictionary" accesskey="p" rel="prev">Barriers dictionary</a>, Up: <a href="Native-threads.html#Native-threads" accesskey="u" rel="up">Native threads</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsection" id="Atomic-operations-1">3.4.14 Atomic operations</h4>
<p>ECL supports both compare-and-swap and fetch-and-add (which may be
faster on some processors) atomic operations on a number of different
places. The compare-and-swap macro is user extensible with a protocol
similar to <code class="code">setf</code>.
</p>
<hr>
</div>
<div class="subsection-level-extent" id="Atomic-operations-dictionary">
<div class="nav-panel">
<p>
Previous: <a href="Native-threads.html#Atomic-operations" accesskey="p" rel="prev">Atomic operations</a>, Up: <a href="Native-threads.html#Native-threads" accesskey="u" rel="up">Native threads</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsection" id="Atomic-operations-dictionary-1">3.4.15 Atomic operations dictionary</h4>
<h4 class="subsubheading" id="C-Reference-24">C Reference</h4>
<a class="anchor" id="ecl_005fcompare_005fand_005fswap"></a><a class="index-entry-id" id="index-ecl_005fcompare_005fand_005fswap"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-ecl_005fcompare_005fand_005fswap-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">ecl_compare_and_swap</strong> <code class="def-code-arguments">(cl_object *slot, cl_object old, cl_object new)</code><a class="copiable-link" href='Native-threads.html#index-ecl_005fcompare_005fand_005fswap-1'> &para;</a></span></dt>
<dd>
<p>Perform an atomic compare and swap operation on <var class="var">slot</var> and return
the previous value stored in <var class="var">slot</var>. If the return value is equal
to <var class="var">old</var> (comparison by <code class="code">==</code>), the operation has succeeded.
This is a inline-only function defined in &quot;ecl/ecl_atomics.h&quot;.
</p></dd></dl>
<a class="anchor" id="ecl_005fatomic_005fincf"></a><a class="index-entry-id" id="index-ecl_005fatomic_005fincf"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-ecl_005fatomic_005fincf-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">ecl_atomic_incf</strong> <code class="def-code-arguments">(cl_object *slot, cl_object increment)</code><a class="copiable-link" href='Native-threads.html#index-ecl_005fatomic_005fincf-1'> &para;</a></span></dt>
</dl>
<a class="anchor" id="ecl_005fatomic_005fincf_005fby_005ffixnum"></a><a class="index-entry-id" id="index-ecl_005fatomic_005fincf_005fby_005ffixnum"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-ecl_005fatomic_005fincf_005fby_005ffixnum-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">ecl_atomic_incf_by_fixnum</strong> <code class="def-code-arguments">(cl_object *slot, cl_fixnum increment)</code><a class="copiable-link" href='Native-threads.html#index-ecl_005fatomic_005fincf_005fby_005ffixnum-1'> &para;</a></span></dt>
<dd>
<p>Atomically increment <var class="var">slot</var> by the given increment and return the
previous value stored in <var class="var">slot</var>. The consequences are undefined if
the value of <var class="var">slot</var> is not of type <code class="code">fixnum</code>.
<code class="code"><a class="ref" href="Native-threads.html#ecl_005fatomic_005fincf">ecl_atomic_incf</a></code> signals an error if <var class="var">increment</var> is not of
type <code class="code">fixnum</code>. This is a inline-only function defined in
&quot;ecl/ecl_atomics.h&quot;.
</p></dd></dl>
<a class="anchor" id="ecl_005fatomic_005findex_005fincf"></a><a class="index-entry-id" id="index-ecl_005fatomic_005findex_005fincf"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-ecl_005fatomic_005findex_005fincf-1"><span class="category-def">Function: </span><span><code class="def-type">cl_index</code> <strong class="def-name">ecl_atomic_index_incf</strong> <code class="def-code-arguments">(cl_index *slot);</code><a class="copiable-link" href='Native-threads.html#index-ecl_005fatomic_005findex_005fincf-1'> &para;</a></span></dt>
<dd>
<p>Atomically increment <var class="var">slot</var> by 1 and return the new value stored
in <var class="var">slot</var>.
</p></dd></dl>
<a class="anchor" id="ecl_005fatomic_005fget"></a><a class="index-entry-id" id="index-ecl_005fatomic_005fget"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-ecl_005fatomic_005fget-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">ecl_atomic_get</strong> <code class="def-code-arguments">(cl_object *slot)</code><a class="copiable-link" href='Native-threads.html#index-ecl_005fatomic_005fget-1'> &para;</a></span></dt>
<dd>
<p>Perform a volatile load of the object in <var class="var">slot</var> and then
atomically set <var class="var">slot</var> to <code class="code">ECL_NIL</code>. Returns the value
previously stored in <var class="var">slot</var>.
</p></dd></dl>
<a class="anchor" id="ecl_005fatomic_005fpush"></a><a class="index-entry-id" id="index-ecl_005fatomic_005fpush"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-ecl_005fatomic_005fpush-1"><span class="category-def">Function: </span><span><code class="def-type">void</code> <strong class="def-name">ecl_atomic_push</strong> <code class="def-code-arguments">(cl_object *slot, cl_object o)</code><a class="copiable-link" href='Native-threads.html#index-ecl_005fatomic_005fpush-1'> &para;</a></span></dt>
</dl>
<a class="anchor" id="ecl_005fatomic_005fpop"></a><a class="index-entry-id" id="index-ecl_005fatomic_005fpop"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-ecl_005fatomic_005fpop-1"><span class="category-def">Function: </span><span><code class="def-type">cl_object</code> <strong class="def-name">ecl_atomic_pop</strong> <code class="def-code-arguments">(cl_object *slot)</code><a class="copiable-link" href='Native-threads.html#index-ecl_005fatomic_005fpop-1'> &para;</a></span></dt>
<dd>
<p>Like push/pop but atomic.
</p></dd></dl>
<h4 class="subsubheading" id="Lisp-Reference">Lisp Reference</h4>
<a class="anchor" id="mp_003aatomic_002dincf"></a><a class="index-entry-id" id="index-mp_003aatomic_002dincf-1"></a>
<a class="anchor" id="mp_003aatomic_002ddecf"></a><a class="index-entry-id" id="index-mp_003aatomic_002ddecf-1"></a>
<dl class="first-deffn first-defmac-alias-first-deffn">
<dt class="deffn defmac-alias-deffn" id="index-mp_003aatomic_002dincf"><span class="category-def">Macro: </span><span><strong class="def-name">mp:atomic-incf</strong> <var class="def-var-arguments">place &amp;optional (increment 1)</var><a class="copiable-link" href='Native-threads.html#index-mp_003aatomic_002dincf'> &para;</a></span></dt>
<dt class="deffnx defmacx-alias-deffnx def-cmd-deffn" id="index-mp_003aatomic_002ddecf"><span class="category-def">Macro: </span><span><strong class="def-name">mp:atomic-decf</strong> <var class="def-var-arguments">place &amp;optional (increment 1)</var><a class="copiable-link" href='Native-threads.html#index-mp_003aatomic_002ddecf'> &para;</a></span></dt>
<dd>
<p>Atomically increments/decrements the fixnum stored in <var class="var">place</var> by
the given <var class="var">increment</var> and returns the value of <var class="var">place</var> before
the increment. Incrementing and decrementing is done using modular
arithmetic, so that <code class="code"><a class="ref" href="Native-threads.html#mp_003aatomic_002dincf">mp:atomic-incf</a></code> of a place whose value is
<code class="code">most-positive-fixnum</code> by 1 results in
<code class="code">most-negative-fixnum</code> stored in place.
</p>
<p>Currently the following places are supported:
</p>
<p><code class="code">car</code>, <code class="code">cdr</code>, <code class="code">first</code>, <code class="code">rest</code>, <code class="code">svref</code>,
<code class="code">symbol-value</code>, <code class="code">slot-value</code>,
<code class="code">clos:standard-instance-access</code>,
<code class="code">clos:funcallable-standard-instance-access</code>.
</p>
<p>For <code class="code">slot-value</code>, the object should have no applicable methods
defined for <code class="code">slot-value-using-class</code> or <code class="code">(setf
slot-value-using-class)</code>.
</p>
<p>The consequences are undefined if the value of <var class="var">place</var> is not of
type <code class="code">fixnum</code>.
</p></dd></dl>
<a class="anchor" id="mp_003acompare_002dand_002dswap"></a><a class="index-entry-id" id="index-mp_003acompare_002dand_002dswap-1"></a>
<dl class="first-deffn first-defmac-alias-first-deffn">
<dt class="deffn defmac-alias-deffn" id="index-mp_003acompare_002dand_002dswap"><span class="category-def">Macro: </span><span><strong class="def-name">mp:compare-and-swap</strong> <var class="def-var-arguments">place old new</var><a class="copiable-link" href='Native-threads.html#index-mp_003acompare_002dand_002dswap'> &para;</a></span></dt>
<dd>
<p>Atomically stores <var class="var">new</var> in <var class="var">place</var> if <var class="var">old</var> is <code class="code">eq</code>
to the current value of <var class="var">place</var>. Returns the previous value of
<var class="var">place</var>: if the returned value is <code class="code">eq</code> to <var class="var">old</var>, the swap
was carried out.
</p>
<p>Currently, the following places are supported:
</p>
<p><code class="code">car</code>, <code class="code">cdr</code>, <code class="code">first</code>, <code class="code">rest</code>, <code class="code">svref</code>,
<code class="code">symbol-plist</code>, <code class="code">symbol-value</code>, <code class="code">slot-value</code>,
<code class="code">clos:standard-instance-access</code>,
<code class="code">clos:funcallable-standard-instance-access</code>, a structure slot
accessor<a class="footnote" id="DOCF4" href="Native-threads.html#FOOT4"><sup>4</sup></a> or any other place for which a compare-and-swap
expansion was defined by <code class="code"><a class="ref" href="Native-threads.html#mp_003adefcas">mp:defcas</a></code> or
<code class="code"><a class="ref" href="Native-threads.html#mp_003adefine_002dcas_002dexpander">mp:define-cas-expander</a></code>.
</p>
<p>For <code class="code">slot-value</code>, <code class="code">slot-unbound</code> is called if the slot is
unbound unless <var class="var">old</var> is <code class="code">eq</code> to <code class="code">si:unbound</code>, in which
case <var class="var">old</var> is returned and <var class="var">new</var> is assigned to the slot.
Additionally, the object should have no applicable methods defined for
<code class="code">slot-value-using-class</code> or <code class="code">(setf slot-value-using-class)</code>.
</p></dd></dl>
<a class="anchor" id="mp_003aatomic_002dupdate"></a><a class="index-entry-id" id="index-mp_003aatomic_002dupdate-1"></a>
<dl class="first-deffn first-defmac-alias-first-deffn">
<dt class="deffn defmac-alias-deffn" id="index-mp_003aatomic_002dupdate"><span class="category-def">Macro: </span><span><strong class="def-name">mp:atomic-update</strong> <var class="def-var-arguments">place update-fn &amp;rest arguments</var><a class="copiable-link" href='Native-threads.html#index-mp_003aatomic_002dupdate'> &para;</a></span></dt>
<dd>
<p>Atomically updates the CAS-able <var class="var">place</var> to the value returned by
calling <var class="var">update-fn</var> with <var class="var">arguments</var> and the old value of
<var class="var">place</var>. <var class="var">update-fn</var> must be a function accepting <code class="code">(1+
(length arguments))</code> arguments. Returns the new value which was stored
in <var class="var">place</var>.
</p>
<p><var class="var">place</var> may be read and <var class="var">update-fn</var> may be called more than
once if multiple threads are trying to write to <var class="var">place</var> at the
same time.
</p>
<a class="index-entry-id" id="index-Atomic-update-of-a-structure-slot"></a>
<p>Example:
</p>
<p>Atomic update of a structure slot. If the update would not be atomic,
the result would be unpredictable.
</p><div class="example lisp">
<pre class="lisp-preformatted">(defstruct test-struct
(slot1 0))
(let ((struct (make-test-struct)))
(mapc #'mp:process-join
(loop repeat 100
collect (mp:process-run-function
&quot;&quot;
(lambda ()
(loop repeat 1000 do
(mp:atomic-update (test-struct-slot1 struct) #'1+)
(sleep 0.00001))))))
(test-struct-slot1 struct))
=&gt; 100000
</pre></div>
</dd></dl>
<a class="anchor" id="mp_003aatomic_002dpush"></a><a class="index-entry-id" id="index-mp_003aatomic_002dpush-1"></a>
<a class="anchor" id="mp_003aatomic_002dpop"></a><a class="index-entry-id" id="index-mp_003aatomic_002dpop-1"></a>
<dl class="first-deffn first-defmac-alias-first-deffn">
<dt class="deffn defmac-alias-deffn" id="index-mp_003aatomic_002dpush"><span class="category-def">Macro: </span><span><strong class="def-name">mp:atomic-push</strong> <var class="def-var-arguments">obj place</var><a class="copiable-link" href='Native-threads.html#index-mp_003aatomic_002dpush'> &para;</a></span></dt>
<dt class="deffnx defmacx-alias-deffnx def-cmd-deffn" id="index-mp_003aatomic_002dpop"><span class="category-def">Macro: </span><span><strong class="def-name">mp:atomic-pop</strong> <var class="def-var-arguments">place</var><a class="copiable-link" href='Native-threads.html#index-mp_003aatomic_002dpop'> &para;</a></span></dt>
<dd>
<p>Like <code class="code">push</code>/<code class="code">pop</code>, but atomic. <var class="var">place</var> must be CAS-able
and may be read multiple times before the update succeeds.
</p></dd></dl>
<a class="anchor" id="mp_003adefine_002dcas_002dexpander"></a><a class="index-entry-id" id="index-mp_003adefine_002dcas_002dexpander-1"></a>
<dl class="first-deffn first-defmac-alias-first-deffn">
<dt class="deffn defmac-alias-deffn" id="index-mp_003adefine_002dcas_002dexpander"><span class="category-def">Macro: </span><span><strong class="def-name">mp:define-cas-expander</strong> <var class="def-var-arguments">accessor lambda-list &amp;body body</var><a class="copiable-link" href='Native-threads.html#index-mp_003adefine_002dcas_002dexpander'> &para;</a></span></dt>
<dd>
<p>Define a compare-and-swap expander similar to
<code class="code">define-setf-expander</code>. Defines the compare-and-swap-expander for
generalized-variables <code class="code">(accessor ...)</code>. When a form
<code class="code">(mp:compare-and-swap (accessor arg1 ... argn) old new)</code> is
evaluated, the forms given in the body of
<code class="code"><a class="ref" href="Native-threads.html#mp_003adefine_002dcas_002dexpander">mp:define-cas-expander</a></code> are evaluated in order with the
parameters in <code class="code">lambda-list</code> bound to <code class="code">arg1 ... argn</code>. The
body must return six values
</p><div class="example lisp">
<pre class="lisp-preformatted">(var1 ... vark)
(form1 ... formk)
old-var
new-var
compare-and-swap-form
volatile-access-form
</pre></div>
<p>in order (Note that <code class="code">old-var</code> and <code class="code">new-var</code> are single
variables, unlike in <code class="code">define-setf-expander</code>). The whole
<code class="code">compare-and-swap</code> form is then expanded into
</p><div class="example lisp">
<pre class="lisp-preformatted">(let* ((var1 from1) ... (vark formk)
(old-var old-form)
(new-var new-form))
compare-and-swap-form).
</pre></div>
<p>Note that it is up to the user of this macro to ensure atomicity for
the resulting compare-and-swap expansions.
</p>
<a class="index-entry-id" id="index-Define-a-compare_002dand_002dswap-expansion"></a>
<p><b class="b">Example</b>
</p>
<p><code class="code"><a class="ref" href="Native-threads.html#mp_003adefine_002dcas_002dexpander">mp:define-cas-expander</a></code> can be used to define a more
convienient compare-and-swap expansion for a class slot. Consider the
following class:
</p><div class="example lisp">
<pre class="lisp-preformatted">(defclass food ()
((name :initarg :name)
(deliciousness :initform 5 :type '(integer 0 10)
:accessor food-deliciousness)))
(defvar *spätzle* (make-instance 'food :name &quot;Spätzle&quot;))
</pre></div>
<p>We can&rsquo;t just use <code class="code"><a class="ref" href="Native-threads.html#mp_003acompare_002dand_002dswap">mp:compare-and-swap</a></code> on
<code class="code">*spätzle*</code>:
</p><div class="example lisp">
<pre class="lisp-preformatted">&gt; (mp:compare-and-swap (food-deliciousness *x*) 5 10)
Condition of type: SIMPLE-ERROR
Cannot get the compare-and-swap expansion of (FOOD-DELICIOUSNESS *X*).
</pre></div>
<p>We can use <code class="code">symbol-value</code>, but let&rsquo;s define a more convenient
compare-and-swap expander:
</p><div class="example lisp">
<pre class="lisp-preformatted">(mp:define-cas-expander food-deliciousness (food)
(let ((old (gensym))
(new (gensym)))
(values nil nil old new
`(progn (check-type ,new (integer 0 10))
(mp:compare-and-swap (slot-value ,food 'deliciousness)
,old ,new))
`(food-deliciousness ,food))))
</pre></div>
<p>Now finally, we can safely store our rating:
</p><div class="example lisp">
<pre class="lisp-preformatted">&gt; (mp:compare-and-swap (food-deliciousness *spätzle*) 5 10)
5
</pre></div>
</dd></dl>
<a class="anchor" id="mp_003adefcas"></a><a class="index-entry-id" id="index-mp_003adefcas-1"></a>
<dl class="first-deffn first-defmac-alias-first-deffn">
<dt class="deffn defmac-alias-deffn" id="index-mp_003adefcas"><span class="category-def">Macro: </span><span><strong class="def-name">mp:defcas</strong> <var class="def-var-arguments">accessor cas-fun &amp;optional documentation</var><a class="copiable-link" href='Native-threads.html#index-mp_003adefcas'> &para;</a></span></dt>
<dd>
<p>Define a compare-and-swap expansion similar to the short form
of <code class="code">defsetf</code>. Defines an expansion
</p><div class="example lisp">
<pre class="lisp-preformatted">(compare-and-swap (accessor arg1 ... argn) old new)
=&gt; (cas-fun arg1 ... argn old new)
</pre></div>
<p>Note that it is up to the user of this macro to ensure atomicity for
the resulting compare-and-swap expansions.
</p></dd></dl>
<a class="anchor" id="mp_003aremcas"></a><a class="index-entry-id" id="index-mp_003aremcas-1"></a>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003aremcas"><span class="category-def">Function: </span><span><strong class="def-name">mp:remcas</strong> <var class="def-var-arguments">symbol</var><a class="copiable-link" href='Native-threads.html#index-mp_003aremcas'> &para;</a></span></dt>
<dd>
<p>Remove a compare-and-swap expansion. It is an equivalent of
<code class="code">fmakunbound (setf symbol)</code> for cas expansions.
</p></dd></dl>
<a class="anchor" id="mp_003aget_002dcas_002dexpansion"></a><a class="index-entry-id" id="index-mp_003aget_002dcas_002dexpansion-1"></a>
<dl class="first-deffn first-defun-alias-first-deffn">
<dt class="deffn defun-alias-deffn" id="index-mp_003aget_002dcas_002dexpansion"><span class="category-def">Function: </span><span><strong class="def-name">mp:get-cas-expansion</strong> <var class="def-var-arguments">place &amp;optional environment</var><a class="copiable-link" href='Native-threads.html#index-mp_003aget_002dcas_002dexpansion'> &para;</a></span></dt>
<dd>
<p>Returns the compare-and-swap expansion forms and variables as defined in
<code class="code"><a class="ref" href="Native-threads.html#mp_003adefine_002dcas_002dexpander">mp:define-cas-expander</a></code> for <var class="var">place</var> as six values.
</p></dd></dl>
</div>
</div>
<div class="footnotes-segment">
<hr>
<h4 class="footnotes-heading">Footnotes</h4>
<h5 class="footnote-body-heading"><a id="FOOT4" href="Native-threads.html#DOCF4">(4)</a></h5>
<p>The creation of atomic structure slot accessors can be
deactivated by supplying a <code class="code">(:atomic-accessors nil)</code> option to
<code class="code">defstruct</code>.</p>
</div>
<hr>
<div class="nav-panel">
<p>
Next: <a href="Signals-and-Interrupts.html#Signals-and-Interrupts" accesskey="n" rel="next">Signals and Interrupts</a>, Previous: <a href="Foreign-Function-Interface.html#Foreign-Function-Interface" accesskey="p" rel="prev">Foreign Function Interface</a>, Up: <a href="Extensions.html" accesskey="u" rel="up">Extensions</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
</body>
</html>