mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-27 07:41:28 -08:00
Check in HTML version of the manual (writable on client) so that it will display automatically on the Ravenbrook server and so that we can easily include it in product releases. Copied from Perforce Change: 180338 ServerID: perforce.ravenbrook.com
276 lines
No EOL
18 KiB
HTML
276 lines
No EOL
18 KiB
HTML
|
|
|
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
|
|
|
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
|
|
<title>8. Threads — Memory Pool System 1.111.0 documentation</title>
|
|
|
|
<link rel="stylesheet" href="../_static/mps.css" type="text/css" />
|
|
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
|
|
|
<script type="text/javascript">
|
|
var DOCUMENTATION_OPTIONS = {
|
|
URL_ROOT: '../',
|
|
VERSION: '1.111.0',
|
|
COLLAPSE_INDEX: false,
|
|
FILE_SUFFIX: '.html',
|
|
HAS_SOURCE: true
|
|
};
|
|
</script>
|
|
<script type="text/javascript" src="../_static/jquery.js"></script>
|
|
<script type="text/javascript" src="../_static/underscore.js"></script>
|
|
<script type="text/javascript" src="../_static/doctools.js"></script>
|
|
<link rel="copyright" title="Copyright" href="../copyright.html" />
|
|
<link rel="top" title="Memory Pool System 1.111.0 documentation" href="../index.html" />
|
|
<link rel="up" title="Reference" href="index.html" />
|
|
<link rel="next" title="9. Roots" href="root.html" />
|
|
<link rel="prev" title="7. Scanning" href="scanning.html" />
|
|
</head>
|
|
<body>
|
|
<div class="related">
|
|
<h3>Navigation</h3>
|
|
<ul>
|
|
<li class="right" style="margin-right: 10px">
|
|
<a href="../genindex.html" title="General Index"
|
|
accesskey="I">index</a></li>
|
|
<li class="right" >
|
|
<a href="root.html" title="9. Roots"
|
|
accesskey="N">next</a> |</li>
|
|
<li class="right" >
|
|
<a href="scanning.html" title="7. Scanning"
|
|
accesskey="P">previous</a> |</li>
|
|
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> »</li>
|
|
<li><a href="index.html" accesskey="U">Reference</a> »</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="document">
|
|
<div class="documentwrapper">
|
|
<div class="bodywrapper">
|
|
<div class="body">
|
|
|
|
<div class="section" id="threads">
|
|
<span id="topic-thread"></span><span id="index-0"></span><h1>8. Threads<a class="headerlink" href="#threads" title="Permalink to this headline">¶</a></h1>
|
|
<div class="section" id="thread-safety">
|
|
<span id="index-1"></span><h2>8.1. Thread safety<a class="headerlink" href="#thread-safety" title="Permalink to this headline">¶</a></h2>
|
|
<p>The MPS is designed to run in an environment with multiple threads all
|
|
calling into the MPS. Some code is known to operate with exclusive
|
|
access to the data it manipulates (for example, allocation via
|
|
<a class="reference internal" href="../glossary/a.html#term-allocation-point"><em class="xref std std-term">allocation points</em></a>, in the common case where the buffer does
|
|
not need to be refilled, and <a class="reference internal" href="../glossary/l.html#term-location-dependency"><em class="xref std std-term">location dependencies</em></a>), so this
|
|
code is safe. For the rest of the code, shared data structures are
|
|
locked by the use of a single lock per <a class="reference internal" href="../glossary/a.html#term-arena"><em class="xref std std-term">arena</em></a>. This lock is
|
|
claimed on entry to the MPS and released on exit from it. So there is
|
|
at most a single thread (per arena) running “inside” the MPS at a
|
|
time.</p>
|
|
</div>
|
|
<div class="section" id="thread-registration">
|
|
<span id="topic-thread-register"></span><span id="index-2"></span><h2>8.2. Thread registration<a class="headerlink" href="#thread-registration" title="Permalink to this headline">¶</a></h2>
|
|
<p>In order to scan a thread’s registers for references (which happens at
|
|
each <a class="reference internal" href="../glossary/f.html#term-flip"><em class="xref std std-term">flip</em></a>), the MPS needs to be able to suspend that thread,
|
|
and in order to gain exclusive atomic access to memory in order to
|
|
scan it, the MPS needs to be able to suspend all threads that might
|
|
access that memory. This means that threads must be registered with
|
|
the MPS by calling <a class="reference internal" href="#mps_thread_reg" title="mps_thread_reg"><tt class="xref c c-func docutils literal"><span class="pre">mps_thread_reg()</span></tt></a> (and thread roots created;
|
|
see <a class="reference internal" href="root.html#topic-root-thread"><em>Thread roots</em></a>).</p>
|
|
<p>For simplicity, we recommend that a thread must be registered with an
|
|
<a class="reference internal" href="../glossary/a.html#term-arena"><em class="xref std std-term">arena</em></a> if:</p>
|
|
<ul class="simple">
|
|
<li>its registers and control stack form a root (this is enforced by
|
|
<a class="reference internal" href="root.html#mps_root_create_reg" title="mps_root_create_reg"><tt class="xref c c-func docutils literal"><span class="pre">mps_root_create_reg()</span></tt></a>); or</li>
|
|
<li>it reads or writes from a location in an <a class="reference internal" href="../glossary/a.html#term-automatic-memory-management"><em class="xref std std-term">automatically managed</em></a> <a class="reference internal" href="../glossary/p.html#term-pool"><em class="xref std std-term">pool</em></a> in the arena.</li>
|
|
</ul>
|
|
<p>However, some automatically managed pool classes may be more liberal
|
|
than this. See the documentation for the pool class.</p>
|
|
<div class="admonition warning">
|
|
<p class="first admonition-title">Warning</p>
|
|
<p>On Unix platforms, the MPS suspends and resumes threads by sending
|
|
them signals. There’s a shortage of available signals that aren’t
|
|
already dedicated to other purposes (for example, LinuxThreads
|
|
uses <tt class="docutils literal"><span class="pre">SIGUSR1</span></tt> and <tt class="docutils literal"><span class="pre">SIGUSR2</span></tt>), so the MPS uses <tt class="docutils literal"><span class="pre">SIGXCPU</span></tt> and
|
|
<tt class="docutils literal"><span class="pre">SIGXFSZ</span></tt>. This means that a program that handles these signals
|
|
needs to co-operate with the MPS.</p>
|
|
<p class="last">The mechanism for co-operation is currently undocumented: please
|
|
<a class="reference internal" href="../contact.html#contact"><em>contact us</em></a>.</p>
|
|
</div>
|
|
</div>
|
|
<div class="section" id="signal-handling-issues">
|
|
<span id="index-3"></span><h2>8.3. Signal handling issues<a class="headerlink" href="#signal-handling-issues" title="Permalink to this headline">¶</a></h2>
|
|
<p>The MPS uses <a class="reference internal" href="../glossary/b.html#term-barrier-1"><em class="xref std std-term">barriers<sup>(1)</sup></em></a> to <a class="reference internal" href="../glossary/p.html#term-protection"><em class="xref std std-term">protect</em></a>
|
|
memory from the <a class="reference internal" href="../glossary/c.html#term-client-program"><em class="xref std std-term">client program</em></a> and handles the signals that
|
|
result from barrier hits.</p>
|
|
<p>On some operating systems, barrier hits generate exceptions that have
|
|
to be caught by a handler that is on the stack. On these operating
|
|
systems, any code that uses memory managed by the MPS must be called
|
|
from inside such an exception handler, that is, inside a call to
|
|
<a class="reference internal" href="#mps_tramp" title="mps_tramp"><tt class="xref c c-func docutils literal"><span class="pre">mps_tramp()</span></tt></a>.</p>
|
|
<div class="admonition-note admonition">
|
|
<p class="first admonition-title">Note</p>
|
|
<p>In fact, it’s only Windows that requires the structured exception
|
|
handler to be on the stack. On other operating systems you can get
|
|
away without calling the trampoline. Nonetheless, for portability
|
|
and forwards compatibility we recommend that each thread that runs
|
|
code that accesses memory managed by the MPS should run it inside
|
|
a call to <a class="reference internal" href="#mps_tramp" title="mps_tramp"><tt class="xref c c-func docutils literal"><span class="pre">mps_tramp()</span></tt></a>.</p>
|
|
<p class="last">On Windows, the requirement to call the trampoline extends to your
|
|
structured exception handlers as well as your threads: any
|
|
structured exception handler that accesses memory managed by the
|
|
MPS must perform the access inside a call to <a class="reference internal" href="#mps_tramp" title="mps_tramp"><tt class="xref c c-func docutils literal"><span class="pre">mps_tramp()</span></tt></a>.</p>
|
|
</div>
|
|
<div class="admonition warning">
|
|
<p class="first admonition-title">Warning</p>
|
|
<p>The use of barriers has the consequence that a program that
|
|
handles <tt class="docutils literal"><span class="pre">SIGBUS</span></tt> (on OS X), <tt class="docutils literal"><span class="pre">SIGSEGV</span></tt> (on FreeBSD or Linux),
|
|
or first-chance exceptions (on Windows) needs to co-operate with
|
|
the MPS.</p>
|
|
<p class="last">The mechanism for co-operation is currently undocumented: please
|
|
<a class="reference internal" href="../contact.html#contact"><em>contact us</em></a>.</p>
|
|
</div>
|
|
</div>
|
|
<div class="section" id="thread-interface">
|
|
<span id="index-4"></span><h2>8.4. Thread interface<a class="headerlink" href="#thread-interface" title="Permalink to this headline">¶</a></h2>
|
|
<dl class="type">
|
|
<dt id="mps_thr_t">
|
|
<tt class="descname">mps_thr_t</tt><a class="headerlink" href="#mps_thr_t" title="Permalink to this definition">¶</a></dt>
|
|
<dd><p>The type of registered <a class="reference internal" href="../glossary/t.html#term-thread"><em class="xref std std-term">thread</em></a> descriptions.</p>
|
|
<p>In a multi-threaded environment where <a class="reference internal" href="../glossary/i.html#term-incremental-garbage-collection"><em class="xref std std-term">incremental garbage
|
|
collection</em></a> is used, threads must be registered with the MPS by
|
|
calling <a class="reference internal" href="#mps_thread_reg" title="mps_thread_reg"><tt class="xref c c-func docutils literal"><span class="pre">mps_thread_reg()</span></tt></a> so that the MPS can suspend them
|
|
as necessary in order to have exclusive access to their state.</p>
|
|
<p>Even in a single-threaded environment it may be necessary to
|
|
register a thread with the MPS so that its stack can be registered
|
|
as a <a class="reference internal" href="../glossary/r.html#term-root"><em class="xref std std-term">root</em></a> by calling <a class="reference internal" href="root.html#mps_root_create_reg" title="mps_root_create_reg"><tt class="xref c c-func docutils literal"><span class="pre">mps_root_create_reg()</span></tt></a>.</p>
|
|
</dd></dl>
|
|
|
|
<dl class="function">
|
|
<dt id="mps_thread_reg">
|
|
<a class="reference internal" href="error.html#mps_res_t" title="mps_res_t">mps_res_t</a> <tt class="descname">mps_thread_reg</tt><big>(</big><a class="reference internal" href="#mps_thr_t" title="mps_thr_t">mps_thr_t</a><em> *thr_o</em>, <a class="reference internal" href="arena.html#mps_arena_t" title="mps_arena_t">mps_arena_t</a><em> arena</em><big>)</big><a class="headerlink" href="#mps_thread_reg" title="Permalink to this definition">¶</a></dt>
|
|
<dd><p>Register the current <a class="reference internal" href="../glossary/t.html#term-thread"><em class="xref std std-term">thread</em></a> with an <a class="reference internal" href="../glossary/a.html#term-arena"><em class="xref std std-term">arena</em></a>.</p>
|
|
<p><tt class="docutils literal"><span class="pre">thr_o</span></tt> points to a location that will hold the address of the
|
|
registered thread description, if successful.</p>
|
|
<p><tt class="docutils literal"><span class="pre">arena</span></tt> is the arena.</p>
|
|
<p>Returns <a class="reference internal" href="error.html#MPS_RES_OK" title="MPS_RES_OK"><tt class="xref c c-macro docutils literal"><span class="pre">MPS_RES_OK</span></tt></a> if successful, or another
|
|
<a class="reference internal" href="../glossary/r.html#term-result-code"><em class="xref std std-term">result code</em></a> if not.</p>
|
|
<p>A thread must be registered with an arena if it ever uses a
|
|
pointer to a location in an <a class="reference internal" href="../glossary/a.html#term-automatic-memory-management"><em class="xref std std-term">automatically managed</em></a> <a class="reference internal" href="../glossary/p.html#term-pool"><em class="xref std std-term">pool</em></a> belonging to that
|
|
arena.</p>
|
|
<div class="admonition-note admonition">
|
|
<p class="first admonition-title">Note</p>
|
|
<p class="last">It is recommended that all threads be registered with all
|
|
arenas.</p>
|
|
</div>
|
|
</dd></dl>
|
|
|
|
<dl class="function">
|
|
<dt id="mps_thread_dereg">
|
|
void <tt class="descname">mps_thread_dereg</tt><big>(</big><a class="reference internal" href="#mps_thr_t" title="mps_thr_t">mps_thr_t</a><em> thr</em><big>)</big><a class="headerlink" href="#mps_thread_dereg" title="Permalink to this definition">¶</a></dt>
|
|
<dd><p>Deregister a <a class="reference internal" href="../glossary/t.html#term-thread"><em class="xref std std-term">thread</em></a>.</p>
|
|
<p><tt class="docutils literal"><span class="pre">thr</span></tt> is the description of the thread.</p>
|
|
<p>After calling this function, the thread whose registration with an
|
|
<a class="reference internal" href="../glossary/a.html#term-arena"><em class="xref std std-term">arena</em></a> was recorded in <tt class="docutils literal"><span class="pre">thr</span></tt> must not read or write from
|
|
a location in an <a class="reference internal" href="../glossary/a.html#term-automatic-memory-management"><em class="xref std std-term">automatically managed</em></a> <a class="reference internal" href="../glossary/p.html#term-pool"><em class="xref std std-term">pool</em></a> belonging to that arena.</p>
|
|
<div class="admonition-note admonition">
|
|
<p class="first admonition-title">Note</p>
|
|
<p class="last">Some pool classes may be more liberal about what a thread may
|
|
do after it has been deregistered. See the documentation for
|
|
the pool class.</p>
|
|
</div>
|
|
<div class="admonition-note admonition">
|
|
<p class="first admonition-title">Note</p>
|
|
<p class="last">It is recommended that threads be deregistered only when they
|
|
are just about to exit.</p>
|
|
</div>
|
|
</dd></dl>
|
|
|
|
<dl class="function">
|
|
<dt id="mps_tramp">
|
|
void <tt class="descname">mps_tramp</tt><big>(</big>void<em> **r_o</em>, <a class="reference internal" href="#mps_tramp_t" title="mps_tramp_t">mps_tramp_t</a><em> f</em>, void<em> *p</em>, size_t<em> s</em><big>)</big><a class="headerlink" href="#mps_tramp" title="Permalink to this definition">¶</a></dt>
|
|
<dd><p>Call a function via the MPS trampoline.</p>
|
|
<p><tt class="docutils literal"><span class="pre">r_o</span></tt> points to a location that will store the result of calling
|
|
<tt class="docutils literal"><span class="pre">f</span></tt>.</p>
|
|
<p><tt class="docutils literal"><span class="pre">f</span></tt> is the function to call.</p>
|
|
<p><tt class="docutils literal"><span class="pre">p</span></tt> and <tt class="docutils literal"><span class="pre">s</span></tt> are arguments that will be passed to <tt class="docutils literal"><span class="pre">f</span></tt> each
|
|
time it is called. This is intended to make it easy to pass, for
|
|
example, an array and its size as parameters.</p>
|
|
<p>The MPS relies on <a class="reference internal" href="../glossary/b.html#term-barrier-1"><em class="xref std std-term">barriers<sup>(1)</sup></em></a> to protect memory
|
|
that is in an inconsistent state. On some operating systems,
|
|
barrier hits generate exceptions that have to be caught by a
|
|
handler that is on the stack. On these operating systems, any code
|
|
that uses memory managed by the MPS must be called from inside
|
|
such an exception handler, that is, inside a call to
|
|
<a class="reference internal" href="#mps_tramp" title="mps_tramp"><tt class="xref c c-func docutils literal"><span class="pre">mps_tramp()</span></tt></a>.</p>
|
|
<p>If you have multiple threads that run code that uses memory
|
|
managed by the MPS, each thread must execute such code inside a
|
|
call to <a class="reference internal" href="#mps_tramp" title="mps_tramp"><tt class="xref c c-func docutils literal"><span class="pre">mps_tramp()</span></tt></a>.</p>
|
|
</dd></dl>
|
|
|
|
<span class="target" id="index-5"></span><dl class="type">
|
|
<dt id="mps_tramp_t">
|
|
void *<tt class="descname">(*mps_tramp_t)</tt><big>(</big>void<em> *p</em>, size_t<em> s</em><big>)</big><a class="headerlink" href="#mps_tramp_t" title="Permalink to this definition">¶</a></dt>
|
|
<dd><p>The type of a function called by <a class="reference internal" href="#mps_tramp" title="mps_tramp"><tt class="xref c c-func docutils literal"><span class="pre">mps_tramp()</span></tt></a>.</p>
|
|
<p><tt class="docutils literal"><span class="pre">p</span></tt> and <tt class="docutils literal"><span class="pre">s</span></tt> are the corresponding arguments that were passed
|
|
to <a class="reference internal" href="#mps_tramp" title="mps_tramp"><tt class="xref c c-func docutils literal"><span class="pre">mps_tramp()</span></tt></a>.</p>
|
|
</dd></dl>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sphinxsidebar">
|
|
<div class="sphinxsidebarwrapper">
|
|
<p class="logo"><a href="../index.html">
|
|
<img class="logo" src="../_static/logo.png" alt="Logo"/>
|
|
</a></p>
|
|
<h3><a href="../index.html">Table Of Contents</a></h3>
|
|
<ul>
|
|
<li><a class="reference internal" href="#">8. Threads</a><ul>
|
|
<li><a class="reference internal" href="#thread-safety">8.1. Thread safety</a></li>
|
|
<li><a class="reference internal" href="#thread-registration">8.2. Thread registration</a></li>
|
|
<li><a class="reference internal" href="#signal-handling-issues">8.3. Signal handling issues</a></li>
|
|
<li><a class="reference internal" href="#thread-interface">8.4. Thread interface</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
|
|
<h4>Previous topic</h4>
|
|
<p class="topless"><a href="scanning.html"
|
|
title="previous chapter">7. Scanning</a></p>
|
|
<h4>Next topic</h4>
|
|
<p class="topless"><a href="root.html"
|
|
title="next chapter">9. Roots</a></p><h4>Contact us</h4>
|
|
|
|
<p class="topless"><a href="mailto:mps-questions@ravenbrook.com">mps-questions@ravenbrook.com</a></p>
|
|
</div>
|
|
</div>
|
|
<div class="clearer"></div>
|
|
</div>
|
|
<div class="related">
|
|
<h3>Navigation</h3>
|
|
<ul>
|
|
<li class="right" style="margin-right: 10px">
|
|
<a href="../genindex.html" title="General Index"
|
|
>index</a></li>
|
|
<li class="right" >
|
|
<a href="root.html" title="9. Roots"
|
|
>next</a> |</li>
|
|
<li class="right" >
|
|
<a href="scanning.html" title="7. Scanning"
|
|
>previous</a> |</li>
|
|
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> »</li>
|
|
<li><a href="index.html" >Reference</a> »</li>
|
|
</ul>
|
|
</div>
|
|
<div class="footer">
|
|
© <a href="../copyright.html">Copyright</a> 2012, Ravenbrook Limited.
|
|
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
|
|
</div>
|
|
</body>
|
|
</html> |