mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-03-15 03:11:54 -07:00
795 lines
No EOL
62 KiB
HTML
795 lines
No EOL
62 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>5. Allocation buffers and allocation points — 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="Old design" href="old.html" />
|
|
<link rel="next" title="6. Checking" href="check.html" />
|
|
<link rel="prev" title="4. Bit tables" href="bt.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="check.html" title="6. Checking"
|
|
accesskey="N">next</a> |</li>
|
|
<li class="right" >
|
|
<a href="bt.html" title="4. Bit tables"
|
|
accesskey="P">previous</a> |</li>
|
|
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> »</li>
|
|
<li><a href="old.html" accesskey="U">Old design</a> »</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="document">
|
|
<div class="documentwrapper">
|
|
<div class="bodywrapper">
|
|
<div class="body">
|
|
|
|
<span class="target" id="design-buffer"></span><div class="section" id="allocation-buffers-and-allocation-points">
|
|
<span id="index-0"></span><h1>5. Allocation buffers and allocation points<a class="headerlink" href="#allocation-buffers-and-allocation-points" title="Permalink to this headline">¶</a></h1>
|
|
<div class="section" id="introduction">
|
|
<span id="design.mps.buffer"></span><h2>5.1. Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline">¶</a></h2>
|
|
<p><span class="target" id="design.mps.buffer.scope"></span><a class="mpstag reference internal" href="#design.mps.buffer.scope">.scope:</a> This document describes the design of allocation buffers
|
|
and allocation points.</p>
|
|
<p><span class="target" id="design.mps.buffer.purpose"></span><a class="mpstag reference internal" href="#design.mps.buffer.purpose">.purpose:</a> The purpose of this document is to record design
|
|
decisions made concerning allocation buffers and allocation points and
|
|
justify those decisions in terms of requirements.</p>
|
|
<p><span class="target" id="design.mps.buffer.readership"></span><a class="mpstag reference internal" href="#design.mps.buffer.readership">.readership:</a> The document is intended for reading by any MPS
|
|
developer.</p>
|
|
</div>
|
|
<div class="section" id="glossary">
|
|
<h2>5.2. Glossary<a class="headerlink" href="#glossary" title="Permalink to this headline">¶</a></h2>
|
|
<p>trapped</p>
|
|
<blockquote>
|
|
<div><span class="target" id="design.mps.buffer.def.trapped"></span><a class="mpstag reference internal" href="#design.mps.buffer.def.trapped">.def.trapped:</a> The buffer is in a state such that the MPS gets
|
|
to know about the next use of that buffer.</div></blockquote>
|
|
</div>
|
|
<div class="section" id="source">
|
|
<h2>5.3. Source<a class="headerlink" href="#source" title="Permalink to this headline">¶</a></h2>
|
|
<p><span class="target" id="design.mps.buffer.source.mail"></span><a class="mpstag reference internal" href="#design.mps.buffer.source.mail">.source.mail:</a> Much of the juicy stuff about buffers is only
|
|
floating around in mail discussions. You might like to try searching
|
|
the archives if you can’t find what you want here.</p>
|
|
<div class="admonition-note admonition">
|
|
<p class="first admonition-title">Note</p>
|
|
<p class="last">Mail archives are only accessible to Ravenbrook staff. RHSK
|
|
2006-06-09.</p>
|
|
</div>
|
|
<p><span class="target" id="design.mps.buffer.source.synchronize"></span><a class="mpstag reference internal" href="#design.mps.buffer.source.synchronize">.source.synchronize:</a> For a discussion of the synchronization
|
|
issues:</p>
|
|
<ul class="simple">
|
|
<li><a class="reference external" href="/project/mps/mail/1995/05/19/17-10/0.txt">mail.richard.1995-05-19.17-10</a></li>
|
|
<li><a class="reference external" href="/project/mps/mail/1995/05/19/19-15/0.txt">mail.ptw.1995-05-19.19-15</a></li>
|
|
<li><a class="reference external" href="/project/mps/mail/1995/05/24/10-18/0.txt">mail.richard.1995-05-24.10-18</a></li>
|
|
</ul>
|
|
<div class="admonition-note admonition">
|
|
<p class="first admonition-title">Note</p>
|
|
<p class="last">I believe that the sequence for flip in PTW’s message is
|
|
incorrect. The operations should be in the other order. DRJ.</p>
|
|
</div>
|
|
<p><span class="target" id="design.mps.buffer.source.interface"></span><a class="mpstag reference internal" href="#design.mps.buffer.source.interface">.source.interface:</a> For a description of the buffer interface in C
|
|
prototypes:</p>
|
|
<ul class="simple">
|
|
<li><a class="reference external" href="/project/mps/mail/1997/04/28/09-25/0.txt">mail.richard.1997-04-28.09-25(0)</a></li>
|
|
</ul>
|
|
<p><span class="target" id="design.mps.buffer.source.qa"></span><a class="mpstag reference internal" href="#design.mps.buffer.source.qa">.source.qa:</a> Discussions with QA were useful in pinning down the
|
|
semantics and understanding of some obscure but important boundary
|
|
cases. See the thread starting
|
|
<a class="reference external" href="/project/mps/mail/1997/05/12/09-45/0.txt">mail.richard.tucker.1997-05-12.09-45(0)</a> with subject “notes on
|
|
our allocation points discussion”:</p>
|
|
<ul class="simple">
|
|
<li><a class="reference external" href="/project/mps/mail/1997/05/12/09-45/0.txt">mail.richard.tucker.1997-05-12.09-45</a></li>
|
|
<li><a class="reference external" href="/project/mps/mail/1997/05/12/12-46/1.txt">mail.ptw.1997-05-12.12-46(1)</a></li>
|
|
<li><a class="reference external" href="/project/mps/mail/1997/05/12/13-15/0.txt">mail.richard.1997-05-12.13-15</a></li>
|
|
<li><a class="reference external" href="/project/mps/mail/1997/05/12/13-28/0.txt">mail.richard.1997-05-12.13-28</a></li>
|
|
<li><a class="reference external" href="/project/mps/mail/1997/05/13/15-15/0.txt">mail.ptw.1997-05-13.15-15</a></li>
|
|
<li><a class="reference external" href="/project/mps/mail/1997/05/14/11-52/0.txt">mail.sheep.1997-05-14.11-52</a></li>
|
|
<li><a class="reference external" href="/project/mps/mail/1997/05/15/09-19/0.txt">mail.rit.1997-05-15.09-19</a></li>
|
|
<li><a class="reference external" href="/project/mps/mail/1997/05/15/21-22/0.txt">mail.ptw.1997-05-15.21-22</a></li>
|
|
<li><a class="reference external" href="/project/mps/mail/1997/05/15/21-35/0.txt">mail.ptw.1997-05-15.21-35</a></li>
|
|
<li><a class="reference external" href="/project/mps/mail/1997/05/16/08-02/0.txt">mail.rit.1997-05-16.08-02</a></li>
|
|
<li><a class="reference external" href="/project/mps/mail/1997/05/16/08-42/0.txt">mail.rit.1997-05-16.08-42</a></li>
|
|
<li><a class="reference external" href="/project/mps/mail/1997/05/16/12-36/0.txt">mail.ptw.1997-05-16.12-36</a></li>
|
|
<li><a class="reference external" href="/project/mps/mail/1997/05/16/12-47/0.txt">mail.ptw.1997-05-16.12-47</a></li>
|
|
<li><a class="reference external" href="/project/mps/mail/1997/05/19/15-46/0.txt">mail.richard.1997-05-19.15-46</a></li>
|
|
<li><a class="reference external" href="/project/mps/mail/1997/05/19/15-56/0.txt">mail.richard.1997-05-19.15-56</a></li>
|
|
<li><a class="reference external" href="/project/mps/mail/1997/05/20/20-47/0.txt">mail.ptw.1997-05-20.20-47</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="section" id="requirements">
|
|
<h2>5.4. Requirements<a class="headerlink" href="#requirements" title="Permalink to this headline">¶</a></h2>
|
|
<p><span class="target" id="design.mps.buffer.req.fast"></span><a class="mpstag reference internal" href="#design.mps.buffer.req.fast">.req.fast:</a> Allocation must be very fast.</p>
|
|
<p><span class="target" id="design.mps.buffer.req.thread-safe"></span><a class="mpstag reference internal" href="#design.mps.buffer.req.thread-safe">.req.thread-safe:</a> Must run safely in a multi-threaded environment.</p>
|
|
<p><span class="target" id="design.mps.buffer.req.no-synch"></span><a class="mpstag reference internal" href="#design.mps.buffer.req.no-synch">.req.no-synch:</a> Must avoid the use of thread-synchronization.
|
|
(<a class="reference internal" href="#design.mps.buffer.req.fast">.req.fast</a>)</p>
|
|
<p><span class="target" id="design.mps.buffer.req.manual"></span><a class="mpstag reference internal" href="#design.mps.buffer.req.manual">.req.manual:</a> Support manual memory management.</p>
|
|
<p><span class="target" id="design.mps.buffer.req.exact"></span><a class="mpstag reference internal" href="#design.mps.buffer.req.exact">.req.exact:</a> Support exact collectors.</p>
|
|
<p><span class="target" id="design.mps.buffer.req.ambig"></span><a class="mpstag reference internal" href="#design.mps.buffer.req.ambig">.req.ambig:</a> Support ambiguous collectors.</p>
|
|
<p><span class="target" id="design.mps.buffer.req.count"></span><a class="mpstag reference internal" href="#design.mps.buffer.req.count">.req.count:</a> Must record (approximately) the amount of allocation (in bytes).</p>
|
|
<div class="admonition-note admonition">
|
|
<p class="first admonition-title">Note</p>
|
|
<p class="last">Actually not a requirement any more, but once was put forward as a
|
|
Dylan requirement. Bits of the code still reflect this
|
|
requirement. See <a class="reference external" href="https://info.ravenbrook.com/project/mps/import/2001-11-05/mmprevol/request/dylan/170554">request.dylan.170554</a>.</p>
|
|
</div>
|
|
</div>
|
|
<div class="section" id="classes">
|
|
<h2>5.5. Classes<a class="headerlink" href="#classes" title="Permalink to this headline">¶</a></h2>
|
|
<p><span class="target" id="design.mps.buffer.class.hierarchy"></span><a class="mpstag reference internal" href="#design.mps.buffer.class.hierarchy">.class.hierarchy:</a> The <tt class="xref c c-type docutils literal"><span class="pre">Buffer</span></tt> data structure is designed to be
|
|
subclassable (see design.mps.protocol).</p>
|
|
<p><span class="target" id="design.mps.buffer.class.hierarchy.buffer"></span><a class="mpstag reference internal" href="#design.mps.buffer.class.hierarchy.buffer">.class.hierarchy.buffer:</a> The basic buffer class (<tt class="xref c c-type docutils literal"><span class="pre">BufferClass</span></tt>)
|
|
supports basic allocation-point buffering, and is appropriate for
|
|
those manual pools which don’t use segments (<a class="reference internal" href="#design.mps.buffer.req.manual">.req.manual</a>). The
|
|
<tt class="xref c c-type docutils literal"><span class="pre">Buffer</span></tt> class doesn’t support reference ranks (that is, the buffers
|
|
have <tt class="docutils literal"><span class="pre">RankSetEMPTY</span></tt>). Clients may use <tt class="xref c c-type docutils literal"><span class="pre">BufferClass</span></tt> directly, or
|
|
create their own subclasses (see <a class="reference internal" href="#design.mps.buffer.subclassing">.subclassing</a>).</p>
|
|
<p><span class="target" id="design.mps.buffer.class.hierarchy.segbuf"></span><a class="mpstag reference internal" href="#design.mps.buffer.class.hierarchy.segbuf">.class.hierarchy.segbuf:</a> Class <tt class="xref c c-type docutils literal"><span class="pre">SegBufClass</span></tt> is also provided for
|
|
the use of pools which additionally need to associate buffers with
|
|
segments. <tt class="xref c c-type docutils literal"><span class="pre">SegBufClass</span></tt> is a subclass of <tt class="xref c c-type docutils literal"><span class="pre">BufferClass</span></tt>. Manual
|
|
pools may find it convenient to use <tt class="xref c c-type docutils literal"><span class="pre">SegBufClass</span></tt>, but it is
|
|
primarily intended for automatic pools (<a class="reference internal" href="#design.mps.buffer.req.exact">.req.exact</a>, <a class="reference internal" href="#design.mps.buffer.req.ambig">.req.ambig</a>).
|
|
An instance of <tt class="xref c c-type docutils literal"><span class="pre">SegBufClass</span></tt> may be attached to a region of memory
|
|
that lies within a single segment. The segment is associated with the
|
|
buffer, and may be accessed with the <tt class="xref c c-func docutils literal"><span class="pre">BufferSeg()</span></tt> function.
|
|
<tt class="xref c c-type docutils literal"><span class="pre">SegBufClass</span></tt> also supports references at any rank set. Hence this
|
|
class or one of its subclasses should be used by all automatic pools
|
|
(with the possible exception of leaf pools). The rank sets of buffers
|
|
and the segments they are attached to must match. Clients may use
|
|
<tt class="xref c c-type docutils literal"><span class="pre">SegBufClass</span></tt> directly, or create their own subclasses (see
|
|
<a class="reference internal" href="#design.mps.buffer.subclassing">.subclassing</a>).</p>
|
|
<p><span class="target" id="design.mps.buffer.class.hierarchy.rankbuf"></span><a class="mpstag reference internal" href="#design.mps.buffer.class.hierarchy.rankbuf">.class.hierarchy.rankbuf:</a> Class <tt class="xref c c-type docutils literal"><span class="pre">RankBufClass</span></tt> is also provided
|
|
as a subclass of <tt class="xref c c-type docutils literal"><span class="pre">SegBufClass</span></tt>. The only way in which this differs
|
|
from its superclass is that the rankset of a <tt class="xref c c-type docutils literal"><span class="pre">RankBufClass</span></tt> is set
|
|
during initialization to the singleton rank passed as an additional
|
|
parameter to <a class="reference internal" href="#BufferCreate" title="BufferCreate"><tt class="xref c c-func docutils literal"><span class="pre">BufferCreate()</span></tt></a>. Instances of <tt class="xref c c-type docutils literal"><span class="pre">RankBufClass</span></tt> are of
|
|
the same type as instances of <tt class="xref c c-type docutils literal"><span class="pre">SegBufClass</span></tt>, that is, <tt class="docutils literal"><span class="pre">SegBuf</span></tt>.
|
|
Clients may use <tt class="xref c c-type docutils literal"><span class="pre">RankBufClass</span></tt> directly, or create their own
|
|
subclasses (see <a class="reference internal" href="#design.mps.buffer.subclassing">.subclassing</a>).</p>
|
|
<p><span class="target" id="design.mps.buffer.class.create"></span><a class="mpstag reference internal" href="#design.mps.buffer.class.create">.class.create:</a> The buffer creation functions (<a class="reference internal" href="#BufferCreate" title="BufferCreate"><tt class="xref c c-func docutils literal"><span class="pre">BufferCreate()</span></tt></a>
|
|
and <tt class="xref c c-func docutils literal"><span class="pre">BufferCreateV()</span></tt>) take a <tt class="docutils literal"><span class="pre">class</span></tt> parameter, which determines
|
|
the class of buffer to be created.</p>
|
|
<p><span class="target" id="design.mps.buffer.class.choice"></span><a class="mpstag reference internal" href="#design.mps.buffer.class.choice">.class.choice:</a> Pools which support buffered allocation should
|
|
specify a default class for buffers. This class will be used when a
|
|
buffer is created in the normal fashion by MPS clients (for example by
|
|
a call to <a class="reference internal" href="../topic/allocation.html#mps_ap_create" title="mps_ap_create"><tt class="xref c c-func docutils literal"><span class="pre">mps_ap_create()</span></tt></a>). Pools specify the default class by
|
|
means of the <tt class="docutils literal"><span class="pre">bufferClass</span></tt> field in the pool class object. This
|
|
should be a pointer to a function of type <tt class="xref c c-type docutils literal"><span class="pre">PoolBufferClassMethod</span></tt>.
|
|
The normal class “Ensure” function (for example
|
|
<tt class="xref c c-func docutils literal"><span class="pre">EnsureBufferClass()</span></tt>) has the appropriate type.</p>
|
|
<p><span class="target" id="design.mps.buffer.subclassing"></span><a class="mpstag reference internal" href="#design.mps.buffer.subclassing">.subclassing:</a> Pools may create their own subclasses of the standard
|
|
buffer classes. This is sometimes useful if the pool needs to add an
|
|
extra field to the buffer. The convenience macro
|
|
<tt class="xref c c-func docutils literal"><span class="pre">DEFINE_BUFFER_CLASS()</span></tt> may be used to define subclasses of buffer
|
|
classes. See design.mps.protocol.int.define-special.</p>
|
|
<p><span class="target" id="design.mps.buffer.replay"></span><a class="mpstag reference internal" href="#design.mps.buffer.replay">.replay:</a> To work with the allocation replayer (see
|
|
design.mps.telemetry.replayer), the buffer class has to emit an event
|
|
for each call to an external interface, containing all the parameters
|
|
passed by the user. If a new event type is required to carry this
|
|
information, the replayer (impl.c.eventrep) must then be extended to
|
|
recreate the call.</p>
|
|
<p><span class="target" id="design.mps.buffer.replay.pool-buffer"></span><a class="mpstag reference internal" href="#design.mps.buffer.replay.pool-buffer">.replay.pool-buffer:</a> The replayer must also be updated if the
|
|
association of buffer class to pool or the buffer class hierarchy is
|
|
changed.</p>
|
|
<p><span class="target" id="design.mps.buffer.class.method"></span><a class="mpstag reference internal" href="#design.mps.buffer.class.method">.class.method:</a> Buffer classes provide the following methods (these
|
|
should not be confused with the pool class methods related to the
|
|
buffer protocol, described in <a class="reference internal" href="#design.mps.buffer.method">.method</a>):</p>
|
|
<dl class="type">
|
|
<dt id="BufferInitMethod">
|
|
<a class="reference internal" href="type.html#Res" title="Res">Res</a> <tt class="descname">(*BufferInitMethod)</tt><big>(</big>Buffer<em> buffer</em>, Pool<em> pool</em>, ArgList<em> args</em><big>)</big><a class="headerlink" href="#BufferInitMethod" title="Permalink to this definition">¶</a></dt>
|
|
<dd></dd></dl>
|
|
|
|
<p><span class="target" id="design.mps.buffer.class.method.init"></span><a class="mpstag reference internal" href="#design.mps.buffer.class.method.init">.class.method.init:</a> <tt class="xref c c-func docutils literal"><span class="pre">init()</span></tt> is a class-specific initialization
|
|
method called from <tt class="xref c c-func docutils literal"><span class="pre">BufferInit()</span></tt>. It receives the keyword arguments
|
|
passed to to <tt class="xref c c-func docutils literal"><span class="pre">BufferInit()</span></tt>. Client-defined methods must call their
|
|
superclass method (via a next-method call) before performing any
|
|
class-specific behaviour. <span class="target" id="design.mps.buffer.replay.init"></span><a class="mpstag reference internal" href="#design.mps.buffer.replay.init">.replay.init:</a> The <tt class="xref c c-func docutils literal"><span class="pre">init()</span></tt> method
|
|
should emit a <tt class="docutils literal"><span class="pre">BufferInit<foo></span></tt> event (if there aren’t any extra
|
|
parameters, <tt class="docutils literal"><span class="pre"><foo></span> <span class="pre">=</span> <span class="pre">""</span></tt>).</p>
|
|
<dl class="type">
|
|
<dt id="BufferFinishMethod">
|
|
void <tt class="descname">(*BufferFinishMethod)</tt><big>(</big>Buffer<em> buffer</em><big>)</big><a class="headerlink" href="#BufferFinishMethod" title="Permalink to this definition">¶</a></dt>
|
|
<dd></dd></dl>
|
|
|
|
<p><span class="target" id="design.mps.buffer.class.method.finish"></span><a class="mpstag reference internal" href="#design.mps.buffer.class.method.finish">.class.method.finish:</a> <tt class="xref c c-func docutils literal"><span class="pre">finish()</span></tt> is a class-specific finish
|
|
method called from <tt class="xref c c-func docutils literal"><span class="pre">BufferFinish()</span></tt>. Client-defined methods must
|
|
call their superclass method (via a next-method call) after performing
|
|
any class-specific behaviour.</p>
|
|
<dl class="type">
|
|
<dt id="BufferAttachMethod">
|
|
void <tt class="descname">(*BufferAttachMethod)</tt><big>(</big>Buffer<em> buffer</em>, <a class="reference internal" href="type.html#Addr" title="Addr">Addr</a><em> base</em>, <a class="reference internal" href="type.html#Addr" title="Addr">Addr</a><em> limit</em>, <a class="reference internal" href="type.html#Addr" title="Addr">Addr</a><em> init</em>, <a class="reference internal" href="type.html#Size" title="Size">Size</a><em> size</em><big>)</big><a class="headerlink" href="#BufferAttachMethod" title="Permalink to this definition">¶</a></dt>
|
|
<dd></dd></dl>
|
|
|
|
<p><span class="target" id="design.mps.buffer.class.method.attach"></span><a class="mpstag reference internal" href="#design.mps.buffer.class.method.attach">.class.method.attach:</a> <tt class="xref c c-func docutils literal"><span class="pre">attach()</span></tt> is a class-specific method
|
|
called whenever a buffer is attached to memory, via
|
|
<a class="reference internal" href="#BufferAttach" title="BufferAttach"><tt class="xref c c-func docutils literal"><span class="pre">BufferAttach()</span></tt></a>. Client-defined methods must call their superclass
|
|
method (via a next-method call) before performing any class-specific
|
|
behaviour.</p>
|
|
<dl class="type">
|
|
<dt id="BufferDetachMethod">
|
|
void <tt class="descname">(*BufferDetachMethod)</tt><big>(</big>Buffer<em> buffer</em><big>)</big><a class="headerlink" href="#BufferDetachMethod" title="Permalink to this definition">¶</a></dt>
|
|
<dd></dd></dl>
|
|
|
|
<p><span class="target" id="design.mps.buffer.class.method.detach"></span><a class="mpstag reference internal" href="#design.mps.buffer.class.method.detach">.class.method.detach:</a> <tt class="xref c c-func docutils literal"><span class="pre">detach()</span></tt> is a class-specific method
|
|
called whenever a buffer is detached from memory, via
|
|
<a class="reference internal" href="#BufferDetach" title="BufferDetach"><tt class="xref c c-func docutils literal"><span class="pre">BufferDetach()</span></tt></a>. Client-defined methods must call their superclass
|
|
method (via a next-method call) after performing any class-specific
|
|
behaviour.</p>
|
|
<dl class="type">
|
|
<dt id="BufferSegMethod">
|
|
<a class="reference internal" href="seg.html#Seg" title="Seg">Seg</a> <tt class="descname">(*BufferSegMethod)</tt><big>(</big>Buffer<em> buffer</em><big>)</big><a class="headerlink" href="#BufferSegMethod" title="Permalink to this definition">¶</a></dt>
|
|
<dd></dd></dl>
|
|
|
|
<p><span class="target" id="design.mps.buffer.class.method.seg"></span><a class="mpstag reference internal" href="#design.mps.buffer.class.method.seg">.class.method.seg:</a> <tt class="xref c c-func docutils literal"><span class="pre">seg()</span></tt> is a class-specific accessor method
|
|
which returns the segment attached to a buffer (or <tt class="xref c c-macro docutils literal"><span class="pre">NULL</span></tt> if there
|
|
isn’t one). It is called from <tt class="xref c c-func docutils literal"><span class="pre">BufferSeg()</span></tt>. Clients should not need
|
|
to define their own methods for this.</p>
|
|
<dl class="type">
|
|
<dt id="BufferRankSetMethod">
|
|
RankSet <tt class="descname">(*BufferRankSetMethod)</tt><big>(</big>Buffer<em> buffer</em><big>)</big><a class="headerlink" href="#BufferRankSetMethod" title="Permalink to this definition">¶</a></dt>
|
|
<dd></dd></dl>
|
|
|
|
<p><span class="target" id="design.mps.buffer.class.method.rankSet"></span><a class="mpstag reference internal" href="#design.mps.buffer.class.method.rankSet">.class.method.rankSet:</a> <tt class="xref c c-func docutils literal"><span class="pre">rankSet()</span></tt> is a class-specific accessor
|
|
method which returns the rank set of a buffer. It is called from
|
|
<tt class="xref c c-func docutils literal"><span class="pre">BufferRankSet()</span></tt>. Clients should not need to define their own
|
|
methods for this.</p>
|
|
<dl class="type">
|
|
<dt id="BufferSetRankSetMethod">
|
|
void <tt class="descname">(*BufferSetRankSetMethod)</tt><big>(</big>Buffer<em> buffer</em>, RankSet<em> rankSet</em><big>)</big><a class="headerlink" href="#BufferSetRankSetMethod" title="Permalink to this definition">¶</a></dt>
|
|
<dd></dd></dl>
|
|
|
|
<p><span class="target" id="design.mps.buffer.class.method.setRankSet"></span><a class="mpstag reference internal" href="#design.mps.buffer.class.method.setRankSet">.class.method.setRankSet:</a> <tt class="xref c c-func docutils literal"><span class="pre">setRankSet()</span></tt> is a class-specific
|
|
setter method which sets the rank set of a buffer. It is called from
|
|
<tt class="xref c c-func docutils literal"><span class="pre">BufferSetRankSet()</span></tt>. Clients should not need to define their own
|
|
methods for this.</p>
|
|
<dl class="type">
|
|
<dt id="BufferDescribeMethod">
|
|
<a class="reference internal" href="type.html#Res" title="Res">Res</a> <tt class="descname">(*BufferDescribeMethod)</tt><big>(</big>Buffer<em> buffer</em>, <a class="reference internal" href="../topic/plinth.html#mps_lib_FILE" title="mps_lib_FILE">mps_lib_FILE</a><em> *stream</em><big>)</big><a class="headerlink" href="#BufferDescribeMethod" title="Permalink to this definition">¶</a></dt>
|
|
<dd></dd></dl>
|
|
|
|
<p><span class="target" id="design.mps.buffer.class.method.describe"></span><a class="mpstag reference internal" href="#design.mps.buffer.class.method.describe">.class.method.describe:</a> <tt class="xref c c-func docutils literal"><span class="pre">describe()</span></tt> is a class-specific method
|
|
called to describe a buffer, via BufferDescribe. Client-defined
|
|
methods must call their superclass method (via a next-method call)
|
|
before describing any class-specific state.</p>
|
|
</div>
|
|
<div class="section" id="logging">
|
|
<h2>5.6. Logging<a class="headerlink" href="#logging" title="Permalink to this headline">¶</a></h2>
|
|
<p><span class="target" id="design.mps.buffer.logging.control"></span><a class="mpstag reference internal" href="#design.mps.buffer.logging.control">.logging.control:</a> Buffers have a separate control for whether they
|
|
are logged or not, this is because they are particularly high volume.
|
|
This is a Boolean flag (<tt class="docutils literal"><span class="pre">bufferLogging</span></tt>) in the <tt class="xref c c-type docutils literal"><span class="pre">ArenaStruct</span></tt>.</p>
|
|
</div>
|
|
<div class="section" id="measurement">
|
|
<h2>5.7. Measurement<a class="headerlink" href="#measurement" title="Permalink to this headline">¶</a></h2>
|
|
<p><span class="target" id="design.mps.buffer.count"></span><a class="mpstag reference internal" href="#design.mps.buffer.count">.count:</a> Counting the allocation volume is done by maintaining two
|
|
fields in the buffer struct:</p>
|
|
<p><span class="target" id="design.mps.buffer.count.fields"></span><a class="mpstag reference internal" href="#design.mps.buffer.count.fields">.count.fields:</a> <tt class="docutils literal"><span class="pre">fillSize</span></tt>, <tt class="docutils literal"><span class="pre">emptySize</span></tt>.</p>
|
|
<p><span class="target" id="design.mps.buffer.count.monotonic"></span><a class="mpstag reference internal" href="#design.mps.buffer.count.monotonic">.count.monotonic:</a> both of these fields are monotonically
|
|
increasing.</p>
|
|
<p><span class="target" id="design.mps.buffer.count.fillsize"></span><a class="mpstag reference internal" href="#design.mps.buffer.count.fillsize">.count.fillsize:</a> <tt class="docutils literal"><span class="pre">fillSize</span></tt> is an accumulated total of the size
|
|
of all the fills (as a result of calling the <tt class="xref c c-type docutils literal"><span class="pre">PoolClass</span></tt>
|
|
<a class="reference internal" href="#BufferFill" title="BufferFill"><tt class="xref c c-func docutils literal"><span class="pre">BufferFill()</span></tt></a> method) that happen on the buffer.</p>
|
|
<p><span class="target" id="design.mps.buffer.count.emptysize"></span><a class="mpstag reference internal" href="#design.mps.buffer.count.emptysize">.count.emptysize:</a> <tt class="docutils literal"><span class="pre">emptySize</span></tt> is an accumulated total of the size of
|
|
all the empties than happen on the buffer (which are notified to the
|
|
pool using the <tt class="xref c c-type docutils literal"><span class="pre">PoolClass</span></tt> <tt class="xref c c-func docutils literal"><span class="pre">BufferEmpty()</span></tt> method).</p>
|
|
<p><span class="target" id="design.mps.buffer.count.generic"></span><a class="mpstag reference internal" href="#design.mps.buffer.count.generic">.count.generic:</a> These fields are maintained by the generic buffer
|
|
code in <a class="reference internal" href="#BufferAttach" title="BufferAttach"><tt class="xref c c-func docutils literal"><span class="pre">BufferAttach()</span></tt></a> and <a class="reference internal" href="#BufferDetach" title="BufferDetach"><tt class="xref c c-func docutils literal"><span class="pre">BufferDetach()</span></tt></a>.</p>
|
|
<p><span class="target" id="design.mps.buffer.count.other"></span><a class="mpstag reference internal" href="#design.mps.buffer.count.other">.count.other:</a> Similar count fields are maintained in the pool and
|
|
the arena. They are maintained on an internal (buffers used internally
|
|
by the MPS) and external (buffers used for mutator allocation points)
|
|
basis. The fields are also updated by the buffer code. The fields are:</p>
|
|
<ul class="simple">
|
|
<li>in the pool: <tt class="docutils literal"><span class="pre">fillMutatorSize</span></tt>, <tt class="docutils literal"><span class="pre">fillInternalSize</span></tt>,
|
|
<tt class="docutils literal"><span class="pre">emptyMutatorSize</span></tt>, and <tt class="docutils literal"><span class="pre">emptyInternalSize</span></tt> (4 fields);</li>
|
|
<li>in the arena, <tt class="docutils literal"><span class="pre">fillMutatorSize</span></tt>, <tt class="docutils literal"><span class="pre">fillInternalSize</span></tt>,
|
|
<tt class="docutils literal"><span class="pre">emptyMutatorSize</span></tt>, <tt class="docutils literal"><span class="pre">emptyInternalSize</span></tt>, and
|
|
<tt class="docutils literal"><span class="pre">allocMutatorSize</span></tt> (5 fields).</li>
|
|
</ul>
|
|
<p><span class="target" id="design.mps.buffer.count.alloc.how"></span><a class="mpstag reference internal" href="#design.mps.buffer.count.alloc.how">.count.alloc.how:</a> The amount of allocation in the buffer just
|
|
after an empty is <tt class="docutils literal"><span class="pre">fillSize</span> <span class="pre">-</span> <span class="pre">emptySize</span></tt>. At other times this
|
|
computation will include space that the buffer has the use of (between
|
|
base and init) but which may not get allocated in (because the
|
|
remaining space may be too large for the next reserve so some or all
|
|
of it may get emptied). The arena field <tt class="docutils literal"><span class="pre">allocMutatorSize</span></tt> is
|
|
incremented by the allocated size (between base and init)
|
|
whenever a buffer is detached. Symmetrically this field is decremented
|
|
by by the pre-allocated size (between base and init) whenever
|
|
a buffer is attached. The overall count is asymptotically correct.</p>
|
|
<p><span class="target" id="design.mps.buffer.count.type"></span><a class="mpstag reference internal" href="#design.mps.buffer.count.type">.count.type:</a> All the count fields are type double.</p>
|
|
<p><span class="target" id="design.mps.buffer.count.type.justify"></span><a class="mpstag reference internal" href="#design.mps.buffer.count.type.justify">.count.type.justify:</a> This is because double is the type most likely
|
|
to give us enough precision. Because of the lack of genuine
|
|
requirements the type isn’t so important. It’s nice to have it more
|
|
precise than long. Which double usually is.</p>
|
|
</div>
|
|
<div class="section" id="notes-from-the-whiteboard">
|
|
<h2>5.8. Notes from the whiteboard<a class="headerlink" href="#notes-from-the-whiteboard" title="Permalink to this headline">¶</a></h2>
|
|
<p>Requirements</p>
|
|
<ul class="simple">
|
|
<li>atomic update of words</li>
|
|
<li>guarantee order of reads and write to certain memory locations.</li>
|
|
</ul>
|
|
<p>Flip</p>
|
|
<ul class="simple">
|
|
<li>limit:=0</li>
|
|
<li>record init for scanner</li>
|
|
</ul>
|
|
<p>Commit</p>
|
|
<ul class="simple">
|
|
<li>init:=alloc</li>
|
|
<li>if(limit = 0) ...</li>
|
|
<li>L written only by MM</li>
|
|
<li>A written only by client (except during synchronized MM op)</li>
|
|
<li>I ditto</li>
|
|
<li>I read by MM during flip</li>
|
|
</ul>
|
|
<p>States</p>
|
|
<ul class="simple">
|
|
<li>busy</li>
|
|
<li>ready</li>
|
|
<li>trapped</li>
|
|
<li>reset</li>
|
|
</ul>
|
|
<div class="admonition-note admonition">
|
|
<p class="first admonition-title">Note</p>
|
|
<p class="last">There are many more states. DRJ.</p>
|
|
</div>
|
|
<p>Misc</p>
|
|
<ul class="simple">
|
|
<li>During buffer ops all field values can change. Might trash perfectly
|
|
good (“valid”?) object if pool isn’t careful.</li>
|
|
</ul>
|
|
</div>
|
|
<div class="section" id="synchronization">
|
|
<h2>5.9. Synchronization<a class="headerlink" href="#synchronization" title="Permalink to this headline">¶</a></h2>
|
|
<p>Buffers provide a loose form of synchronization between the mutator
|
|
and the collector.</p>
|
|
<p>The crucial synchronization issues are between the operation the pool
|
|
performs on flip and the mutator’s commit operation.</p>
|
|
<p>Commit</p>
|
|
<ul class="simple">
|
|
<li>read init</li>
|
|
<li>write init</li>
|
|
<li>Memory Barrier</li>
|
|
<li>read <tt class="docutils literal"><span class="pre">limit</span></tt></li>
|
|
</ul>
|
|
<p>Flip</p>
|
|
<ul class="simple">
|
|
<li>write <tt class="docutils literal"><span class="pre">limit</span></tt></li>
|
|
<li>Memory Barrier</li>
|
|
<li>read init</li>
|
|
</ul>
|
|
<p>Commit consists of two parts. The first is the update to init.
|
|
This is a declaration that the new object just before init is now
|
|
correctly formatted and can be scanned. The second is a check to see
|
|
if the buffer has been “tripped”. The ordering of the two parts is
|
|
crucial.</p>
|
|
<p>Note that the declaration that the object is correctly formatted is
|
|
independent of whether the buffer has been tripped or not. In
|
|
particular a pool can scan up to the init pointer (including the newly
|
|
declared object) whether or not the pool will cause the commit to
|
|
fail. In the case where the pool scans the object, but then causes the
|
|
commit to fail (and presumably the allocation to occur somewhere
|
|
else), the pool will have scanned a “dead” object, but this is just
|
|
another example of conservatism in the general sense.</p>
|
|
<p>Not that the read of init in the Flip sequence can in fact be
|
|
arbitrarily delayed (as long as it is read before a buffered segment
|
|
is scanned).</p>
|
|
<p>On processors with Relaxed Memory Order (such as the DEC Alpha),
|
|
Memory Barriers will need to be placed at the points indicated.</p>
|
|
<div class="highlight-c"><pre>* DESIGN
|
|
*
|
|
* design.mps.buffer.
|
|
*
|
|
* An allocation buffer is an interface to a pool which provides
|
|
* very fast allocation, and defers the need for synchronization in
|
|
* a multi-threaded environment.
|
|
*
|
|
* Pools which contain formatted objects must be synchronized so
|
|
* that the pool can know when an object is valid. Allocation from
|
|
* such pools is done in two stages: reserve and commit. The client
|
|
* first reserves memory, then initializes it, then commits.
|
|
* Committing the memory declares that it contains a valid formatted
|
|
* object. Under certain conditions, some pools may cause the
|
|
* commit operation to fail. (See the documentation for the pool.)
|
|
* Failure to commit indicates that the whole allocation failed and
|
|
* must be restarted. When using a pool which introduces the
|
|
* possibility of commit failing, the allocation sequence could look
|
|
* something like this:
|
|
*
|
|
* do {
|
|
* res = BufferReserve(&p, buffer, size);
|
|
* if(res != ResOK) return res; // allocation fails, reason res
|
|
* initialize(p); // p now points at valid object
|
|
* } while(!BufferCommit(buffer, p, size));
|
|
*
|
|
* Pools which do not contain formatted objects can use a one-step
|
|
* allocation as usual. Effectively any random rubbish counts as a
|
|
* "valid object" to such pools.
|
|
*
|
|
* An allocation buffer is an area of memory which is pre-allocated
|
|
* from a pool, plus a buffer descriptor, which contains, inter
|
|
* alia, four pointers: base, init, alloc, and limit. Base points
|
|
* to the base address of the area, limit to the last address plus
|
|
* one. Init points to the first uninitialized address in the
|
|
* buffer, and alloc points to the first unallocated address.
|
|
*
|
|
* L . - - - - - . ^
|
|
* | | Higher addresses -'
|
|
* | junk |
|
|
* | | the "busy" state, after Reserve
|
|
* A |-----------|
|
|
* | uninit |
|
|
* I |-----------|
|
|
* | init |
|
|
* | | Lower addresses -.
|
|
* B `-----------' v
|
|
*
|
|
* L . - - - - - . ^
|
|
* | | Higher addresses -'
|
|
* | junk |
|
|
* | | the "ready" state, after Commit
|
|
* A=I |-----------|
|
|
* | |
|
|
* | |
|
|
* | init |
|
|
* | | Lower addresses -.
|
|
* B `-----------' v
|
|
*
|
|
* Access to these pointers is restricted in order to allow
|
|
* synchronization between the pool and the client. The client may
|
|
* only write to init and alloc, but in a restricted and atomic way
|
|
* detailed below. The pool may read the contents of the buffer
|
|
* descriptor at _any_ time. During calls to the fill and trip
|
|
* methods, the pool may update any or all of the fields
|
|
* in the buffer descriptor. The pool may update the limit at _any_
|
|
* time.
|
|
*
|
|
* Access to buffers by these methods is not synchronized. If a buffer
|
|
* is to be used by more than one thread then it is the client's
|
|
* responsibility to ensure exclusive access. It is recommended that
|
|
* a buffer be used by only a single thread.
|
|
*
|
|
* [Only one thread may use a buffer at once, unless the client
|
|
* places a mutual exclusion around the buffer access in the usual
|
|
* way. In such cases it is usually better to create one buffer for
|
|
* each thread.]
|
|
*
|
|
* Here are pseudo-code descriptions of the reserve and commit
|
|
* operations. These may be implemented in-line by the client.
|
|
* Note that the client is responsible for ensuring that the size
|
|
* (and therefore the alloc and init pointers) are aligned according
|
|
* to the buffer's alignment.
|
|
*
|
|
* Reserve(buf, size) ; size must be aligned to pool
|
|
* if buf->limit - buf->alloc >= size then
|
|
* buf->alloc +=size ; must be atomic update
|
|
* p = buf->init
|
|
* else
|
|
* res = BufferFill(&p, buf, size) ; buf contents may change
|
|
*
|
|
* Commit(buf, p, size)
|
|
* buf->init = buf->alloc ; must be atomic update
|
|
* if buf->limit == 0 then
|
|
* res = BufferTrip(buf, p, size) ; buf contents may change
|
|
* else
|
|
* res = True
|
|
* (returns True on successful commit)
|
|
*
|
|
* The pool must allocate the buffer descriptor and initialize it by
|
|
* calling BufferInit. The descriptor this creates will fall
|
|
* through to the fill method on the first allocation. In general,
|
|
* pools should not assign resources to the buffer until the first
|
|
* allocation, since the buffer may never be used.
|
|
*
|
|
* The pool may update the base, init, alloc, and limit fields when
|
|
* the fallback methods are called. In addition, the pool may set
|
|
* the limit to zero at any time. The effect of this is either:
|
|
*
|
|
* 1. cause the _next_ allocation in the buffer to fall through to
|
|
* the buffer fill method, and allow the buffer to be flushed
|
|
* and relocated;
|
|
*
|
|
* 2. cause the buffer trip method to be called if the client was
|
|
* between reserve and commit.
|
|
*
|
|
* A buffer may not be relocated under other circumstances because
|
|
* there is a race between updating the descriptor and the client
|
|
* allocation sequence.</pre>
|
|
</div>
|
|
</div>
|
|
<div class="section" id="interface">
|
|
<h2>5.10. Interface<a class="headerlink" href="#interface" title="Permalink to this headline">¶</a></h2>
|
|
<dl class="function">
|
|
<dt id="BufferCreate">
|
|
<a class="reference internal" href="type.html#Res" title="Res">Res</a> <tt class="descname">BufferCreate</tt><big>(</big>Buffer<em> *bufferReturn</em>, BufferClass<em> class</em>, Pool<em> pool</em>, <a class="reference internal" href="type.html#Bool" title="Bool">Bool</a><em> isMutator</em>, ArgList<em> args</em><big>)</big><a class="headerlink" href="#BufferCreate" title="Permalink to this definition">¶</a></dt>
|
|
<dd></dd></dl>
|
|
|
|
<p><span class="target" id="design.mps.buffer.method.create"></span><a class="mpstag reference internal" href="#design.mps.buffer.method.create">.method.create:</a> Create an allocation buffer in a pool. The buffer
|
|
is created in the “ready” state.</p>
|
|
<p>A buffer structure is allocated from the space control pool and
|
|
partially initialized (in particularly neither the signature nor the
|
|
serial field are initialized). The pool class’s <tt class="xref c c-func docutils literal"><span class="pre">bufferCreate()</span></tt>
|
|
method is then called. This method can update (some undefined subset
|
|
of) the fields of the structure; it should return with the buffer in
|
|
the “ready” state (or fail). The remainder of the initialization then
|
|
occurs.</p>
|
|
<p>If and only if successful then a valid buffer is returned.</p>
|
|
<dl class="function">
|
|
<dt id="BufferDestroy">
|
|
void <tt class="descname">BufferDestroy</tt><big>(</big>Buffer<em> buffer</em><big>)</big><a class="headerlink" href="#BufferDestroy" title="Permalink to this definition">¶</a></dt>
|
|
<dd></dd></dl>
|
|
|
|
<p><span class="target" id="design.mps.buffer.method.destroy"></span><a class="mpstag reference internal" href="#design.mps.buffer.method.destroy">.method.destroy:</a> Free a buffer descriptor. The buffer must be in
|
|
the “ready” state, that is, not between a Reserve and Commit.
|
|
Allocation in the area of memory to which the descriptor refers must
|
|
cease after <a class="reference internal" href="#BufferDestroy" title="BufferDestroy"><tt class="xref c c-func docutils literal"><span class="pre">BufferDestroy()</span></tt></a> is called.</p>
|
|
<p>Destroying an allocation buffer does not affect objects which have
|
|
been allocated, it just frees resources associated with the buffer
|
|
itself.</p>
|
|
<p>The pool class’s <tt class="xref c c-func docutils literal"><span class="pre">bufferDestroy()</span></tt> method is called and then the
|
|
buffer structure is uninitialized and freed.</p>
|
|
<dl class="function">
|
|
<dt id="BufferCheck">
|
|
<tt class="descname">BufferCheck</tt><big>(</big>Buffer<em> buffer</em><big>)</big><a class="headerlink" href="#BufferCheck" title="Permalink to this definition">¶</a></dt>
|
|
<dd></dd></dl>
|
|
|
|
<p><span class="target" id="design.mps.buffer.method.check"></span><a class="mpstag reference internal" href="#design.mps.buffer.method.check">.method.check:</a> The check method is straightforward, the non-trivial dependencies checked are:</p>
|
|
<ul class="simple">
|
|
<li>The ordering constraints between base, init, alloc, and limit.</li>
|
|
<li>The alignment constraints on base, init, alloc, and limit.</li>
|
|
<li>That the buffer’s rank is identical to the segment’s rank.</li>
|
|
</ul>
|
|
<dl class="function">
|
|
<dt id="BufferAttach">
|
|
void <tt class="descname">BufferAttach</tt><big>(</big>Buffer<em> buffer</em>, <a class="reference internal" href="type.html#Addr" title="Addr">Addr</a><em> base</em>, <a class="reference internal" href="type.html#Addr" title="Addr">Addr</a><em> limit</em>, <a class="reference internal" href="type.html#Addr" title="Addr">Addr</a><em> init</em>, <a class="reference internal" href="type.html#Size" title="Size">Size</a><em> size</em><big>)</big><a class="headerlink" href="#BufferAttach" title="Permalink to this definition">¶</a></dt>
|
|
<dd></dd></dl>
|
|
|
|
<p><span class="target" id="design.mps.buffer.method.attach"></span><a class="mpstag reference internal" href="#design.mps.buffer.method.attach">.method.attach:</a> Set the base, init, alloc, and limit fields so that
|
|
the buffer is ready to start allocating in area of memory. The alloc
|
|
field is set to <tt class="docutils literal"><span class="pre">init</span> <span class="pre">+</span> <span class="pre">size</span></tt>.</p>
|
|
<p><span class="target" id="design.mps.buffer.method.attach.unbusy"></span><a class="mpstag reference internal" href="#design.mps.buffer.method.attach.unbusy">.method.attach.unbusy:</a> <a class="reference internal" href="#BufferAttach" title="BufferAttach"><tt class="xref c c-func docutils literal"><span class="pre">BufferAttach()</span></tt></a> must only be applied to
|
|
buffers that are not busy.</p>
|
|
<dl class="function">
|
|
<dt id="BufferDetach">
|
|
void <tt class="descname">BufferDetach</tt><big>(</big>Buffer<em> buffer</em>, Pool<em> pool</em><big>)</big><a class="headerlink" href="#BufferDetach" title="Permalink to this definition">¶</a></dt>
|
|
<dd></dd></dl>
|
|
|
|
<p><span class="target" id="design.mps.buffer.method.detach"></span><a class="mpstag reference internal" href="#design.mps.buffer.method.detach">.method.detach:</a> Set the seg, base, init, alloc, and limit fields to
|
|
zero, so that the next reserve request will call the fill method.</p>
|
|
<p><span class="target" id="design.mps.buffer.method.detach.unbusy"></span><a class="mpstag reference internal" href="#design.mps.buffer.method.detach.unbusy">.method.detach.unbusy:</a> <a class="reference internal" href="#BufferDetach" title="BufferDetach"><tt class="xref c c-func docutils literal"><span class="pre">BufferDetach()</span></tt></a> must only be applied to
|
|
buffers that are not busy.</p>
|
|
<dl class="function">
|
|
<dt id="BufferIsReset">
|
|
<a class="reference internal" href="type.html#Bool" title="Bool">Bool</a> <tt class="descname">BufferIsReset</tt><big>(</big>Buffer<em> buffer</em><big>)</big><a class="headerlink" href="#BufferIsReset" title="Permalink to this definition">¶</a></dt>
|
|
<dd></dd></dl>
|
|
|
|
<p><span class="target" id="design.mps.buffer.method.isreset"></span><a class="mpstag reference internal" href="#design.mps.buffer.method.isreset">.method.isreset:</a> Returns <tt class="xref c c-macro docutils literal"><span class="pre">TRUE</span></tt> if and only if the buffer is in the
|
|
reset state, that is, with base, init, alloc, and limit all set to
|
|
zero.</p>
|
|
<dl class="function">
|
|
<dt id="BufferIsReady">
|
|
<a class="reference internal" href="type.html#Bool" title="Bool">Bool</a> <tt class="descname">BufferIsReady</tt><big>(</big>Buffer<em> buffer</em><big>)</big><a class="headerlink" href="#BufferIsReady" title="Permalink to this definition">¶</a></dt>
|
|
<dd></dd></dl>
|
|
|
|
<p><span class="target" id="design.mps.buffer.method.isready"></span><a class="mpstag reference internal" href="#design.mps.buffer.method.isready">.method.isready:</a> Returns <tt class="xref c c-macro docutils literal"><span class="pre">TRUE</span></tt> if and only if the buffer is not
|
|
between a reserve and commit. The result is only reliable if the
|
|
client is not currently using the buffer, since it may update the
|
|
alloc and init pointers asynchronously.</p>
|
|
<dl class="function">
|
|
<dt id="(BufferAP)">
|
|
<a class="reference internal" href="../topic/allocation.html#mps_ap_t" title="mps_ap_t">mps_ap_t</a> <tt class="descname">(BufferAP)</tt><big>(</big>Buffer<em> buffer</em><big>)</big><a class="headerlink" href="#(BufferAP)" title="Permalink to this definition">¶</a></dt>
|
|
<dd></dd></dl>
|
|
|
|
<p>Returns the <tt class="xref c c-type docutils literal"><span class="pre">APStruct</span></tt> substructure of a buffer.</p>
|
|
<dl class="function">
|
|
<dt id="BufferOfAP">
|
|
Buffer <tt class="descname">BufferOfAP</tt><big>(</big><a class="reference internal" href="../topic/allocation.html#mps_ap_t" title="mps_ap_t">mps_ap_t</a><em> ap</em><big>)</big><a class="headerlink" href="#BufferOfAP" title="Permalink to this definition">¶</a></dt>
|
|
<dd></dd></dl>
|
|
|
|
<p><span class="target" id="design.mps.buffer.method.ofap"></span><a class="mpstag reference internal" href="#design.mps.buffer.method.ofap">.method.ofap:</a> Return the buffer which owns an <tt class="xref c c-type docutils literal"><span class="pre">APStruct</span></tt>.</p>
|
|
<p><span class="target" id="design.mps.buffer.method.ofap.thread-safe"></span><a class="mpstag reference internal" href="#design.mps.buffer.method.ofap.thread-safe">.method.ofap.thread-safe:</a> <a class="reference internal" href="#BufferOfAP" title="BufferOfAP"><tt class="xref c c-func docutils literal"><span class="pre">BufferOfAP()</span></tt></a> must be thread safe (see
|
|
impl.c.mpsi.thread-safety). This is achieved simply because the
|
|
underlying operation involved is simply a subtraction.</p>
|
|
<dl class="function">
|
|
<dt id="BufferArena">
|
|
<a class="reference internal" href="arena.html#Arena" title="Arena">Arena</a> <tt class="descname">BufferArena</tt><big>(</big>Buffer<em> buffer</em><big>)</big><a class="headerlink" href="#BufferArena" title="Permalink to this definition">¶</a></dt>
|
|
<dd></dd></dl>
|
|
|
|
<p><span class="target" id="design.mps.buffer.method.arena"></span><a class="mpstag reference internal" href="#design.mps.buffer.method.arena">.method.arena:</a> Returns the arena which owns a buffer.</p>
|
|
<p><span class="target" id="design.mps.buffer.method.arena.thread-safe"></span><a class="mpstag reference internal" href="#design.mps.buffer.method.arena.thread-safe">.method.arena.thread-safe:</a> <a class="reference internal" href="#BufferArena" title="BufferArena"><tt class="xref c c-func docutils literal"><span class="pre">BufferArena()</span></tt></a> must be thread safe
|
|
(see impl.c.mpsi.thread-safety). This is achieved simple because the
|
|
underlying operation is a read of shared-non-mutable data (see
|
|
design.mps.thread-safety).</p>
|
|
<dl class="function">
|
|
<dt id="BufferPool">
|
|
Pool <tt class="descname">BufferPool</tt><big>(</big>Buffer<em> buffer</em><big>)</big><a class="headerlink" href="#BufferPool" title="Permalink to this definition">¶</a></dt>
|
|
<dd></dd></dl>
|
|
|
|
<p>Returns the pool to which a buffer is attached.</p>
|
|
<dl class="function">
|
|
<dt id="BufferReserve">
|
|
<a class="reference internal" href="type.html#Res" title="Res">Res</a> <tt class="descname">BufferReserve</tt><big>(</big><a class="reference internal" href="type.html#Addr" title="Addr">Addr</a><em> *pReturn</em>, Buffer<em> buffer</em>, <a class="reference internal" href="type.html#Size" title="Size">Size</a><em> size</em>, <a class="reference internal" href="type.html#Bool" title="Bool">Bool</a><em> withReservoirPermit</em><big>)</big><a class="headerlink" href="#BufferReserve" title="Permalink to this definition">¶</a></dt>
|
|
<dd></dd></dl>
|
|
|
|
<p><span class="target" id="design.mps.buffer.method.reserve"></span><a class="mpstag reference internal" href="#design.mps.buffer.method.reserve">.method.reserve:</a> Reserves memory from an allocation buffer.</p>
|
|
<p>This is a provided version of the reserve procedure described above.
|
|
The size must be aligned according to the buffer alignment. If
|
|
successful, <tt class="docutils literal"><span class="pre">ResOK</span></tt> is returned and <tt class="docutils literal"><span class="pre">*pReturn</span></tt> is updated with a
|
|
pointer to the reserved memory. Otherwise <tt class="docutils literal"><span class="pre">*pReturn</span></tt> is not touched.
|
|
The reserved memory is not guaranteed to have any particular contents.
|
|
The memory must be initialized with a valid object (according to the
|
|
pool to which the buffer belongs) and then passed to the
|
|
<a class="reference internal" href="#BufferCommit" title="BufferCommit"><tt class="xref c c-func docutils literal"><span class="pre">BufferCommit()</span></tt></a> method (see below). <tt class="docutils literal"><span class="pre">BufferReserve(0</span></tt> may not be
|
|
applied twice to a buffer without a <a class="reference internal" href="#BufferCommit" title="BufferCommit"><tt class="xref c c-func docutils literal"><span class="pre">BufferCommit()</span></tt></a> in-between. In
|
|
other words, Reserve/Commit pairs do not nest.</p>
|
|
<dl class="function">
|
|
<dt id="BufferFill">
|
|
<a class="reference internal" href="type.html#Res" title="Res">Res</a> <tt class="descname">BufferFill</tt><big>(</big><a class="reference internal" href="type.html#Addr" title="Addr">Addr</a><em> *pReturn</em>, Buffer<em> buffer</em>, <a class="reference internal" href="type.html#Size" title="Size">Size</a><em> size</em>, <a class="reference internal" href="type.html#Bool" title="Bool">Bool</a><em> withReservoirPermit</em><big>)</big><a class="headerlink" href="#BufferFill" title="Permalink to this definition">¶</a></dt>
|
|
<dd></dd></dl>
|
|
|
|
<p><span class="target" id="design.mps.buffer.method.fill"></span><a class="mpstag reference internal" href="#design.mps.buffer.method.fill">.method.fill:</a> Refills an empty buffer. If there is not enough space
|
|
in a buffer to allocate in-line, <a class="reference internal" href="#BufferFill" title="BufferFill"><tt class="xref c c-func docutils literal"><span class="pre">BufferFill()</span></tt></a> must be called to
|
|
“refill” the buffer.</p>
|
|
<dl class="function">
|
|
<dt id="BufferCommit">
|
|
<a class="reference internal" href="type.html#Bool" title="Bool">Bool</a> <tt class="descname">BufferCommit</tt><big>(</big>Buffer<em> buffer</em>, <a class="reference internal" href="type.html#Addr" title="Addr">Addr</a><em> p</em>, <a class="reference internal" href="type.html#Size" title="Size">Size</a><em> size</em><big>)</big><a class="headerlink" href="#BufferCommit" title="Permalink to this definition">¶</a></dt>
|
|
<dd></dd></dl>
|
|
|
|
<p><span class="target" id="design.mps.buffer.method.commit"></span><a class="mpstag reference internal" href="#design.mps.buffer.method.commit">.method.commit:</a> Commit memory previously reserved.</p>
|
|
<p><a class="reference internal" href="#BufferCommit" title="BufferCommit"><tt class="xref c c-func docutils literal"><span class="pre">BufferCommit()</span></tt></a> notifies the pool that memory which has been
|
|
previously reserved (see above) has been initialized with a valid
|
|
object (according to the pool to which the buffer belongs). The
|
|
pointer <tt class="docutils literal"><span class="pre">p</span></tt> must be the same as that returned by
|
|
<a class="reference internal" href="#BufferReserve" title="BufferReserve"><tt class="xref c c-func docutils literal"><span class="pre">BufferReserve()</span></tt></a>, and the size must match the size passed to
|
|
<a class="reference internal" href="#BufferReserve" title="BufferReserve"><tt class="xref c c-func docutils literal"><span class="pre">BufferReserve()</span></tt></a>.</p>
|
|
<p><a class="reference internal" href="#BufferCommit" title="BufferCommit"><tt class="xref c c-func docutils literal"><span class="pre">BufferCommit()</span></tt></a> may not be applied twice to a buffer without a
|
|
reserve in between. In other words, objects must be reserved,
|
|
initialized, then committed only once.</p>
|
|
<p>Commit returns <tt class="xref c c-macro docutils literal"><span class="pre">TRUE</span></tt> if successful, <tt class="xref c c-macro docutils literal"><span class="pre">FALSE</span></tt> otherwise. If commit
|
|
fails and returns <tt class="xref c c-macro docutils literal"><span class="pre">FALSE</span></tt>, the client may try to allocate again by
|
|
going back to the reserve stage, and may not use the memory at <tt class="docutils literal"><span class="pre">p</span></tt>
|
|
again for any purpose.</p>
|
|
<p>Some classes of pool may cause commit to fail under rare
|
|
circumstances.</p>
|
|
<dl class="function">
|
|
<dt id="BufferTrip">
|
|
<tt class="descname">BufferTrip</tt><big>(</big>Buffer<em> buffer</em>, <a class="reference internal" href="type.html#Addr" title="Addr">Addr</a><em> p</em>, <a class="reference internal" href="type.html#Size" title="Size">Size</a><em> size</em><big>)</big><a class="headerlink" href="#BufferTrip" title="Permalink to this definition">¶</a></dt>
|
|
<dd></dd></dl>
|
|
|
|
<p><span class="target" id="design.mps.buffer.method.trip"></span><a class="mpstag reference internal" href="#design.mps.buffer.method.trip">.method.trip:</a> Act on a tripped buffer. The pool which owns a buffer
|
|
may asynchronously set the buffer limit to zero in order to get
|
|
control over the buffer. If this occurs after a <a class="reference internal" href="#BufferReserve" title="BufferReserve"><tt class="xref c c-func docutils literal"><span class="pre">BufferReserve()</span></tt></a>
|
|
(but before the corresponding commit), then the <a class="reference internal" href="#BufferCommit" title="BufferCommit"><tt class="xref c c-func docutils literal"><span class="pre">BufferCommit()</span></tt></a>
|
|
method calls <a class="reference internal" href="#BufferTrip" title="BufferTrip"><tt class="xref c c-func docutils literal"><span class="pre">BufferTrip()</span></tt></a> and the <a class="reference internal" href="#BufferCommit" title="BufferCommit"><tt class="xref c c-func docutils literal"><span class="pre">BufferCommit()</span></tt></a> method
|
|
returns with the return value of <a class="reference internal" href="#BufferTrip" title="BufferTrip"><tt class="xref c c-func docutils literal"><span class="pre">BufferTrip()</span></tt></a>.</p>
|
|
<p><span class="target" id="design.mps.buffer.method.trip.precondition"></span><a class="mpstag reference internal" href="#design.mps.buffer.method.trip.precondition">.method.trip.precondition:</a> At the time trip is called, from
|
|
<a class="reference internal" href="#BufferCommit" title="BufferCommit"><tt class="xref c c-func docutils literal"><span class="pre">BufferCommit()</span></tt></a>, the following are true:</p>
|
|
<ul class="simple">
|
|
<li><span class="target" id="design.mps.buffer.method.trip.precondition.limit"></span><a class="mpstag reference internal" href="#design.mps.buffer.method.trip.precondition.limit">.method.trip.precondition.limit:</a> <tt class="docutils literal"><span class="pre">limit</span> <span class="pre">==</span> <span class="pre">0</span></tt></li>
|
|
<li><span class="target" id="design.mps.buffer.method.trip.precondition.init"></span><a class="mpstag reference internal" href="#design.mps.buffer.method.trip.precondition.init">.method.trip.precondition.init:</a> <tt class="docutils literal"><span class="pre">init</span> <span class="pre">==</span> <span class="pre">alloc</span></tt></li>
|
|
<li><span class="target" id="design.mps.buffer.method.trip.precondition.p"></span><a class="mpstag reference internal" href="#design.mps.buffer.method.trip.precondition.p">.method.trip.precondition.p:</a> <tt class="docutils literal"><span class="pre">p</span> <span class="pre">+</span> <span class="pre">size</span> <span class="pre">==</span> <span class="pre">alloc</span></tt></li>
|
|
</ul>
|
|
</div>
|
|
<div class="section" id="diagrams">
|
|
<h2>5.11. Diagrams<a class="headerlink" href="#diagrams" title="Permalink to this headline">¶</a></h2>
|
|
<p>Here are a number of diagrams showing how buffers behave. In general,
|
|
the horizontal axis corresponds to mutator action (reserve, commit)
|
|
and the vertical axis corresponds to collector action. I’m not sure
|
|
which of the diagrams are the same as each other, and which are best
|
|
or most complete when they are different, but they all attempt to show
|
|
essentially the same information. It’s very difficult to get all the
|
|
details in. These diagrams were drawn by Richard Brooksby, Richard
|
|
Tucker, Gavin Matthews, and others in April 1997. In general, the
|
|
later diagrams are, I suspect, more correct, complete and useful than
|
|
the earlier ones. I have put them all here for the record. Richard
|
|
Tucker, 1998-02-09.</p>
|
|
<p>Buffer Diagram:
|
|
Buffer States</p>
|
|
<p>Buffer States (3-column)
|
|
Buffer States (4-column)
|
|
Buffer States (gavinised)
|
|
Buffer States (interleaved)
|
|
Buffer States (richardized)</p>
|
|
<p>[missing diagrams]</p>
|
|
</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="#">5. Allocation buffers and allocation points</a><ul>
|
|
<li><a class="reference internal" href="#introduction">5.1. Introduction</a></li>
|
|
<li><a class="reference internal" href="#glossary">5.2. Glossary</a></li>
|
|
<li><a class="reference internal" href="#source">5.3. Source</a></li>
|
|
<li><a class="reference internal" href="#requirements">5.4. Requirements</a></li>
|
|
<li><a class="reference internal" href="#classes">5.5. Classes</a></li>
|
|
<li><a class="reference internal" href="#logging">5.6. Logging</a></li>
|
|
<li><a class="reference internal" href="#measurement">5.7. Measurement</a></li>
|
|
<li><a class="reference internal" href="#notes-from-the-whiteboard">5.8. Notes from the whiteboard</a></li>
|
|
<li><a class="reference internal" href="#synchronization">5.9. Synchronization</a></li>
|
|
<li><a class="reference internal" href="#interface">5.10. Interface</a></li>
|
|
<li><a class="reference internal" href="#diagrams">5.11. Diagrams</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
|
|
<h4>Previous topic</h4>
|
|
<p class="topless"><a href="bt.html"
|
|
title="previous chapter">4. Bit tables</a></p>
|
|
<h4>Next topic</h4>
|
|
<p class="topless"><a href="check.html"
|
|
title="next chapter">6. Checking</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="check.html" title="6. Checking"
|
|
>next</a> |</li>
|
|
<li class="right" >
|
|
<a href="bt.html" title="4. Bit tables"
|
|
>previous</a> |</li>
|
|
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> »</li>
|
|
<li><a href="old.html" >Old 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> |