1628 lines
121 KiB
HTML
1628 lines
121 KiB
HTML
|
<!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> [<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> [<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
|
||
|
"processes". 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’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> [<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> [<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'> ¶</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'> ¶</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>
|
||
|
|
||
|

|
||
|
<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'> ¶</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'> ¶</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>
|
||
|
|
||
|

|
||
|
<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'> ¶</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'> ¶</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>
|
||
|
|
||
|

|
||
|
<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'> ¶</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">&key name initial-bindings</var><a class="copiable-link" href='Native-threads.html#index-mp_003amake_002dprocess'> ¶</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>
|
||
|
|
||
|

|
||
|
<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'> ¶</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'> ¶</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’t designate a valid
|
||
|
process.
|
||
|
</p>
|
||
|
</dd></dl>
|
||
|
|
||
|

|
||
|
<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'> ¶</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'> ¶</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 &rest args)
|
||
|
(let ((process (mp:make-process name)))
|
||
|
(apply #'mp:process-preset process function args)
|
||
|
(mp:process-enable process)))
|
||
|
</pre></div>
|
||
|
</dd></dl>
|
||
|
|
||
|

|
||
|
<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'> ¶</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'> ¶</a></span></dt>
|
||
|
<dd><p>Yield the processor to other threads.
|
||
|
</p></dd></dl>
|
||
|
|
||
|

|
||
|
<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'> ¶</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'> ¶</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>
|
||
|
|
||
|

|
||
|
<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'> ¶</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'> ¶</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>
|
||
|
|
||
|

|
||
|
<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'> ¶</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'> ¶</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 "Running task (one tick per second)")
|
||
|
(let ((task (mp:process-run-function 'background #'ticking-task)))
|
||
|
(sleep 5)
|
||
|
(print "Suspending task for 5 seconds")
|
||
|
(mp:process-suspend task)
|
||
|
(sleep 5)
|
||
|
(print "Resuming task for 5 seconds")
|
||
|
(mp:process-resume task)
|
||
|
(sleep 5)
|
||
|
(print "Killing task")
|
||
|
(mp:process-kill task)))
|
||
|
</pre></div>
|
||
|
</dd></dl>
|
||
|
|
||
|

|
||
|
<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'> ¶</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'> ¶</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>
|
||
|
|
||
|

|
||
|
<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'> ¶</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'> ¶</a></span></dt>
|
||
|
<dd><p>Returns the name of a <var class="var">process</var> (if any).
|
||
|
</p></dd></dl>
|
||
|
|
||
|

|
||
|
<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'> ¶</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 &rest function-args</var><a class="copiable-link" href='Native-threads.html#index-mp_003aprocess_002dpreset'> ¶</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>
|
||
|
|
||
|

|
||
|
<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'> ¶</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 &rest function-args</var><a class="copiable-link" href='Native-threads.html#index-mp_003aprocess_002drun_002dfunction'> ¶</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 "~%;;; Counting: ~i" i)
|
||
|
(terpri)
|
||
|
(sleep 1))))
|
||
|
(mp:process-run-function 'counter #'count-numbers 10))
|
||
|
</pre></div>
|
||
|
</dd></dl>
|
||
|
|
||
|

|
||
|
<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'> ¶</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'> ¶</a></span></dt>
|
||
|
<dd><p>Returns/holds the current process of a caller.
|
||
|
</p></dd></dl>
|
||
|
|
||
|

|
||
|
<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'> ¶</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'> ¶</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>
|
||
|
|
||
|

|
||
|
<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'> ¶</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'> ¶</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>
|
||
|
|
||
|

|
||
|
<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">&body body</var><a class="copiable-link" href='Native-threads.html#index-mp_003awithout_002dinterrupts'> ¶</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>
|
||
|
|
||
|

|
||
|
<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">&body body</var><a class="copiable-link" href='Native-threads.html#index-mp_003awith_002dinterrupts'> ¶</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> [<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’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> [<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>
|
||
|
|
||
|

|
||
|
<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'> ¶</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>
|
||
|
|
||
|

|
||
|
<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">&key name (recursive nil)</var><a class="copiable-link" href='Native-threads.html#index-mp_003amake_002dlock'> ¶</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>
|
||
|
|
||
|

|
||
|
<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'> ¶</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'> ¶</a></span></dt>
|
||
|
<dd><p>Predicate verifying if <var class="var">lock</var> is recursive.
|
||
|
</p></dd></dl>
|
||
|
|
||
|

|
||
|
<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'> ¶</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'> ¶</a></span></dt>
|
||
|
<dd><p>Predicate verifying if the current thread holds <var class="var">lock</var>.
|
||
|
</p></dd></dl>
|
||
|
|
||
|

|
||
|
<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'> ¶</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'> ¶</a></span></dt>
|
||
|
<dd><p>Returns the name of <var class="var">lock</var>.
|
||
|
</p></dd></dl>
|
||
|
|
||
|

|
||
|
<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'> ¶</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'> ¶</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>
|
||
|
|
||
|

|
||
|
<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'> ¶</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'> ¶</a></span></dt>
|
||
|
<dd><p>Returns number of times <var class="var">lock</var> has been locked.
|
||
|
</p></dd></dl>
|
||
|
|
||
|

|
||
|
<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'> ¶</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'> ¶</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 &optional (wait t)</var><a class="copiable-link" href='Native-threads.html#index-mp_003aget_002dlock'> ¶</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’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>
|
||
|
|
||
|

|
||
|
<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'> ¶</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'> ¶</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>
|
||
|
|
||
|

|
||
|
<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) &body body</var><a class="copiable-link" href='Native-threads.html#index-mp_003awith_002dlock'> ¶</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> [<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> [<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>
|
||
|
|
||
|

|
||
|
<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'> ¶</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>
|
||
|
|
||
|

|
||
|
<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">&key name</var><a class="copiable-link" href='Native-threads.html#index-mp_003amake_002drwlock'> ¶</a></span></dt>
|
||
|
<dd><p>Creates a rwlock named <var class="var">name</var>.
|
||
|
</p></dd></dl>
|
||
|
|
||
|

|
||
|
<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'> ¶</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'> ¶</a></span></dt>
|
||
|
<dd><p>Returns the name of <var class="var">lock</var>.
|
||
|
</p></dd></dl>
|
||
|
|
||
|

|
||
|
<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'> ¶</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'> ¶</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 &optional (wait t)</var><a class="copiable-link" href='Native-threads.html#index-mp_003aget_002drwlock_002dread'> ¶</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>
|
||
|
|
||
|

|
||
|
<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'> ¶</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'> ¶</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 &optional (wait t)</var><a class="copiable-link" href='Native-threads.html#index-mp_003aget_002drwlock_002dwrite'> ¶</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>
|
||
|
|
||
|

|
||
|
<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'> ¶</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'> ¶</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'> ¶</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'> ¶</a></span></dt>
|
||
|
<dd><p>Release <var class="var">lock</var>.
|
||
|
</p></dd></dl>
|
||
|
|
||
|

|
||
|
<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) &body body</var><a class="copiable-link" href='Native-threads.html#index-mp_003awith_002drwlock'> ¶</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> [<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> [<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>
|
||
|
|
||
|

|
||
|
<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'> ¶</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'> ¶</a></span></dt>
|
||
|
<dd><p>Creates a condition variable.
|
||
|
</p></dd></dl>
|
||
|
|
||
|

|
||
|
<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'> ¶</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'> ¶</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>
|
||
|
|
||
|

|
||
|
<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'> ¶</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'> ¶</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>
|
||
|
|
||
|

|
||
|
<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'> ¶</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'> ¶</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>
|
||
|
|
||
|

|
||
|
<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'> ¶</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'> ¶</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> [<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> [<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>
|
||
|
|
||
|

|
||
|
<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'> ¶</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>
|
||
|
|
||
|

|
||
|
<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">&key name count</var><a class="copiable-link" href='Native-threads.html#index-mp_003amake_002dsemaphore'> ¶</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>
|
||
|
|
||
|

|
||
|
<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'> ¶</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'> ¶</a></span></dt>
|
||
|
<dd><p>Returns the name of <var class="var">semaphore</var>.
|
||
|
</p></dd></dl>
|
||
|
|
||
|

|
||
|
<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'> ¶</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'> ¶</a></span></dt>
|
||
|
<dd><p>Returns the resource count of <var class="var">semaphore</var>.
|
||
|
</p></dd></dl>
|
||
|
|
||
|

|
||
|
<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'> ¶</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'> ¶</a></span></dt>
|
||
|
<dd><p>Returns the number of threads waiting on <var class="var">semaphore</var>.
|
||
|
</p></dd></dl>
|
||
|
|
||
|

|
||
|
<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'> ¶</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'> ¶</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>
|
||
|
|
||
|

|
||
|
<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'> ¶</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 &key count timeout</var><a class="copiable-link" href='Native-threads.html#index-mp_003await_002don_002dsemaphore'> ¶</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>
|
||
|
|
||
|

|
||
|
<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'> ¶</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 &optional count</var><a class="copiable-link" href='Native-threads.html#index-mp_003atry_002dget_002dsemaphore'> ¶</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>
|
||
|
|
||
|

|
||
|
<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'> ¶</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 &optional (count 1)</var><a class="copiable-link" href='Native-threads.html#index-mp_003asignal_002dsemaphore'> ¶</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> [<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’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> [<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>
|
||
|
|
||
|

|
||
|
<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'> ¶</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>
|
||
|
|
||
|

|
||
|
<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 &key name</var><a class="copiable-link" href='Native-threads.html#index-mp_003amake_002dbarrier'> ¶</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>
|
||
|
|
||
|

|
||
|
<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'> ¶</a></span></dt>
|
||
|
<dd><p>Returns the count of <var class="var">barrier</var>.
|
||
|
</p></dd></dl>
|
||
|
|
||
|

|
||
|
<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'> ¶</a></span></dt>
|
||
|
<dd><p>Returns the name of <var class="var">barrier</var>.
|
||
|
</p></dd></dl>
|
||
|
|
||
|

|
||
|
<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'> ¶</a></span></dt>
|
||
|
<dd><p>Returns the number of threads waiting on <var class="var">barrier</var>.
|
||
|
</p></dd></dl>
|
||
|
|
||
|

|
||
|
<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'> ¶</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>
|
||
|
|
||
|

|
||
|
<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 &key reset-count disable kill-waiting</var><a class="copiable-link" href='Native-threads.html#index-mp_003abarrier_002dunblock'> ¶</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> [<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> [<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'> ¶</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 "ecl/ecl_atomics.h".
|
||
|
</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'> ¶</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'> ¶</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
|
||
|
"ecl/ecl_atomics.h".
|
||
|
</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'> ¶</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'> ¶</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'> ¶</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'> ¶</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 &optional (increment 1)</var><a class="copiable-link" href='Native-threads.html#index-mp_003aatomic_002dincf'> ¶</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 &optional (increment 1)</var><a class="copiable-link" href='Native-threads.html#index-mp_003aatomic_002ddecf'> ¶</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'> ¶</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 &rest arguments</var><a class="copiable-link" href='Native-threads.html#index-mp_003aatomic_002dupdate'> ¶</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
|
||
|
""
|
||
|
(lambda ()
|
||
|
(loop repeat 1000 do
|
||
|
(mp:atomic-update (test-struct-slot1 struct) #'1+)
|
||
|
(sleep 0.00001))))))
|
||
|
(test-struct-slot1 struct))
|
||
|
=> 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'> ¶</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'> ¶</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 &body body</var><a class="copiable-link" href='Native-threads.html#index-mp_003adefine_002dcas_002dexpander'> ¶</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 "Spätzle"))
|
||
|
</pre></div>
|
||
|
<p>We can’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">> (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’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">> (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 &optional documentation</var><a class="copiable-link" href='Native-threads.html#index-mp_003adefcas'> ¶</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)
|
||
|
=> (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'> ¶</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 &optional environment</var><a class="copiable-link" href='Native-threads.html#index-mp_003aget_002dcas_002dexpansion'> ¶</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> [<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>
|