mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-13 06:50:39 -08:00
315 lines
No EOL
18 KiB
HTML
315 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>14. The lock module — 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="Design" href="index.html" />
|
|
<link rel="next" title="15. Debugging features for client objects" href="object-debug.html" />
|
|
<link rel="prev" title="9. The generic fix function" href="fix.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="object-debug.html" title="15. Debugging features for client objects"
|
|
accesskey="N">next</a> |</li>
|
|
<li class="right" >
|
|
<a href="fix.html" title="9. The generic fix function"
|
|
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">Design</a> »</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="document">
|
|
<div class="documentwrapper">
|
|
<div class="bodywrapper">
|
|
<div class="body">
|
|
|
|
<div class="section" id="the-lock-module">
|
|
<span id="design.mps.lock"></span><h1>14. The lock module<a class="headerlink" href="#the-lock-module" title="Permalink to this headline">¶</a></h1>
|
|
<div class="section" id="history">
|
|
<h2>14.1. History<a class="headerlink" href="#history" title="Permalink to this headline">¶</a></h2>
|
|
<p><span class="target" id="design.mps.lock.hist.0"></span><a class="mpstag reference internal" href="#design.mps.lock.hist.0">.hist.0:</a> Incomplete design. David Moore, 1995-11-21.</p>
|
|
<p><span class="target" id="design.mps.lock.hist.1"></span><a class="mpstag reference internal" href="#design.mps.lock.hist.1">.hist.1:</a> Converted from MMInfo database design document.
|
|
Richard Brooksby, 2002-06-07.</p>
|
|
<p><span class="target" id="design.mps.lock.hist.2"></span><a class="mpstag reference internal" href="#design.mps.lock.hist.2">.hist.2:</a> Converted to reStructuredText. Gareth Rees,
|
|
2013-04-14.</p>
|
|
</div>
|
|
<div class="section" id="purpose">
|
|
<h2>14.2. Purpose<a class="headerlink" href="#purpose" title="Permalink to this headline">¶</a></h2>
|
|
<p><span class="target" id="design.mps.lock.purpose"></span><a class="mpstag reference internal" href="#design.mps.lock.purpose">.purpose:</a> Support the locking needs of the thread-safe
|
|
design. In particular:</p>
|
|
<ul class="simple">
|
|
<li>recursive locks;</li>
|
|
<li>binary locks;</li>
|
|
<li>recursive “global” lock that need not be allocated or initialized by
|
|
the client;</li>
|
|
<li>binary “global” lock that need not be allocated or initialized by
|
|
the client.</li>
|
|
</ul>
|
|
<p><span class="target" id="design.mps.lock.context"></span><a class="mpstag reference internal" href="#design.mps.lock.context">.context:</a> The MPS has to be able to operate in a
|
|
multi-threaded environment. The thread-safe design
|
|
(design.mps.thread-safety) requires client-allocatable
|
|
binary locks, a global binary lock and a global recursive lock. An
|
|
interface to client-allocatable recursive locks is also present to
|
|
support any potential use, because of historic requirements, and
|
|
because the implementation will presumably be necessary anyway for the
|
|
global recursive lock.</p>
|
|
</div>
|
|
<div class="section" id="background">
|
|
<h2>14.3. Background<a class="headerlink" href="#background" title="Permalink to this headline">¶</a></h2>
|
|
<p><span class="target" id="design.mps.lock.need"></span><a class="mpstag reference internal" href="#design.mps.lock.need">.need:</a> In an environment where multiple threads are accessing
|
|
shared data. The threads which access data which is shared with other
|
|
threads need to cooperate with those threads to maintain consistency.
|
|
Locks provide a simple mechanism for doing this.</p>
|
|
<p><span class="target" id="design.mps.lock.ownership"></span><a class="mpstag reference internal" href="#design.mps.lock.ownership">.ownership:</a> A lock is an object which may be “owned” by a
|
|
single thread at a time. By claiming ownership of a lock before
|
|
executing some piece of code a thread can guarantee that no other
|
|
thread owns the lock during execution of that code. If some other
|
|
thread holds a claim on a lock, the thread trying to claim the lock
|
|
will suspend until the lock is released by the owning thread.</p>
|
|
<p><span class="target" id="design.mps.lock.data"></span><a class="mpstag reference internal" href="#design.mps.lock.data">.data:</a> A simple way of using this behaviour is to associate a
|
|
lock with a shared data structure. By claiming that lock around
|
|
accesses to the data, a consistent view of the structure can be seen
|
|
by the accessing thread. More generally any set of operations which
|
|
are required to be mutually exclusive may be performed so by using
|
|
locks.</p>
|
|
</div>
|
|
<div class="section" id="overview">
|
|
<h2>14.4. Overview<a class="headerlink" href="#overview" title="Permalink to this headline">¶</a></h2>
|
|
<p><span class="target" id="design.mps.lock.adt"></span><a class="mpstag reference internal" href="#design.mps.lock.adt">.adt:</a> There is an abstract datatype <tt class="xref c c-type docutils literal"><span class="pre">Lock</span></tt> which
|
|
points to a locking structure <tt class="xref c c-type docutils literal"><span class="pre">LockStruct</span></tt>. This structure is
|
|
opaque to any client, although an interface is provided to supply the
|
|
size of the structure for any client wishing to make a new lock. The
|
|
lock is not allocated by the module as allocation itself may require
|
|
locking. <tt class="xref c c-type docutils literal"><span class="pre">LockStruct</span></tt> is implementation specific.</p>
|
|
<p><span class="target" id="design.mps.lock.simple-lock"></span><a class="mpstag reference internal" href="#design.mps.lock.simple-lock">.simple-lock:</a> There are facilities for claiming and releasing
|
|
locks. <tt class="xref c c-type docutils literal"><span class="pre">Lock</span></tt> is used for both binary and recursive locking.</p>
|
|
<p><span class="target" id="design.mps.lock.global-locks"></span><a class="mpstag reference internal" href="#design.mps.lock.global-locks">.global-locks:</a> “Global” locks are so called because they are
|
|
used to protect data in a global location (such as a global variable).
|
|
The lock module provides two global locks; one recursive and one binary.
|
|
There are facilities for claiming and releasing both of these locks.
|
|
These global locks have the advantage that they need not be allocated
|
|
or atomically initialized by the client, so they may be used for
|
|
locking the initialization of the allocator itself. The binary global
|
|
lock is intended to protect mutable data, possibly in conjunction with
|
|
other local locking strategies. The recursive global lock is intended
|
|
to protect static read-only data during one-off initialization. See
|
|
design.mps.thread-safety.</p>
|
|
<p><span class="target" id="design.mps.lock.deadlock"></span><a class="mpstag reference internal" href="#design.mps.lock.deadlock">.deadlock:</a> This module does not provide any deadlock
|
|
protection. Clients are responsible for avoiding deadlock by using
|
|
traditional strategies such as ordering of locks. (See
|
|
design.mps.thread-safety.deadlock.)</p>
|
|
<p><span class="target" id="design.mps.lock.single-thread"></span><a class="mpstag reference internal" href="#design.mps.lock.single-thread">.single-thread:</a> In the single-threaded configuration, locks
|
|
are not needed and the claim/release interfaces defined to be no-ops.</p>
|
|
</div>
|
|
<div class="section" id="detailed-design">
|
|
<h2>14.5. Detailed design<a class="headerlink" href="#detailed-design" title="Permalink to this headline">¶</a></h2>
|
|
<p><span class="target" id="design.mps.lock.interface"></span><a class="mpstag reference internal" href="#design.mps.lock.interface">.interface:</a> The interface comprises the following functions:</p>
|
|
<dl class="function">
|
|
<dt id="LockSize">
|
|
size_t <tt class="descname">LockSize</tt><big>(</big>void<big>)</big><a class="headerlink" href="#LockSize" title="Permalink to this definition">¶</a></dt>
|
|
<dd></dd></dl>
|
|
|
|
<p>Return the size of a <tt class="xref c c-type docutils literal"><span class="pre">LockStruct</span></tt> for allocation purposes.</p>
|
|
<dl class="function">
|
|
<dt id="LockInit">
|
|
void <tt class="descname">LockInit</tt><big>(</big>Lock<em> lock</em><big>)</big><a class="headerlink" href="#LockInit" title="Permalink to this definition">¶</a></dt>
|
|
<dd></dd></dl>
|
|
|
|
<p>After initialisation the lock is not owned by any thread.</p>
|
|
<dl class="function">
|
|
<dt id="LockFinish">
|
|
void <tt class="descname">LockFinish</tt><big>(</big>Lock<em> lock</em><big>)</big><a class="headerlink" href="#LockFinish" title="Permalink to this definition">¶</a></dt>
|
|
<dd></dd></dl>
|
|
|
|
<p>Before finalisation the lock must not beowned by any thread.</p>
|
|
<dl class="function">
|
|
<dt id="LockClaim">
|
|
void <tt class="descname">LockClaim</tt><big>(</big>Lock<em> lock</em><big>)</big><a class="headerlink" href="#LockClaim" title="Permalink to this definition">¶</a></dt>
|
|
<dd></dd></dl>
|
|
|
|
<p>Claims ownership of a lock that was previously not held by current
|
|
thread.</p>
|
|
<dl class="function">
|
|
<dt id="LockReleaseMPM">
|
|
void <tt class="descname">LockReleaseMPM</tt><big>(</big>Lock<em> lock</em><big>)</big><a class="headerlink" href="#LockReleaseMPM" title="Permalink to this definition">¶</a></dt>
|
|
<dd></dd></dl>
|
|
|
|
<p>Releases ownership of a lock that is currently owned.</p>
|
|
<dl class="function">
|
|
<dt id="LockClaimRecursive">
|
|
void <tt class="descname">LockClaimRecursive</tt><big>(</big>Lock<em> lock</em><big>)</big><a class="headerlink" href="#LockClaimRecursive" title="Permalink to this definition">¶</a></dt>
|
|
<dd></dd></dl>
|
|
|
|
<p>Remembers the previous state of the lock with respect to the current
|
|
thread and claims the lock (if not already held).</p>
|
|
<dl class="function">
|
|
<dt id="LockReleaseRecursive">
|
|
void <tt class="descname">LockReleaseRecursive</tt><big>(</big>Lock<em> lock</em><big>)</big><a class="headerlink" href="#LockReleaseRecursive" title="Permalink to this definition">¶</a></dt>
|
|
<dd></dd></dl>
|
|
|
|
<p>Testores the previous state of the lock stored by corresponding
|
|
<a class="reference internal" href="#LockClaimRecursive" title="LockClaimRecursive"><tt class="xref c c-func docutils literal"><span class="pre">LockClaimRecursive()</span></tt></a> call.</p>
|
|
<dl class="function">
|
|
<dt id="LockClaimGlobal">
|
|
void <tt class="descname">LockClaimGlobal</tt><big>(</big>void<big>)</big><a class="headerlink" href="#LockClaimGlobal" title="Permalink to this definition">¶</a></dt>
|
|
<dd></dd></dl>
|
|
|
|
<p>Claims ownership of the binary global lock which was previously not
|
|
held by current thread.</p>
|
|
<dl class="function">
|
|
<dt id="LockReleaseGlobal">
|
|
void <tt class="descname">LockReleaseGlobal</tt><big>(</big>void<big>)</big><a class="headerlink" href="#LockReleaseGlobal" title="Permalink to this definition">¶</a></dt>
|
|
<dd></dd></dl>
|
|
|
|
<p>Releases ownership of the binary global lock that is currently owned.</p>
|
|
<dl class="function">
|
|
<dt id="LockClaimGlobalRecursive">
|
|
void <tt class="descname">LockClaimGlobalRecursive</tt><big>(</big>void<big>)</big><a class="headerlink" href="#LockClaimGlobalRecursive" title="Permalink to this definition">¶</a></dt>
|
|
<dd></dd></dl>
|
|
|
|
<p>Remembers the previous state of the recursive global lock with respect
|
|
to the current thread and claims the lock (if not already held).</p>
|
|
<dl class="function">
|
|
<dt id="LockReleaseGlobalRecursive">
|
|
void <tt class="descname">LockReleaseGlobalRecursive</tt><big>(</big>void<big>)</big><a class="headerlink" href="#LockReleaseGlobalRecursive" title="Permalink to this definition">¶</a></dt>
|
|
<dd></dd></dl>
|
|
|
|
<p>Restores the previous state of the recursive global lock stored by
|
|
corresponding <a class="reference internal" href="#LockClaimGlobalRecursive" title="LockClaimGlobalRecursive"><tt class="xref c c-func docutils literal"><span class="pre">LockClaimGlobalRecursive()</span></tt></a> call.</p>
|
|
<p><span class="target" id="design.mps.lock.impl.recursive"></span><a class="mpstag reference internal" href="#design.mps.lock.impl.recursive">.impl.recursive:</a> For recursive claims, the list of previous
|
|
states can be simply implemented by keeping a count of the number of
|
|
claims made by the current thread so far. In multi-threaded
|
|
implementation below this is handled by the operating system. A count
|
|
is still kept and used to check correctness.</p>
|
|
<p><span class="target" id="design.mps.lock.impl.global"></span><a class="mpstag reference internal" href="#design.mps.lock.impl.global">.impl.global:</a> The binary and recursive global locks may
|
|
actually be implemented using the same mechanism as normal locks.</p>
|
|
<p><span class="target" id="design.mps.lock.impl.ansi"></span><a class="mpstag reference internal" href="#design.mps.lock.impl.ansi">.impl.ansi:</a> Single-Threaded Generic Implementation:</p>
|
|
<ul class="simple">
|
|
<li>single-thread;</li>
|
|
<li>no need for locking;</li>
|
|
<li>locking structure contains count;</li>
|
|
<li>provides checking in debug version;</li>
|
|
<li>otherwise does nothing except keep count of claims.</li>
|
|
</ul>
|
|
<p><span class="target" id="design.mps.lock.impl.win32"></span><a class="mpstag reference internal" href="#design.mps.lock.impl.win32">.impl.win32:</a> Win32 Implementation:</p>
|
|
<ul class="simple">
|
|
<li>supports Win32’s threads;</li>
|
|
<li>uses Critical Sections [ref?];</li>
|
|
<li>locking structure contains a Critical Section;</li>
|
|
<li>both recursive and non-recursive calls use same Windows function;</li>
|
|
<li>also performs checking.</li>
|
|
</ul>
|
|
<p><span class="target" id="design.mps.lock.impl.linux"></span><a class="mpstag reference internal" href="#design.mps.lock.impl.linux">.impl.linux:</a> LinuxThreads Implementation (possibly suitable
|
|
for all PThreads implementations):</p>
|
|
<ul class="simple">
|
|
<li>supports LinuxThreads threads, which are an implementation of
|
|
PThreads (see <a class="reference external" href="http://pauillac.inria.fr/~xleroy/linuxthreads/">http://pauillac.inria.fr/~xleroy/linuxthreads/</a>);</li>
|
|
<li>locking structure contains a mutex, initialized to check for
|
|
recursive locking;</li>
|
|
<li>locking structure contains a count of the number of active claims;</li>
|
|
<li>non-recursive locking calls pthread_mutex_lock and expects success;</li>
|
|
<li>recursive locking calls pthread_mutex_lock and expects either
|
|
success or EDEADLK (indicating a recursive claim);</li>
|
|
<li>also performs checking.</li>
|
|
</ul>
|
|
</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="#">14. The lock module</a><ul>
|
|
<li><a class="reference internal" href="#history">14.1. History</a></li>
|
|
<li><a class="reference internal" href="#purpose">14.2. Purpose</a></li>
|
|
<li><a class="reference internal" href="#background">14.3. Background</a></li>
|
|
<li><a class="reference internal" href="#overview">14.4. Overview</a></li>
|
|
<li><a class="reference internal" href="#detailed-design">14.5. Detailed design</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
|
|
<h4>Previous topic</h4>
|
|
<p class="topless"><a href="fix.html"
|
|
title="previous chapter">9. The generic fix function</a></p>
|
|
<h4>Next topic</h4>
|
|
<p class="topless"><a href="object-debug.html"
|
|
title="next chapter">15. Debugging features for client objects</a></p><h4>Downloads</h4>
|
|
|
|
<p class="topless">
|
|
<a href="http://www.ravenbrook.com/project/mps/release/1.111.0/">MPS Kit release 1.111.0</a><br>
|
|
<a href="http://www.ravenbrook.com/project/mps/release/">All MPS Kit releases</a>
|
|
</p>
|
|
|
|
<h4>Issues</h4>
|
|
|
|
<p class="topless">
|
|
<a href="http://www.ravenbrook.com/project/mps/issue/?action=list&view=status%3dopen&display=Job:Priority:Title&sort=Priority">Known issues</a><br>
|
|
<a href="http://www.ravenbrook.com/project/mps/issue/?action=fixed&release_fixed=1.111.0">Issues fixed in release 1.111.0</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="object-debug.html" title="15. Debugging features for client objects"
|
|
>next</a> |</li>
|
|
<li class="right" >
|
|
<a href="fix.html" title="9. The generic fix function"
|
|
>previous</a> |</li>
|
|
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> »</li>
|
|
<li><a href="index.html" >Design</a> »</li>
|
|
</ul>
|
|
</div>
|
|
<div class="footer">
|
|
© <a href="../copyright.html">Copyright</a> 2013, Ravenbrook Limited.
|
|
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
|
|
</div>
|
|
</body>
|
|
</html> |