1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-13 06:50:39 -08:00
emacs/mps/manual/html/design/lock.html
Gareth Rees c5f77afc19 Bring html up to date for the mps manual.
Copied from Perforce
 Change: 181433
 ServerID: perforce.ravenbrook.com
2013-04-24 12:21:37 +01:00

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 &mdash; 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> &raquo;</li>
<li><a href="index.html" accesskey="U">Design</a> &raquo;</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 &#8220;global&#8221; lock that need not be allocated or initialized by
the client;</li>
<li>binary &#8220;global&#8221; 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 &#8220;owned&#8221; 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> &#8220;Global&#8221; 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>&nbsp;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>&nbsp;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>&nbsp;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>&nbsp;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>&nbsp;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>&nbsp;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&#8217;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&amp;view=status%3dopen&amp;display=Job:Priority:Title&amp;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> &raquo;</li>
<li><a href="index.html" >Design</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; <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>