mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-13 23:10:26 -08:00
844 lines
No EOL
90 KiB
HTML
844 lines
No EOL
90 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>2. Bit tables — 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="3. Coalescing block structure" href="cbs.html" />
|
||
<link rel="prev" title="1. Arena" href="arena.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="cbs.html" title="3. Coalescing block structure"
|
||
accesskey="N">next</a> |</li>
|
||
<li class="right" >
|
||
<a href="arena.html" title="1. Arena"
|
||
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="bit-tables">
|
||
<span id="design.mps.bt"></span><h1>2. Bit tables<a class="headerlink" href="#bit-tables" title="Permalink to this headline">¶</a></h1>
|
||
<div class="section" id="introduction">
|
||
<h2>2.1. Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline">¶</a></h2>
|
||
<p><span class="target" id="design.mps.bt.readership"></span><a class="mpstag reference internal" href="#design.mps.bt.readership">.readership:</a> Any MPS developer.</p>
|
||
<p><span class="target" id="design.mps.bt.intro"></span><a class="mpstag reference internal" href="#design.mps.bt.intro">.intro:</a> This is the design of the Bit Tables module. A Bit
|
||
Table is a linear array of bits. A Bit Table of length <em>n</em> is indexed
|
||
using an integer from 0 up to (but not including) <em>n</em>. Each bit in a
|
||
Bit Table can hold either the value 0 (aka <tt class="docutils literal"><span class="pre">FALSE</span></tt>) or 1 (aka
|
||
<tt class="docutils literal"><span class="pre">TRUE</span></tt>). A variety of operations are provided including: set, reset,
|
||
and retrieve, individual bits; set and reset a contiguous range of
|
||
bits; search for a contiguous range of reset bits; making a “negative
|
||
image” copy of a range.</p>
|
||
</div>
|
||
<div class="section" id="history">
|
||
<h2>2.2. History<a class="headerlink" href="#history" title="Permalink to this headline">¶</a></h2>
|
||
<p><span class="target" id="design.mps.bt.hist.0-3"></span><a class="mpstag reference internal" href="#design.mps.bt.hist.0-3">.hist.0-3:</a> The history for versions 0-3 is lost pending
|
||
possible reconstruction. David Jones, 1997-03-04.</p>
|
||
<p><span class="target" id="design.mps.bt.hist.4"></span><a class="mpstag reference internal" href="#design.mps.bt.hist.4">.hist.4:</a> Prepared for review. Added full requirements
|
||
section. Made notation more consistent throughout. Documented all
|
||
functions. David Jones, 1999-04-29.</p>
|
||
<p><span class="target" id="design.mps.bt.hist.5"></span><a class="mpstag reference internal" href="#design.mps.bt.hist.5">.hist.5:</a> Converted from MMInfo database design document.
|
||
Richard Brooksby, 2002-06-07.</p>
|
||
<p><span class="target" id="design.mps.bt.hist.6"></span><a class="mpstag reference internal" href="#design.mps.bt.hist.6">.hist.6:</a> Converted to reStructuredText. Gareth Rees,
|
||
2013-03-12.</p>
|
||
</div>
|
||
<div class="section" id="definitions">
|
||
<h2>2.3. Definitions<a class="headerlink" href="#definitions" title="Permalink to this headline">¶</a></h2>
|
||
<p><span class="target" id="design.mps.bt.def.set"></span><a class="mpstag reference internal" href="#design.mps.bt.def.set">.def.set:</a> <strong>Set</strong></p>
|
||
<blockquote>
|
||
<div>Used as a verb meaning to assign the value 1 or <tt class="docutils literal"><span class="pre">TRUE</span></tt> to a bit.
|
||
Used descriptively to denote a bit containing the value 1. Note 1
|
||
and <tt class="docutils literal"><span class="pre">TRUE</span></tt> are synonyms in MPS C code (see
|
||
design.mps.type(0).bool.value).</div></blockquote>
|
||
<p><span class="target" id="design.mps.bt.def.reset"></span><a class="mpstag reference internal" href="#design.mps.bt.def.reset">.def.reset:</a> <strong>Reset</strong></p>
|
||
<blockquote>
|
||
<div>Used as a verb meaning to assign the value 0 or <tt class="docutils literal"><span class="pre">FALSE</span></tt> to a
|
||
bit. Used descriptively to denote a bit containing the value 0.
|
||
Note 0 and <tt class="docutils literal"><span class="pre">FALSE</span></tt> are synonyms in MPS C code (see
|
||
design.mps.type(0).bool.value).</div></blockquote>
|
||
<div class="admonition-note admonition">
|
||
<p class="first admonition-title">Note</p>
|
||
<p class="last">Consider using “fill/empty” or “mark/clear” instead of
|
||
“set/reset”, set/reset is probably a hangover from drj’s z80
|
||
hacking days – drj 1999-04-26</p>
|
||
</div>
|
||
<p><span class="target" id="design.mps.bt.def.bt"></span><a class="mpstag reference internal" href="#design.mps.bt.def.bt">.def.bt:</a> <strong>Bit Table</strong></p>
|
||
<blockquote>
|
||
<div><p>A Bit Table is a mapping from [0, <em>n</em>) to {0,1} for some <em>n</em>,
|
||
represented as a linear array of bits.</p>
|
||
<p><span class="target" id="design.mps.bt..def.bt.justify"></span><a class="mpstag reference internal" href="#design.mps.bt..def.bt.justify">..def.bt.justify:</a> They are called <em>bit tables</em> because a
|
||
single bit is used to encode whether the image of a particular
|
||
integer under the map is 0 or 1.</p>
|
||
</div></blockquote>
|
||
<p><span class="target" id="design.mps.bt.def.range"></span><a class="mpstag reference internal" href="#design.mps.bt.def.range">.def.range:</a> <strong>Range</strong></p>
|
||
<blockquote>
|
||
<div>A contiguous sequence of bits in a Bit Table. Ranges are typically
|
||
specified as a <em>base</em>–<em>limit</em> pair where the range includes the
|
||
position specified by the base, but excludes that specified by the
|
||
limit. The mathematical interval notation for half-open intervals,
|
||
[<em>base</em>, <em>limit</em>), is used.</div></blockquote>
|
||
</div>
|
||
<div class="section" id="requirements">
|
||
<h2>2.4. Requirements<a class="headerlink" href="#requirements" title="Permalink to this headline">¶</a></h2>
|
||
<p><span class="target" id="design.mps.bt.req.bit"></span><a class="mpstag reference internal" href="#design.mps.bt.req.bit">.req.bit:</a> The storage for a Bit Table of <em>n</em> bits shall take
|
||
no more than a small constant addition to the storage required for <em>n</em>
|
||
bits. <span class="target" id="design.mps.bt..req.bit.why"></span><a class="mpstag reference internal" href="#design.mps.bt..req.bit.why">..req.bit.why:</a> This is so that clients can make some
|
||
predictions about how much storage their algorithms use. A small
|
||
constant is allowed over the minimal for two reasons: inevitable
|
||
implementation overheads (such as only being able to allocate storage
|
||
in multiples of 32 bits), extra storage for robustness or speed (such
|
||
as signature and length fields).</p>
|
||
<p><span class="target" id="design.mps.bt.req.create"></span><a class="mpstag reference internal" href="#design.mps.bt.req.create">.req.create:</a> A means to create Bit Tables.
|
||
<span class="target" id="design.mps.bt.req.create.why"></span><a class="mpstag reference internal" href="#design.mps.bt.req.create.why">.req.create.why:</a> Obvious.</p>
|
||
<p><span class="target" id="design.mps.bt.req.destroy"></span><a class="mpstag reference internal" href="#design.mps.bt.req.destroy">.req.destroy:</a> A means to destroy Bit Tables.
|
||
<span class="target" id="design.mps.bt.req.destroy.why"></span><a class="mpstag reference internal" href="#design.mps.bt.req.destroy.why">.req.destroy.why:</a> Obvious.</p>
|
||
<p><span class="target" id="design.mps.bt.req.ops"></span><a class="mpstag reference internal" href="#design.mps.bt.req.ops">.req.ops:</a> The following operations shall be supported:</p>
|
||
<ul class="simple">
|
||
<li><span class="target" id="design.mps.bt.req.ops.get"></span><a class="mpstag reference internal" href="#design.mps.bt.req.ops.get">.req.ops.get:</a> <strong>Get</strong>. Get the value of a bit at a specified
|
||
index.</li>
|
||
<li><span class="target" id="design.mps.bt.req.ops.set"></span><a class="mpstag reference internal" href="#design.mps.bt.req.ops.set">.req.ops.set:</a> <strong>Set</strong>. Set a bit at a specified index.</li>
|
||
<li><span class="target" id="design.mps.bt.req.ops.reset"></span><a class="mpstag reference internal" href="#design.mps.bt.req.ops.reset">.req.ops.reset:</a> <strong>Reset</strong>. Reset a bit at a specified index.</li>
|
||
</ul>
|
||
<p><span class="target" id="design.mps.bt.req.ops.minimal.why"></span><a class="mpstag reference internal" href="#design.mps.bt.req.ops.minimal.why">.req.ops.minimal.why:</a> Get, Set, Reset, are the minimal
|
||
operations. All possible mappings can be created and inspected using
|
||
these operations.</p>
|
||
<ul class="simple">
|
||
<li><span class="target" id="design.mps.bt.req.ops.set.range"></span><a class="mpstag reference internal" href="#design.mps.bt.req.ops.set.range">.req.ops.set.range:</a> <strong>SetRange</strong>. Set a range of bits.
|
||
<span class="target" id="design.mps.bt.req.ops.set.range.why"></span><a class="mpstag reference internal" href="#design.mps.bt.req.ops.set.range.why">.req.ops.set.range.why:</a> It’s expected that clients will
|
||
often want to set a range of bits; providing this operation allows
|
||
the implementation of the BT module to make the operation efficient.</li>
|
||
<li><span class="target" id="design.mps.bt.req.ops.reset.range"></span><a class="mpstag reference internal" href="#design.mps.bt.req.ops.reset.range">.req.ops.reset.range:</a> <strong>ResetRange</strong>. Reset a range of
|
||
bits. <span class="target" id="design.mps.bt.req.ops.reset.range.why"></span><a class="mpstag reference internal" href="#design.mps.bt.req.ops.reset.range.why">.req.ops.reset.range.why:</a> as for SetRange, see
|
||
<a class="reference internal" href="#design.mps.bt.req.ops.set.range.why">.req.ops.set.range.why</a>.</li>
|
||
<li><span class="target" id="design.mps.bt.req.ops.test.range.set"></span><a class="mpstag reference internal" href="#design.mps.bt.req.ops.test.range.set">.req.ops.test.range.set:</a> <strong>IsSetRange</strong>. Test whether a range
|
||
of bits are all set. <span class="target" id="design.mps.bt.req.ops.test.range.set.why"></span><a class="mpstag reference internal" href="#design.mps.bt.req.ops.test.range.set.why">.req.ops.test.range.set.why:</a> Mostly
|
||
for checking. For example, often clients will know that a range they
|
||
are about to reset is currently all set, they can use this operation
|
||
to assert that fact.</li>
|
||
<li><span class="target" id="design.mps.bt.req.ops.test.range.reset"></span><a class="mpstag reference internal" href="#design.mps.bt.req.ops.test.range.reset">.req.ops.test.range.reset:</a> <strong>IsResetRange</strong>. Test whether a
|
||
range of bits are all reset. <span class="target" id="design.mps.bt.req.ops.test.range.reset.why"></span><a class="mpstag reference internal" href="#design.mps.bt.req.ops.test.range.reset.why">.req.ops.test.range.reset.why:</a>
|
||
As for IsSetRange, see <a class="reference internal" href="#design.mps.bt.req.ops.test.range.set.why">.req.ops.test.range.set.why</a>.</li>
|
||
<li><span class="target" id="design.mps.bt.req.ops.find"></span><a class="mpstag reference internal" href="#design.mps.bt.req.ops.find">.req.ops.find:</a> Find a range (which we’ll denote [<em>i</em>, <em>j</em>))
|
||
of at least <em>L</em> reset bits that lies in a specified subrange of the
|
||
entire Bit Table. Various find operations are required according to
|
||
the (additional) properties of the required range:<ul>
|
||
<li><span class="target" id="design.mps.bt.req.ops.find.short.low"></span><a class="mpstag reference internal" href="#design.mps.bt.req.ops.find.short.low">.req.ops.find.short.low:</a> <strong>FindShortResetRange</strong>. Of all
|
||
candidate ranges, find the range with least <em>j</em> (find the leftmost
|
||
range that has at least <em>L</em> reset bits and return just enough of
|
||
that). <span class="target" id="design.mps.bt.req.ops.find.short.low.why"></span><a class="mpstag reference internal" href="#design.mps.bt.req.ops.find.short.low.why">.req.ops.find.short.low.why:</a> Required by client
|
||
and VM arenas to allocate segments. The arenas implement definite
|
||
placement policies (such as lowest addressed segment first) so
|
||
they need the lowest (or highest) range that will do. It’s not
|
||
currently useful to allocate segments larger than the requested
|
||
size, so finding a short range is sufficient.</li>
|
||
<li><span class="target" id="design.mps.bt.req.ops.find.short.high"></span><a class="mpstag reference internal" href="#design.mps.bt.req.ops.find.short.high">.req.ops.find.short.high:</a> <strong>FindShortResetRangeHigh</strong>. Of
|
||
all candidate ranges, find the range with greatest <em>i</em> (find the
|
||
rightmost range that has at least <em>L</em> reset bits and return just
|
||
enough of that). <span class="target" id="design.mps.bt.req.ops.find.short.high.why"></span><a class="mpstag reference internal" href="#design.mps.bt.req.ops.find.short.high.why">.req.ops.find.short.high.why:</a> Required
|
||
by arenas to implement a specific segment placement policy
|
||
(highest addressed segment first).</li>
|
||
<li><span class="target" id="design.mps.bt.req.ops.find.long.low"></span><a class="mpstag reference internal" href="#design.mps.bt.req.ops.find.long.low">.req.ops.find.long.low:</a> <strong>FindLongResetRange</strong>. Of all
|
||
candidate ranges, identify the ranges with least <em>i</em> and of those
|
||
find the one with greatest <em>j</em> (find the leftmost range that has
|
||
at least <em>L</em> reset bits and return all of it).
|
||
<span class="target" id="design.mps.bt.req.ops.find.long.low.why"></span><a class="mpstag reference internal" href="#design.mps.bt.req.ops.find.long.low.why">.req.ops.find.long.low.why:</a> Required by the mark and
|
||
sweep Pool Classes (AMS, AWL, LO) for allocating objects (filling
|
||
a buffer). It’s more efficient to fill a buffer with as much
|
||
memory as is conveniently possible. There’s no strong reason to
|
||
find the lowest range but it’s bound to have some beneficial
|
||
(small) cache effect and makes the algorithm more predictable.</li>
|
||
<li><span class="target" id="design.mps.bt.req.ops.find.long.high"></span><a class="mpstag reference internal" href="#design.mps.bt.req.ops.find.long.high">.req.ops.find.long.high:</a> <strong>FindLongResetRangeHigh</strong>.
|
||
Provided, but not required, see
|
||
<a class="reference internal" href="#design.mps.bt.non-req.ops.find.long.high">.non-req.ops.find.long.high</a>.</li>
|
||
</ul>
|
||
</li>
|
||
<li><span class="target" id="design.mps.bt.req.ops.copy"></span><a class="mpstag reference internal" href="#design.mps.bt.req.ops.copy">.req.ops.copy:</a> Copy a range of bits from one Bit Table to another Bit Table. Various copy operations are required:<ul>
|
||
<li><span class="target" id="design.mps.bt.req.ops.copy.simple"></span><a class="mpstag reference internal" href="#design.mps.bt.req.ops.copy.simple">.req.ops.copy.simple:</a> Copy a range of bits from one Bit
|
||
Table to the same position in another Bit Table.
|
||
<span class="target" id="design.mps.bt.req.ops.copy.why"></span><a class="mpstag reference internal" href="#design.mps.bt.req.ops.copy.why">.req.ops.copy.why:</a> Required to support copying of the
|
||
tables for the “low” segment during segment merging and splitting,
|
||
for pools using tables (for example, <tt class="xref c c-type docutils literal"><span class="pre">PoolClassAMS</span></tt>).</li>
|
||
<li><span class="target" id="design.mps.bt.req.ops.copy.offset"></span><a class="mpstag reference internal" href="#design.mps.bt.req.ops.copy.offset">.req.ops.copy.offset:</a> Copy a range of bits from one Bit
|
||
Table to an offset position in another Bit Table.
|
||
<span class="target" id="design.mps.bt.req.ops.copy.why"></span><a class="mpstag reference internal" href="#design.mps.bt.req.ops.copy.why">.req.ops.copy.why:</a> Required to support copying of the
|
||
tables for the “high” segment during segment merging and
|
||
splitting, for pools which support this (currently none, as of
|
||
2000-01-17).</li>
|
||
<li><span class="target" id="design.mps.bt.req.ops.copy.invert"></span><a class="mpstag reference internal" href="#design.mps.bt.req.ops.copy.invert">.req.ops.copy.invert:</a> Copy a range of bits from one Bit
|
||
Table to the same position in another Bit Table inverting all the
|
||
bits in the target copy. <span class="target" id="design.mps.bt.req.ops.copy.invert.why"></span><a class="mpstag reference internal" href="#design.mps.bt.req.ops.copy.invert.why">.req.ops.copy.invert.why:</a>
|
||
Required by colour manipulation code in <tt class="xref c c-type docutils literal"><span class="pre">PoolClassAMS</span></tt> and
|
||
<tt class="xref c c-type docutils literal"><span class="pre">PoolClassLO</span></tt>.</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<p><span class="target" id="design.mps.bt.req.speed"></span><a class="mpstag reference internal" href="#design.mps.bt.req.speed">.req.speed:</a> Operations shall take no more than a few memory
|
||
operations per bit manipulated. <span class="target" id="design.mps.bt.req.speed.why"></span><a class="mpstag reference internal" href="#design.mps.bt.req.speed.why">.req.speed.why:</a> Any slower
|
||
would be gratuitous.</p>
|
||
<p><span class="target" id="design.mps.bt.req.speed.fast"></span><a class="mpstag reference internal" href="#design.mps.bt.req.speed.fast">.req.speed.fast:</a> The following operations shall be very fast:</p>
|
||
<ul>
|
||
<li><p class="first"><span class="target" id="design.mps.bt.req.speed.fast.find.short"></span><a class="mpstag reference internal" href="#design.mps.bt.req.speed.fast.find.short">.req.speed.fast.find.short:</a> FindShortResRange (the
|
||
operation used to meet <a class="reference internal" href="#design.mps.bt.req.ops.find.short.low">.req.ops.find.short.low</a>)
|
||
FindShortResRangeHigh (the operation used to meet
|
||
<a class="reference internal" href="#design.mps.bt.req.ops.find.short.high">.req.ops.find.short.high</a>).</p>
|
||
<p><span class="target" id="design.mps.bt.req.speed.fast.find.short.why"></span><a class="mpstag reference internal" href="#design.mps.bt.req.speed.fast.find.short.why">.req.speed.fast.find.short.why:</a> These two are used by the
|
||
client arena (design.mps.arena.client) and the VM arena
|
||
(design.mps.arena.vm) for finding segments in page tables. The
|
||
operation will be used sufficiently often that its speed will
|
||
noticeably affect the overall speed of the MPS. They will be called
|
||
with a length equal to the number of pages in a segment. Typical
|
||
values of this length depend on the pool classes used and their
|
||
configuration, but we can expect length to be small (1 to 16)
|
||
usually. We can expect the Bit Table to be populated densely where
|
||
it is populated at all, that is set bits will tend to be clustered
|
||
together in subranges.</p>
|
||
</li>
|
||
<li><p class="first"><span class="target" id="design.mps.bt.req.speed.fast.find.long"></span><a class="mpstag reference internal" href="#design.mps.bt.req.speed.fast.find.long">.req.speed.fast.find.long:</a> FindLongResRange (the operation
|
||
used to meet <a class="reference internal" href="#design.mps.bt.req.ops.find.long.low">.req.ops.find.long.low</a>)</p>
|
||
<p><span class="target" id="design.mps.bt.req.speed.fast.find.long.why"></span><a class="mpstag reference internal" href="#design.mps.bt.req.speed.fast.find.long.why">.req.speed.fast.find.long.why:</a> Used in the allocator for
|
||
<tt class="xref c c-type docutils literal"><span class="pre">PoolClassAWL</span></tt> (design.mps.poolawl(1)),
|
||
<tt class="xref c c-type docutils literal"><span class="pre">PoolClassAMS</span></tt> (design.mps.poolams(2)),
|
||
<tt class="xref c c-type docutils literal"><span class="pre">PoolClassEPVM</span></tt> (design.mps.poolepvm(0)). Of
|
||
these AWL and EPVM have speed requirements. For AWL the length of
|
||
range to be found will be the length of a Dylan table in words.
|
||
According to mail.tony.1999-05-05.11-36(0), only <entry-vector>
|
||
objects are allocated in AWL (though not all <entry-vector> objects
|
||
are allocated in AWL), and the mean length of an <entry-vector>
|
||
object is 486 Words. No data for EPVM alas.</p>
|
||
</li>
|
||
</ul>
|
||
<p><span class="target" id="design.mps.bt.req.speed.fast.other.why"></span><a class="mpstag reference internal" href="#design.mps.bt.req.speed.fast.other.why">.req.speed.fast.other.why:</a> We might expect mark and sweep
|
||
pools to make use of Bit Tables, the MPS has general requirements to
|
||
support efficient mark and sweep pools, so that imposes general speed
|
||
requirements on Bit Tables.</p>
|
||
</div>
|
||
<div class="section" id="non-requirements">
|
||
<h2>2.5. Non requirements<a class="headerlink" href="#non-requirements" title="Permalink to this headline">¶</a></h2>
|
||
<p>The following are not requirements but the current design could
|
||
support them with little modification or does support them. Often they
|
||
used to be requirements, but are no longer, or were added
|
||
speculatively or experimentally but aren’t currently used.</p>
|
||
<ul class="simple">
|
||
<li><span class="target" id="design.mps.bt.non-req.ops.test.range.same"></span><a class="mpstag reference internal" href="#design.mps.bt.non-req.ops.test.range.same">.non-req.ops.test.range.same:</a> <strong>RangesSame</strong>. Test whether
|
||
two ranges that occupy the same positions in different Bit Tables
|
||
are the same. This used to be required by <tt class="xref c c-type docutils literal"><span class="pre">PoolClassAMS</span></tt>,
|
||
but is no longer. Currently (1999-05-04) the functionality still
|
||
exists.</li>
|
||
<li><span class="target" id="design.mps.bt.non-req.ops.find.long.high"></span><a class="mpstag reference internal" href="#design.mps.bt.non-req.ops.find.long.high">.non-req.ops.find.long.high:</a> <strong>FindLongResetRangeHigh</strong>.
|
||
(see <a class="reference internal" href="#design.mps.bt.req.ops.find">.req.ops.find</a>) Of all candidate ranges, identify the
|
||
ranges with greatest <em>j</em> and of those find the one with least <em>i</em>
|
||
(find the rightmost range that has at least <em>L</em> reset bits and
|
||
return all of it). Provided for symmetry but only currently used by
|
||
the BT tests and <tt class="docutils literal"><span class="pre">cbstest.c</span></tt>.</li>
|
||
</ul>
|
||
</div>
|
||
<div class="section" id="background">
|
||
<h2>2.6. Background<a class="headerlink" href="#background" title="Permalink to this headline">¶</a></h2>
|
||
<p><span class="target" id="design.mps.bt.background"></span><a class="mpstag reference internal" href="#design.mps.bt.background">.background:</a> Originally Bit Tables were used and implemented
|
||
by <tt class="xref c c-type docutils literal"><span class="pre">PoolClassLO</span></tt> (design.mps.poollo). It was
|
||
decided to lift them out into a separate module when designing the
|
||
Pool to manage Dylan Weak Tables which is also a mark and sweep pool
|
||
and will make use of Bit Tables (see design.mps.poolawl).
|
||
<span class="target" id="design.mps.bt.background.analysis"></span><a class="mpstag reference internal" href="#design.mps.bt.background.analysis">.background.analysis:</a> analysis.mps.bt(0) contains
|
||
some of the analysis of the design decisions that were and were not
|
||
made in this document.</p>
|
||
</div>
|
||
<div class="section" id="clients">
|
||
<h2>2.7. Clients<a class="headerlink" href="#clients" title="Permalink to this headline">¶</a></h2>
|
||
<p><span class="target" id="design.mps.bt.clients"></span><a class="mpstag reference internal" href="#design.mps.bt.clients">.clients:</a> Bit Tables are used throughout the MPS but the
|
||
important uses are in the client and VM arenas
|
||
(design.mps.arena.client(0) and
|
||
design.mps.arena.vm(1)) a bit table is used to record
|
||
whether each page is free or not; several pool classes
|
||
(<tt class="xref c c-type docutils literal"><span class="pre">PoolClassLO</span></tt>, <tt class="xref c c-type docutils literal"><span class="pre">PoolClassEPVM</span></tt>,
|
||
<tt class="xref c c-type docutils literal"><span class="pre">PoolClassAMS</span></tt>) use bit tables to record which locations are
|
||
free and also to store colour.</p>
|
||
</div>
|
||
<div class="section" id="overview">
|
||
<h2>2.8. Overview<a class="headerlink" href="#overview" title="Permalink to this headline">¶</a></h2>
|
||
<p><span class="target" id="design.mps.bt.over"></span><a class="mpstag reference internal" href="#design.mps.bt.over">.over:</a> Mostly, the design is as simple as possible. The
|
||
significant complications are iteration (see <a class="reference internal" href="#design.mps.bt.iteration">.iteration</a>
|
||
below) and searching (see <a class="reference internal" href="#design.mps.bt.fun.find-res-range">.fun.find-res-range</a> below)
|
||
because both of these are required to be fast.</p>
|
||
</div>
|
||
<div class="section" id="interface">
|
||
<h2>2.9. Interface<a class="headerlink" href="#interface" title="Permalink to this headline">¶</a></h2>
|
||
<dl class="type">
|
||
<dt>
|
||
<tt class="descname">typedef Word *BT;</tt></dt>
|
||
<dd></dd></dl>
|
||
|
||
<p><span class="target" id="design.mps.bt.if.representation.abstract"></span><a class="mpstag reference internal" href="#design.mps.bt.if.representation.abstract">.if.representation.abstract:</a> A Bit Table is represented by
|
||
the type <tt class="xref c c-type docutils literal"><span class="pre">BT</span></tt>.</p>
|
||
<p><span class="target" id="design.mps.bt.if.declare"></span><a class="mpstag reference internal" href="#design.mps.bt.if.declare">.if.declare:</a> The module declares a type <tt class="xref c c-type docutils literal"><span class="pre">BT</span></tt> and a
|
||
prototype for each of the functions below. The type is declared in
|
||
impl.h.mpmtypes, the prototypes are declared in
|
||
impl.h.mpm. Some of the functions are in fact implemented
|
||
as macros in the usual way
|
||
(doc.mps.ref-man.if-conv(0).macro.std).</p>
|
||
<p><span class="target" id="design.mps.bt.if.general.index"></span><a class="mpstag reference internal" href="#design.mps.bt.if.general.index">.if.general.index:</a> Many of the functions specified below take
|
||
indexes. If otherwise unspecified an index must be in the interval
|
||
[0, <em>n</em>) (note, up to, but not including, <em>n</em>) where <em>n</em> is the number
|
||
of bits in the relevant Bit Table (as passed to the <a class="reference internal" href="#BTCreate" title="BTCreate"><tt class="xref c c-func docutils literal"><span class="pre">BTCreate()</span></tt></a>
|
||
function).</p>
|
||
<p><span class="target" id="design.mps.bt.if.general.range"></span><a class="mpstag reference internal" href="#design.mps.bt.if.general.range">.if.general.range:</a> Where a range is specified by two indexes
|
||
(<em>base</em> and <em>limit</em>), the index <em>base</em>, which specifies the beginning
|
||
of the range, must be in the interval [0, <em>n</em>), and the index <em>limit</em>,
|
||
which specifies the end of the range, must be in the interval [1, <em>n</em>]
|
||
(note can be <em>n</em>), and <em>base</em> must be strictly less than <em>limit</em>
|
||
(empty ranges are not allowed). Sometimes <em>i</em> and <em>j</em> are used instead
|
||
of <em>base</em> and <em>limit</em>.</p>
|
||
<dl class="function">
|
||
<dt id="BTCreate">
|
||
<a class="reference internal" href="type.html#Res" title="Res">Res</a> <tt class="descname">BTCreate</tt><big>(</big>BT<em> *btReturn</em>, Arena<em> arena</em>, Count<em> n</em><big>)</big><a class="headerlink" href="#BTCreate" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
<p><span class="target" id="design.mps.bt.if.create"></span><a class="mpstag reference internal" href="#design.mps.bt.if.create">.if.create:</a> Attempts to create a table of length <tt class="docutils literal"><span class="pre">n</span></tt> in the
|
||
arena control pool, putting the table in <tt class="docutils literal"><span class="pre">*btReturn</span></tt>. Returns
|
||
<tt class="xref c c-macro docutils literal"><span class="pre">ResOK</span></tt> if and only if the table is created OK. The initial
|
||
values of the bits in the table are undefined (so the client should
|
||
probably call <a class="reference internal" href="#BTResRange" title="BTResRange"><tt class="xref c c-func docutils literal"><span class="pre">BTResRange()</span></tt></a> on the entire range before using
|
||
the <tt class="xref c c-type docutils literal"><span class="pre">BT</span></tt>). Meets <a class="reference internal" href="#design.mps.bt.req.create">.req.create</a>.</p>
|
||
<dl class="function">
|
||
<dt id="BTDestroy">
|
||
void <tt class="descname">BTDestroy</tt><big>(</big>BT<em> t</em>, Arena<em> arena</em>, Count<em> n</em><big>)</big><a class="headerlink" href="#BTDestroy" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
<p><span class="target" id="design.mps.bt.if.destroy"></span><a class="mpstag reference internal" href="#design.mps.bt.if.destroy">.if.destroy:</a> Destroys the table <tt class="docutils literal"><span class="pre">t</span></tt>, which must have been
|
||
created with <a class="reference internal" href="#BTCreate" title="BTCreate"><tt class="xref c c-func docutils literal"><span class="pre">BTCreate()</span></tt></a>. The value of argument <tt class="docutils literal"><span class="pre">n</span></tt> must be
|
||
same as the value of the argument passed to <a class="reference internal" href="#BTCreate" title="BTCreate"><tt class="xref c c-func docutils literal"><span class="pre">BTCreate()</span></tt></a>. Meets
|
||
mps:ref:<cite>.req.destroy</cite>.</p>
|
||
<dl class="function">
|
||
<dt id="BTSize">
|
||
size_t <tt class="descname">BTSize</tt><big>(</big>Count<em> n</em><big>)</big><a class="headerlink" href="#BTSize" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
<p><span class="target" id="design.mps.bt.if.size"></span><a class="mpstag reference internal" href="#design.mps.bt.if.size">.if.size:</a> <tt class="docutils literal"><span class="pre">BTSize(n)</span></tt> returns the number of bytes needed
|
||
for a Bit Table of <tt class="docutils literal"><span class="pre">n</span></tt> bits. <a class="reference internal" href="#BTSize" title="BTSize"><tt class="xref c c-func docutils literal"><span class="pre">BTSize()</span></tt></a> is a macro, but
|
||
<tt class="docutils literal"><span class="pre">(BTSize)(n)</span></tt> will assert if <tt class="docutils literal"><span class="pre">n</span></tt> exceeds <cite>COUNT_MAX -
|
||
MPS_WORD_WIDTH + 1`</cite>. This is used by clients that allocate storage
|
||
for the <tt class="xref c c-type docutils literal"><span class="pre">BT</span></tt> themselves. Before <a class="reference internal" href="#BTCreate" title="BTCreate"><tt class="xref c c-func docutils literal"><span class="pre">BTCreate()</span></tt></a> and
|
||
<a class="reference internal" href="#BTDestroy" title="BTDestroy"><tt class="xref c c-func docutils literal"><span class="pre">BTDestroy()</span></tt></a> were implemented that was the only way to allocate
|
||
a Bit Table, but is now deprecated.</p>
|
||
<dl class="function">
|
||
<dt id="BTGet">
|
||
int <tt class="descname">BTGet</tt><big>(</big>BT<em> t</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> i</em><big>)</big><a class="headerlink" href="#BTGet" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
<p><span class="target" id="design.mps.bt.if.get"></span><a class="mpstag reference internal" href="#design.mps.bt.if.get">.if.get:</a> <tt class="docutils literal"><span class="pre">BTGet(t,</span> <span class="pre">i)</span></tt> returns the <tt class="docutils literal"><span class="pre">i</span></tt>-th bit of the table
|
||
<tt class="docutils literal"><span class="pre">t</span></tt> (that is, the image of <tt class="docutils literal"><span class="pre">i</span></tt> under the mapping). Meets
|
||
<a class="reference internal" href="#design.mps.bt.req.ops.get">.req.ops.get</a>.</p>
|
||
<dl class="function">
|
||
<dt id="BTSet">
|
||
void <tt class="descname">BTSet</tt><big>(</big>BT<em> t</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> i</em><big>)</big><a class="headerlink" href="#BTSet" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
<p><span class="target" id="design.mps.bt.if.set"></span><a class="mpstag reference internal" href="#design.mps.bt.if.set">.if.set:</a> <tt class="docutils literal"><span class="pre">BTSet(t,</span> <span class="pre">i)</span></tt> sets the <tt class="docutils literal"><span class="pre">i</span></tt>-th bit of the table
|
||
<tt class="docutils literal"><span class="pre">t</span></tt> (to 1). <tt class="docutils literal"><span class="pre">BTGet(t,</span> <span class="pre">i)</span></tt> will now return 1. Meets
|
||
<a class="reference internal" href="#design.mps.bt.req.ops.set">.req.ops.set</a>.</p>
|
||
<dl class="function">
|
||
<dt id="BTRes">
|
||
void <tt class="descname">BTRes</tt><big>(</big>BT<em> t</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> i</em><big>)</big><a class="headerlink" href="#BTRes" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
<p><span class="target" id="design.mps.bt.if.res"></span><a class="mpstag reference internal" href="#design.mps.bt.if.res">.if.res:</a> <tt class="docutils literal"><span class="pre">BTRes(t,</span> <span class="pre">i)</span></tt> resets the <tt class="docutils literal"><span class="pre">i</span></tt>-th bit of the table
|
||
<tt class="docutils literal"><span class="pre">t</span></tt> (to 0). <tt class="docutils literal"><span class="pre">BTGet(t,</span> <span class="pre">i)</span></tt> will now return 0. Meets
|
||
<a class="reference internal" href="#design.mps.bt.req.ops.res">.req.ops.res</a>.</p>
|
||
<dl class="function">
|
||
<dt id="BTSetRange">
|
||
void <tt class="descname">BTSetRange</tt><big>(</big>BT<em> t</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> base</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> limit</em><big>)</big><a class="headerlink" href="#BTSetRange" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
<p><span class="target" id="design.mps.bt.if.set-range"></span><a class="mpstag reference internal" href="#design.mps.bt.if.set-range">.if.set-range:</a> <tt class="docutils literal"><span class="pre">BTSetRange(t,</span> <span class="pre">base,</span> <span class="pre">limit)</span></tt> sets the range
|
||
of bits [<tt class="docutils literal"><span class="pre">base</span></tt>, <tt class="docutils literal"><span class="pre">limit</span></tt>) in the table <tt class="docutils literal"><span class="pre">t</span></tt>. <tt class="docutils literal"><span class="pre">BTGet(t,</span> <span class="pre">x)</span></tt> will
|
||
now return 1 for <tt class="docutils literal"><span class="pre">base</span></tt> ≤ <tt class="docutils literal"><span class="pre">x</span></tt> < <tt class="docutils literal"><span class="pre">limit</span></tt>. Meets
|
||
<a class="reference internal" href="#design.mps.bt.req.ops.range.set">.req.ops.range.set</a>.</p>
|
||
<dl class="function">
|
||
<dt id="BTResRange">
|
||
void <tt class="descname">BTResRange</tt><big>(</big>BT<em> t</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> base</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> limit</em><big>)</big><a class="headerlink" href="#BTResRange" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
<p><span class="target" id="design.mps.bt.if.res-range"></span><a class="mpstag reference internal" href="#design.mps.bt.if.res-range">.if.res-range:</a> <tt class="docutils literal"><span class="pre">BTResRange(t,</span> <span class="pre">base,</span> <span class="pre">limit)</span></tt> resets the
|
||
range of bits [<tt class="docutils literal"><span class="pre">base</span></tt>, <tt class="docutils literal"><span class="pre">limit</span></tt>) in the table <tt class="docutils literal"><span class="pre">t</span></tt>. <tt class="docutils literal"><span class="pre">BTGet(t,</span>
|
||
<span class="pre">x)</span></tt> will now return 0 for <tt class="docutils literal"><span class="pre">base</span></tt> ≤ <tt class="docutils literal"><span class="pre">x</span></tt> < <tt class="docutils literal"><span class="pre">limit</span></tt>. Meets <a class="reference internal" href="#design.mps.bt.req.ops.range.res">.req.ops.range.res</a>.</p>
|
||
<dl class="function">
|
||
<dt id="BTIsSetRange">
|
||
<a class="reference internal" href="type.html#Bool" title="Bool">Bool</a> <tt class="descname">BTIsSetRange</tt><big>(</big>BT<em> bt</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> base</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> limit</em><big>)</big><a class="headerlink" href="#BTIsSetRange" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
<p><span class="target" id="design.mps.bt.if.test.range.set"></span><a class="mpstag reference internal" href="#design.mps.bt.if.test.range.set">.if.test.range.set:</a> Returns <tt class="docutils literal"><span class="pre">TRUE</span></tt> if all the bits in the
|
||
range [<tt class="docutils literal"><span class="pre">base</span></tt>, <tt class="docutils literal"><span class="pre">limit</span></tt>) are set, <tt class="docutils literal"><span class="pre">FALSE</span></tt> otherwise. Meets
|
||
<a class="reference internal" href="#design.mps.bt.req.ops.test.range.set">.req.ops.test.range.set</a>.</p>
|
||
<dl class="function">
|
||
<dt id="BTIsResRange">
|
||
<a class="reference internal" href="type.html#Bool" title="Bool">Bool</a> <tt class="descname">BTIsResRange</tt><big>(</big>BT<em> bt</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> base</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> limit</em><big>)</big><a class="headerlink" href="#BTIsResRange" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
<p><span class="target" id="design.mps.bt.if.test.range.reset"></span><a class="mpstag reference internal" href="#design.mps.bt.if.test.range.reset">.if.test.range.reset:</a> Returns <tt class="docutils literal"><span class="pre">TRUE</span></tt> if all the bits in the
|
||
range [<tt class="docutils literal"><span class="pre">base</span></tt>, <tt class="docutils literal"><span class="pre">limit</span></tt>) are reset, <tt class="docutils literal"><span class="pre">FALSE</span></tt> otherwise. Meets
|
||
<a class="reference internal" href="#design.mps.bt.req.ops.test.range.reset">.req.ops.test.range.reset</a>.</p>
|
||
<dl class="function">
|
||
<dt>
|
||
<tt class="descname">Bool BTRangesSame(BT BTx, BT BTy, Index base, Index limit);</tt></dt>
|
||
<dd></dd></dl>
|
||
|
||
<p><span class="target" id="design.mps.bt.if.test.range.same"></span><a class="mpstag reference internal" href="#design.mps.bt.if.test.range.same">.if.test.range.same:</a> returns <tt class="docutils literal"><span class="pre">TRUE</span></tt> if <tt class="docutils literal"><span class="pre">BTGet(BTx,i)</span></tt>
|
||
equals <tt class="docutils literal"><span class="pre">BTGet(BTy,i)</span></tt> for <tt class="docutils literal"><span class="pre">i</span></tt> in [<tt class="docutils literal"><span class="pre">base</span></tt>, <tt class="docutils literal"><span class="pre">limit</span></tt>), and
|
||
<tt class="docutils literal"><span class="pre">FALSE</span></tt> otherwise. Meets <a class="reference internal" href="#design.mps.bt.non-req.ops.test.range.same">.non-req.ops.test.range.same</a>.</p>
|
||
<p><span class="target" id="design.mps.bt.if.find.general"></span><a class="mpstag reference internal" href="#design.mps.bt.if.find.general">.if.find.general:</a> There are four functions (below) to find
|
||
reset ranges. All the functions have the same prototype (for
|
||
symmetry):</p>
|
||
<div class="highlight-c"><div class="highlight"><pre><span class="n">Bool</span> <span class="n">find</span><span class="p">(</span><span class="n">Index</span> <span class="o">*</span><span class="n">baseReturn</span><span class="p">,</span> <span class="n">Index</span> <span class="o">*</span><span class="n">limitReturn</span><span class="p">,</span>
|
||
<span class="n">BT</span> <span class="n">bt</span><span class="p">,</span>
|
||
<span class="n">Index</span> <span class="n">searchBase</span><span class="p">,</span> <span class="n">Index</span> <span class="n">searchLimit</span><span class="p">,</span>
|
||
<span class="n">Count</span> <span class="n">length</span><span class="p">);</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>where <tt class="docutils literal"><span class="pre">bt</span></tt> is the Bit Table in which to search. <tt class="docutils literal"><span class="pre">searchBase</span></tt> and
|
||
<tt class="docutils literal"><span class="pre">searchLimit</span></tt> specify a subset of the Bit Table to use, the
|
||
functions will only find ranges that are subsets of [<tt class="docutils literal"><span class="pre">searchBase</span></tt>,
|
||
<tt class="docutils literal"><span class="pre">searchLimit</span></tt>) (when set, <tt class="docutils literal"><span class="pre">*baseReturn</span></tt> will never be less than
|
||
<tt class="docutils literal"><span class="pre">searchBase</span></tt> and <tt class="docutils literal"><span class="pre">*limitReturn</span></tt> will never be greater than
|
||
<tt class="docutils literal"><span class="pre">searchLimit</span></tt>). <tt class="docutils literal"><span class="pre">searchBase</span></tt> and <tt class="docutils literal"><span class="pre">searchLimit</span></tt> specify a range
|
||
that must conform to the general range requirements for a range
|
||
[<em>i</em>, <em>j</em>), as per <a class="reference internal" href="#design.mps.bt.if.general.range">.if.general.range</a> modified appropriately.
|
||
<tt class="docutils literal"><span class="pre">length</span></tt> is the number of contiguous reset bits to find; it must not
|
||
be bigger than <tt class="docutils literal"><span class="pre">searchLimit</span> <span class="pre">-</span> <span class="pre">searchBase</span></tt> (that would be silly). If
|
||
a suitable range cannot be found the function returns <tt class="docutils literal"><span class="pre">FALSE</span></tt> (0)
|
||
and leaves <tt class="docutils literal"><span class="pre">*baseReturn</span></tt> and <tt class="docutils literal"><span class="pre">*limitReturn</span></tt> untouched. If a
|
||
suitable range is found then the function returns the range’s base in
|
||
<tt class="docutils literal"><span class="pre">*baseReturn</span></tt> and its limit in <tt class="docutils literal"><span class="pre">*limitReturn</span></tt> and returns <tt class="docutils literal"><span class="pre">TRUE</span></tt>
|
||
(1).</p>
|
||
<dl class="function">
|
||
<dt id="BTFindShortResRange">
|
||
<a class="reference internal" href="type.html#Bool" title="Bool">Bool</a> <tt class="descname">BTFindShortResRange</tt><big>(</big><a class="reference internal" href="type.html#Index" title="Index">Index</a><em> *baseReturn</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> *limitReturn</em>, BT<em> bt</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> searchBase</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> searchLimit</em>, Count<em> length</em><big>)</big><a class="headerlink" href="#BTFindShortResRange" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
<p><span class="target" id="design.mps.bt.if.find-short-res-range"></span><a class="mpstag reference internal" href="#design.mps.bt.if.find-short-res-range">.if.find-short-res-range:</a> Finds a range of reset bits in the
|
||
table, starting at <tt class="docutils literal"><span class="pre">searchBase</span></tt> and working upwards. This function
|
||
is intended to meet <a class="reference internal" href="#design.mps.bt.req.ops.find.short.low">.req.ops.find.short.low</a> so it will find
|
||
the leftmost range that will do, and never finds a range longer than
|
||
the requested length (the intention is that it will not waste time
|
||
looking).</p>
|
||
<dl class="function">
|
||
<dt id="BTFindShortResRangeHigh">
|
||
<a class="reference internal" href="type.html#Bool" title="Bool">Bool</a> <tt class="descname">BTFindShortResRangeHigh</tt><big>(</big><a class="reference internal" href="type.html#Index" title="Index">Index</a><em> *baseReturn</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> *limitReturn</em>, BT<em> bt</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> searchBase</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> searchLimit</em>, Count<em> length</em><big>)</big><a class="headerlink" href="#BTFindShortResRangeHigh" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
<p><span class="target" id="design.mps.bt.if.find-short-res-range-high"></span><a class="mpstag reference internal" href="#design.mps.bt.if.find-short-res-range-high">.if.find-short-res-range-high:</a> Finds a range of reset bits in
|
||
the table, starting at <tt class="docutils literal"><span class="pre">searchLimit</span></tt> and working downwards. This
|
||
function is intended to meet <a class="reference internal" href="#design.mps.bt.req.ops.find.short.high">.req.ops.find.short.high</a> so it
|
||
will find the rightmost range that will do, and never finds a range
|
||
longer than the requested length.</p>
|
||
<dl class="function">
|
||
<dt id="BTFindLongResRange">
|
||
<a class="reference internal" href="type.html#Bool" title="Bool">Bool</a> <tt class="descname">BTFindLongResRange</tt><big>(</big><a class="reference internal" href="type.html#Index" title="Index">Index</a><em> *baseReturn</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> *limitReturn</em>, BT<em> bt</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> searchBase</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> searchLimit</em>, Count<em> length</em><big>)</big><a class="headerlink" href="#BTFindLongResRange" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
<p><span class="target" id="design.mps.bt.if.find-long-res-range"></span><a class="mpstag reference internal" href="#design.mps.bt.if.find-long-res-range">.if.find-long-res-range:</a> Finds a range of reset bits in the
|
||
table, starting at <tt class="docutils literal"><span class="pre">searchBase</span></tt> and working upwards. This function
|
||
is intended to meet <a class="reference internal" href="#design.mps.bt.req.ops.find.long.low">.req.ops.find.long.low</a> so it will find
|
||
the leftmost range that will do and returns all of that range (which
|
||
can be longer than the requested length).</p>
|
||
<dl class="function">
|
||
<dt id="BTFindLongResRangeHigh">
|
||
<a class="reference internal" href="type.html#Bool" title="Bool">Bool</a> <tt class="descname">BTFindLongResRangeHigh</tt><big>(</big><a class="reference internal" href="type.html#Index" title="Index">Index</a><em> *baseReturn</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> *limitReturn</em>, BT<em> bt</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> searchBase</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> searchLimit</em>, Count<em> length</em><big>)</big><a class="headerlink" href="#BTFindLongResRangeHigh" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
<p><span class="target" id="design.mps.bt.if.find-long-res-range-high"></span><a class="mpstag reference internal" href="#design.mps.bt.if.find-long-res-range-high">.if.find-long-res-range-high:</a> Finds a range of reset bits in
|
||
the table, starting at <tt class="docutils literal"><span class="pre">searchLimit</span></tt> and working downwards. This
|
||
function is intended to meet <a class="reference internal" href="#design.mps.bt.req.ops.find.long.high">.req.ops.find.long.high</a> so it
|
||
will find the rightmost range that will do and returns all that range
|
||
(which can be longer than the requested length).</p>
|
||
<dl class="function">
|
||
<dt id="BTCopyRange">
|
||
void <tt class="descname">BTCopyRange</tt><big>(</big>BT<em> fromBT</em>, BT<em> toBT</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> base</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> limit</em><big>)</big><a class="headerlink" href="#BTCopyRange" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
<p><span class="target" id="design.mps.bt.if.copy-range"></span><a class="mpstag reference internal" href="#design.mps.bt.if.copy-range">.if.copy-range:</a> Overwrites the <tt class="docutils literal"><span class="pre">i</span></tt>-th bit of <tt class="docutils literal"><span class="pre">toBT</span></tt> with
|
||
the <tt class="docutils literal"><span class="pre">i</span></tt>-th bit of <tt class="docutils literal"><span class="pre">fromBT</span></tt>, for all <tt class="docutils literal"><span class="pre">i</span></tt> in [<tt class="docutils literal"><span class="pre">base</span></tt>, <tt class="docutils literal"><span class="pre">limit</span></tt>).
|
||
Meets <a class="reference internal" href="#design.mps.bt.req.ops.copy.simple">.req.ops.copy.simple</a>.</p>
|
||
<dl class="function">
|
||
<dt id="BTCopyOffsetRange">
|
||
void <tt class="descname">BTCopyOffsetRange</tt><big>(</big>BT<em> fromBT</em>, BT<em> toBT</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> fromBase</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> fromLimit</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> toBase</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> toLimit</em><big>)</big><a class="headerlink" href="#BTCopyOffsetRange" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
<p><span class="target" id="design.mps.bt.if.copy-offset-range"></span><a class="mpstag reference internal" href="#design.mps.bt.if.copy-offset-range">.if.copy-offset-range:</a> Overwrites the <tt class="docutils literal"><span class="pre">i</span></tt>-th bit of <tt class="docutils literal"><span class="pre">toBT</span></tt>
|
||
with the <tt class="docutils literal"><span class="pre">j</span></tt>-th bit of <tt class="docutils literal"><span class="pre">fromBT</span></tt>, for all <tt class="docutils literal"><span class="pre">i</span></tt> in [<tt class="docutils literal"><span class="pre">toBase</span></tt>,
|
||
<tt class="docutils literal"><span class="pre">toLimit</span></tt>) and corresponding <tt class="docutils literal"><span class="pre">j</span></tt> in [<tt class="docutils literal"><span class="pre">fromBase</span></tt>, <tt class="docutils literal"><span class="pre">fromLimit</span></tt>).
|
||
Each of these ranges must be the same size. This might be
|
||
significantly less efficient than <a class="reference internal" href="#BTCopyRange" title="BTCopyRange"><tt class="xref c c-func docutils literal"><span class="pre">BTCopyRange()</span></tt></a>. Meets
|
||
<a class="reference internal" href="#design.mps.bt.req.ops.copy.offset">.req.ops.copy.offset</a>.</p>
|
||
<dl class="function">
|
||
<dt id="BTCopyInvertRange">
|
||
void <tt class="descname">BTCopyInvertRange</tt><big>(</big>BT<em> fromBT</em>, BT<em> toBT</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> base</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> limit</em><big>)</big><a class="headerlink" href="#BTCopyInvertRange" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
<p><span class="target" id="design.mps.bt.if.copy-invert-range"></span><a class="mpstag reference internal" href="#design.mps.bt.if.copy-invert-range">.if.copy-invert-range:</a> Overwrites the <tt class="docutils literal"><span class="pre">i</span></tt>-th bit of <tt class="docutils literal"><span class="pre">toBT</span></tt> with the inverse of the <tt class="docutils literal"><span class="pre">i</span></tt>-th bit of <tt class="docutils literal"><span class="pre">fromBT</span></tt>, for
|
||
all <tt class="docutils literal"><span class="pre">i</span></tt> in [<tt class="docutils literal"><span class="pre">base</span></tt>, <tt class="docutils literal"><span class="pre">limit</span></tt>). Meets <a class="reference internal" href="#design.mps.bt.req.ops.copy.invert">.req.ops.copy.invert</a>.</p>
|
||
</div>
|
||
<div class="section" id="detailed-design">
|
||
<h2>2.10. Detailed design<a class="headerlink" href="#detailed-design" title="Permalink to this headline">¶</a></h2>
|
||
<div class="section" id="data-structures">
|
||
<h3>2.10.1. Data structures<a class="headerlink" href="#data-structures" title="Permalink to this headline">¶</a></h3>
|
||
<p><span class="target" id="design.mps.bt.datastructure"></span><a class="mpstag reference internal" href="#design.mps.bt.datastructure">.datastructure:</a> Bit Tables will be represented as (a pointer
|
||
to) an array of <a class="reference internal" href="type.html#Word" title="Word"><tt class="xref c c-type docutils literal"><span class="pre">Word</span></tt></a>. A plain array is used instead of the
|
||
more usual design convention of implementing an abstract data type as
|
||
a structure with a signature (see guide.impl.c.adt(0)).
|
||
<span class="target" id="design.mps.bt.datastructure.words.justify"></span><a class="mpstag reference internal" href="#design.mps.bt.datastructure.words.justify">.datastructure.words.justify:</a> The type <a class="reference internal" href="type.html#Word" title="Word"><tt class="xref c c-type docutils literal"><span class="pre">Word</span></tt></a> is used
|
||
as it will probably map to the object that can be most efficiently
|
||
accessed on any particular platform.
|
||
<span class="target" id="design.mps.bt.datastructure.non-adt.justify"></span><a class="mpstag reference internal" href="#design.mps.bt.datastructure.non-adt.justify">.datastructure.non-adt.justify:</a> The usual abstract data type
|
||
convention was not followed because (i) The initial design (drj) was
|
||
lazy, (ii) Bit Tables are more likely to come in convenient powers of
|
||
two with the extra one or two words overhead. However, the loss of
|
||
checking is severe. Perhaps it would be better to use the usual
|
||
abstract data type style.</p>
|
||
</div>
|
||
<div class="section" id="functions">
|
||
<h3>2.10.2. Functions<a class="headerlink" href="#functions" title="Permalink to this headline">¶</a></h3>
|
||
<p><span class="target" id="design.mps.bt.fun.size"></span><a class="mpstag reference internal" href="#design.mps.bt.fun.size">.fun.size:</a> <a class="reference internal" href="#BTSize" title="BTSize"><tt class="xref c c-func docutils literal"><span class="pre">BTSize()</span></tt></a>. Since a Bit Table is an array of
|
||
<a class="reference internal" href="type.html#Word" title="Word"><tt class="xref c c-type docutils literal"><span class="pre">Word</span></tt></a>, the size of a Bit Table of <em>n</em> bits is simply the
|
||
number of words that it takes to store <em>n</em> bits times the number of
|
||
bytes in a word. This is ceiling(n/MPS_WORD_WIDTH)*sizeof(Word).
|
||
<span class="target" id="design.mps.bt.fun.size.justify"></span><a class="mpstag reference internal" href="#design.mps.bt.fun.size.justify">.fun.size.justify:</a> Since there can be at most
|
||
<cite>MPS_WORD_WIDTH - 1</cite> unused bits in the entire table, this satisfies
|
||
<a class="reference internal" href="#design.mps.bt.req.bit">.req.bit</a>.</p>
|
||
<p><span class="target" id="design.mps.bt.index"></span><a class="mpstag reference internal" href="#design.mps.bt.index">.index:</a> The designs for the following functions use a
|
||
decomposition of a bit-index, <tt class="docutils literal"><span class="pre">i</span></tt>, into two parts, <tt class="docutils literal"><span class="pre">iw</span></tt>, <tt class="docutils literal"><span class="pre">ib</span></tt>.</p>
|
||
<ul class="simple">
|
||
<li><span class="target" id="design.mps.bt.index.word"></span><a class="mpstag reference internal" href="#design.mps.bt.index.word">.index.word:</a> <tt class="docutils literal"><span class="pre">iw</span></tt> is the “word-index” which is the index
|
||
into the word array of the word that contains the bit referred to by
|
||
the bit-index. <tt class="docutils literal"><span class="pre">iw</span> <span class="pre">=</span> <span class="pre">i</span> <span class="pre">/</span> <span class="pre">MPS_WORD_WIDTH</span></tt>. Since <tt class="docutils literal"><span class="pre">MPS_WORD_WIDTH</span></tt>
|
||
is a power of two, this is the same as <tt class="docutils literal"><span class="pre">iw</span> <span class="pre">=</span> <span class="pre">i</span> <span class="pre">>></span> <span class="pre">MPS_WORD_SHIFT</span></tt>.
|
||
The latter expression is used in the code.
|
||
<span class="target" id="design.mps.bt.index.word.justify"></span><a class="mpstag reference internal" href="#design.mps.bt.index.word.justify">.index.word.justify:</a> The compiler is more likely to
|
||
generate good code without the divide.</li>
|
||
<li><span class="target" id="design.mps.bt.index.sub-word"></span><a class="mpstag reference internal" href="#design.mps.bt.index.sub-word">.index.sub-word:</a> <tt class="docutils literal"><span class="pre">ib</span></tt> is the “sub-word-index” which is
|
||
the index of the bit referred to by the bit-index in the above word.
|
||
<tt class="docutils literal"><span class="pre">ib</span> <span class="pre">=</span> <span class="pre">i</span> <span class="pre">%</span> <span class="pre">MPS_WORD_WIDTH</span></tt>. Since <tt class="docutils literal"><span class="pre">MPS_WORD_WIDTH</span></tt> is a power of
|
||
two, this is the same as <tt class="docutils literal"><span class="pre">ib</span> <span class="pre">=</span> <span class="pre">i</span> <span class="pre">&</span> <span class="pre">~((Word)-1<<MPS_WORD_SHIFT)</span></tt>.
|
||
The latter expression is used in the code.
|
||
<span class="target" id="design.mps.bt.index.sub-word.justify"></span><a class="mpstag reference internal" href="#design.mps.bt.index.sub-word.justify">.index.sub-word.justify:</a> The compiler is more likely to
|
||
generate good code without the modulus.</li>
|
||
</ul>
|
||
<p><span class="target" id="design.mps.bt.index.justify.dubious"></span><a class="mpstag reference internal" href="#design.mps.bt.index.justify.dubious">.index.justify.dubious:</a> The above justifications are dubious;
|
||
gcc 2.7.2 (with -O2) running on a sparc (zaphod) produces identical
|
||
code for the following two functions:</p>
|
||
<div class="highlight-c"><div class="highlight"><pre><span class="kt">unsigned</span> <span class="kt">long</span> <span class="nf">f</span><span class="p">(</span><span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">i</span><span class="p">)</span> <span class="p">{</span>
|
||
<span class="k">return</span> <span class="n">i</span><span class="o">/</span><span class="mi">32</span> <span class="o">+</span> <span class="n">i</span><span class="o">%</span><span class="mi">32</span><span class="p">;</span>
|
||
<span class="p">}</span>
|
||
|
||
<span class="kt">unsigned</span> <span class="kt">long</span> <span class="nf">g</span><span class="p">(</span><span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">i</span><span class="p">)</span> <span class="p">{</span>
|
||
<span class="k">return</span> <span class="p">(</span><span class="n">i</span><span class="o">>></span><span class="mi">5</span><span class="p">)</span> <span class="o">+</span> <span class="p">(</span><span class="n">i</span><span class="o">&</span><span class="mi">31</span><span class="p">);</span>
|
||
<span class="p">}</span>
|
||
</pre></div>
|
||
</div>
|
||
<dl class="function">
|
||
<dt id="ACT_ON_RANGE">
|
||
<tt class="descname">ACT_ON_RANGE</tt><big>(</big><a class="reference internal" href="type.html#Index" title="Index">Index</a><em> base</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> limit</em>, single_action, bits_action, word_action<big>)</big><a class="headerlink" href="#ACT_ON_RANGE" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="ACT_ON_RANGE_HIGH">
|
||
<tt class="descname">ACT_ON_RANGE_HIGH</tt><big>(</big><a class="reference internal" href="type.html#Index" title="Index">Index</a><em> base</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> limit</em>, single_action, bits_action, word_action<big>)</big><a class="headerlink" href="#ACT_ON_RANGE_HIGH" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
<p><span class="target" id="design.mps.bt.iteration"></span><a class="mpstag reference internal" href="#design.mps.bt.iteration">.iteration:</a> Many of the following functions involve iteration
|
||
over ranges in a Bit Table. This is performed on whole words rather
|
||
than individual bits, whenever possible (to improve speed). This is
|
||
implemented internally by the macros <a class="reference internal" href="#ACT_ON_RANGE" title="ACT_ON_RANGE"><tt class="xref c c-func docutils literal"><span class="pre">ACT_ON_RANGE()</span></tt></a> and
|
||
<a class="reference internal" href="#ACT_ON_RANGE_HIGH" title="ACT_ON_RANGE_HIGH"><tt class="xref c c-func docutils literal"><span class="pre">ACT_ON_RANGE_HIGH()</span></tt></a> for iterating over the range forwards and
|
||
backwards respectively. These macros do not form part of the interface
|
||
of the module, but are used extensively in the implementation. The
|
||
macros are often used even when speed is not an issue because it
|
||
simplifies the implementation and makes it more uniform. The iteration
|
||
macros take the parameters <tt class="docutils literal"><span class="pre">base</span></tt>, <tt class="docutils literal"><span class="pre">limit</span></tt>, <tt class="docutils literal"><span class="pre">single_action</span></tt>, <tt class="docutils literal"><span class="pre">bits_action</span></tt>, and <tt class="docutils literal"><span class="pre">word_action</span></tt>:</p>
|
||
<ul class="simple">
|
||
<li><tt class="docutils literal"><span class="pre">base</span></tt> and <tt class="docutils literal"><span class="pre">limit</span></tt> are of type <a class="reference internal" href="type.html#Index" title="Index"><tt class="xref c c-type docutils literal"><span class="pre">Index</span></tt></a> and define the
|
||
range of the iteration.</li>
|
||
<li><tt class="docutils literal"><span class="pre">single_action</span></tt> is the name of a macro which will be used for
|
||
iterating over bits in the table individually. This macro must take
|
||
a single <a class="reference internal" href="type.html#Index" title="Index"><tt class="xref c c-type docutils literal"><span class="pre">Index</span></tt></a> parameter corresponding to the index for
|
||
the bit. The expansion of the macro must not contain <tt class="docutils literal"><span class="pre">break</span></tt> or
|
||
<tt class="docutils literal"><span class="pre">continue</span></tt> because it will be called from within a loop from the
|
||
expansion of <a class="reference internal" href="#ACT_ON_RANGE" title="ACT_ON_RANGE"><tt class="xref c c-func docutils literal"><span class="pre">ACT_ON_RANGE()</span></tt></a>.</li>
|
||
<li><tt class="docutils literal"><span class="pre">bits_action</span></tt> is the name of a macro which will be used for
|
||
iterating over part-words. This macro must take parameters
|
||
<tt class="docutils literal"><span class="pre">wordIndex</span></tt>, <tt class="docutils literal"><span class="pre">base</span></tt>, <tt class="docutils literal"><span class="pre">limit</span></tt> where <tt class="docutils literal"><span class="pre">wordIndex</span></tt> is the index
|
||
into the array of words, and <tt class="docutils literal"><span class="pre">base</span></tt> and <tt class="docutils literal"><span class="pre">limit</span></tt> define a range
|
||
of bits within the indexed word.</li>
|
||
<li><tt class="docutils literal"><span class="pre">word_action</span></tt> is the name of a macro which will be used for
|
||
iterating over whole-words. This macro must take the single
|
||
parameter <tt class="docutils literal"><span class="pre">wordIndex</span></tt> which is the index of the whole-word in the
|
||
array. The expansion of the macro must not contain <tt class="docutils literal"><span class="pre">break</span></tt> or
|
||
<tt class="docutils literal"><span class="pre">continue</span></tt> because it will be called from within a loop from the
|
||
expansion of <a class="reference internal" href="#ACT_ON_RANGE" title="ACT_ON_RANGE"><tt class="xref c c-func docutils literal"><span class="pre">ACT_ON_RANGE()</span></tt></a>.</li>
|
||
</ul>
|
||
<p><span class="target" id="design.mps.bt.iteration.exit"></span><a class="mpstag reference internal" href="#design.mps.bt.iteration.exit">.iteration.exit:</a> The expansion of the <tt class="docutils literal"><span class="pre">single_action</span></tt>,
|
||
<tt class="docutils literal"><span class="pre">bits_action</span></tt>, and <tt class="docutils literal"><span class="pre">word_action</span></tt> macros is allowed to contain
|
||
<tt class="docutils literal"><span class="pre">return</span></tt> or <tt class="docutils literal"><span class="pre">goto</span></tt> to terminate the iteration early. This is used
|
||
by the test (<a class="reference internal" href="#design.mps.bt.fun.test.range.set">.fun.test.range.set</a>) and find
|
||
(<a class="reference internal" href="#design.mps.bt.fun.find">.fun.find</a>) operations.</p>
|
||
<p><span class="target" id="design.mps.bt.iteration.small"></span><a class="mpstag reference internal" href="#design.mps.bt.iteration.small">.iteration.small:</a> If the range is sufficiently small only the
|
||
<tt class="docutils literal"><span class="pre">single_action</span></tt> macro will be used, as this is more efficient in
|
||
practice. The choice of what constitutes a small range is made
|
||
entirely on the basis of experimental performance results (and
|
||
currently, 1999-04-27, a “small range” is 6 bits or fewer. See
|
||
change.mps.epcore.brisling.160181 for some justification). Otherwise
|
||
(for a bigger range) <tt class="docutils literal"><span class="pre">bits_action</span></tt> is used on the part words at
|
||
either end of the range (or the whole of the range it if it fits in a
|
||
single word), and <tt class="docutils literal"><span class="pre">word_action</span></tt> is used on the words that comprise
|
||
the inner portion of the range.</p>
|
||
<p>The implementation of <a class="reference internal" href="#ACT_ON_RANGE" title="ACT_ON_RANGE"><tt class="xref c c-func docutils literal"><span class="pre">ACT_ON_RANGE()</span></tt></a> (and
|
||
<a class="reference internal" href="#ACT_ON_RANGE_HIGH" title="ACT_ON_RANGE_HIGH"><tt class="xref c c-func docutils literal"><span class="pre">ACT_ON_RANGE_HIGH()</span></tt></a>) is simple enough. It decides which macros
|
||
it should invoke and invokes them. <tt class="docutils literal"><span class="pre">single_action</span></tt> and
|
||
<tt class="docutils literal"><span class="pre">word_action</span></tt> are invoked inside loops.</p>
|
||
<p><span class="target" id="design.mps.bt.fun.get"></span><a class="mpstag reference internal" href="#design.mps.bt.fun.get">.fun.get:</a> <a class="reference internal" href="#BTGet" title="BTGet"><tt class="xref c c-func docutils literal"><span class="pre">BTGet()</span></tt></a>. The bit-index will be converted in
|
||
the usual way, see <a class="reference internal" href="#design.mps.bt.index">.index</a>. The relevant <a class="reference internal" href="type.html#Word" title="Word"><tt class="xref c c-type docutils literal"><span class="pre">Word</span></tt></a> will
|
||
be read out of the Bit Table and shifted right by the
|
||
sub-<a class="reference internal" href="type.html#Word" title="Word"><tt class="xref c c-type docutils literal"><span class="pre">Word</span></tt></a> index (this brings the relevant bit down to the
|
||
least significant bit of the <a class="reference internal" href="type.html#Word" title="Word"><tt class="xref c c-type docutils literal"><span class="pre">Word</span></tt></a>), the <a class="reference internal" href="type.html#Word" title="Word"><tt class="xref c c-type docutils literal"><span class="pre">Word</span></tt></a> will
|
||
then be masked with 1, producing the answer.</p>
|
||
<p><span class="target" id="design.mps.bt.fun.set"></span><a class="mpstag reference internal" href="#design.mps.bt.fun.set">.fun.set:</a> <a class="reference internal" href="#BTSet" title="BTSet"><tt class="xref c c-func docutils literal"><span class="pre">BTSet()</span></tt></a>.</p>
|
||
<p><span class="target" id="design.mps.bt.fun.res"></span><a class="mpstag reference internal" href="#design.mps.bt.fun.res">.fun.res:</a> <a class="reference internal" href="#BTRes" title="BTRes"><tt class="xref c c-func docutils literal"><span class="pre">BTRes()</span></tt></a>.</p>
|
||
<p>In both <a class="reference internal" href="#BTSet" title="BTSet"><tt class="xref c c-func docutils literal"><span class="pre">BTSet()</span></tt></a> and <a class="reference internal" href="#BTRes" title="BTRes"><tt class="xref c c-func docutils literal"><span class="pre">BTRes()</span></tt></a> a mask is constructed by
|
||
shifting 1 left by the sub-word-index (see <a class="reference internal" href="#design.mps.bt.index">.index</a>). For
|
||
<a class="reference internal" href="#BTSet" title="BTSet"><tt class="xref c c-func docutils literal"><span class="pre">BTSet()</span></tt></a> the mask is or-ed into the relevant word (thereby
|
||
setting a single bit). For <a class="reference internal" href="#BTRes" title="BTRes"><tt class="xref c c-func docutils literal"><span class="pre">BTRes()</span></tt></a> the mask is inverted and
|
||
and-ed into the relevant word (thereby resetting a single bit).</p>
|
||
<p><span class="target" id="design.mps.bt.fun.set-range"></span><a class="mpstag reference internal" href="#design.mps.bt.fun.set-range">.fun.set-range:</a> <a class="reference internal" href="#BTSetRange" title="BTSetRange"><tt class="xref c c-func docutils literal"><span class="pre">BTSetRange()</span></tt></a>. <a class="reference internal" href="#ACT_ON_RANGE" title="ACT_ON_RANGE"><tt class="xref c c-func docutils literal"><span class="pre">ACT_ON_RANGE()</span></tt></a>
|
||
(see <a class="reference internal" href="#design.mps.bt.iteration">.iteration</a> above) is used with macros that set a
|
||
single bit (using <a class="reference internal" href="#BTSet" title="BTSet"><tt class="xref c c-func docutils literal"><span class="pre">BTSet()</span></tt></a>), set a range of bits in a word, and
|
||
set a whole word.</p>
|
||
<p><span class="target" id="design.mps.bt.fun.res-range"></span><a class="mpstag reference internal" href="#design.mps.bt.fun.res-range">.fun.res-range:</a> <a class="reference internal" href="#BTResRange" title="BTResRange"><tt class="xref c c-func docutils literal"><span class="pre">BTResRange()</span></tt></a> This is implemented
|
||
similarly to <a class="reference internal" href="#BTSetRange" title="BTSetRange"><tt class="xref c c-func docutils literal"><span class="pre">BTSetRange()</span></tt></a> (<a class="reference internal" href="#design.mps.bt.fun.set-range">.fun.set-range</a>) except
|
||
using <a class="reference internal" href="#BTRes" title="BTRes"><tt class="xref c c-func docutils literal"><span class="pre">BTRes()</span></tt></a> and reverse bit-masking logic.</p>
|
||
<p><span class="target" id="design.mps.bt.fun.test.range.set"></span><a class="mpstag reference internal" href="#design.mps.bt.fun.test.range.set">.fun.test.range.set:</a> <a class="reference internal" href="#BTIsSetRange" title="BTIsSetRange"><tt class="xref c c-func docutils literal"><span class="pre">BTIsSetRange()</span></tt></a>.
|
||
<a class="reference internal" href="#ACT_ON_RANGE" title="ACT_ON_RANGE"><tt class="xref c c-func docutils literal"><span class="pre">ACT_ON_RANGE()</span></tt></a> (see <a class="reference internal" href="#design.mps.bt.iteration">.iteration</a> above) is used with
|
||
macros that test whether all the relevant bits are set; if some of the
|
||
relevant bits are not set then <tt class="docutils literal"><span class="pre">return</span> <span class="pre">FALSE</span></tt> is used to terminate
|
||
the iteration early and return from the <a class="reference internal" href="#BTIsSetRange" title="BTIsSetRange"><tt class="xref c c-func docutils literal"><span class="pre">BTIsSetRange()</span></tt></a>
|
||
function. If the iteration completes then <tt class="docutils literal"><span class="pre">TRUE</span></tt> is returned.</p>
|
||
<p><span class="target" id="design.mps.bt.fun.test.range.reset"></span><a class="mpstag reference internal" href="#design.mps.bt.fun.test.range.reset">.fun.test.range.reset:</a> <a class="reference internal" href="#BTIsResRange" title="BTIsResRange"><tt class="xref c c-func docutils literal"><span class="pre">BTIsResRange()</span></tt></a>. As for
|
||
<a class="reference internal" href="#BTIsSetRange" title="BTIsSetRange"><tt class="xref c c-func docutils literal"><span class="pre">BTIsSetRange()</span></tt></a> (<a class="reference internal" href="#design.mps.bt.fun.test.range.set">.fun.test.range.set</a> above) but
|
||
testing whether the bits are reset.</p>
|
||
<p><span class="target" id="design.mps.bt.fun.test.range.same"></span><a class="mpstag reference internal" href="#design.mps.bt.fun.test.range.same">.fun.test.range.same:</a> <tt class="xref c c-func docutils literal"><span class="pre">BTRangesSame()</span></tt>. As for
|
||
<a class="reference internal" href="#BTIsSetRange" title="BTIsSetRange"><tt class="xref c c-func docutils literal"><span class="pre">BTIsSetRange()</span></tt></a> (<a class="reference internal" href="#design.mps.bt.fun.test.range.set">.fun.test.range.set</a> above) but
|
||
testing whether corresponding ranges in the two Bit Tables are the
|
||
same. Note there are no speed requirements, but <a class="reference internal" href="#ACT_ON_RANGE" title="ACT_ON_RANGE"><tt class="xref c c-func docutils literal"><span class="pre">ACT_ON_RANGE()</span></tt></a>
|
||
is used for simplicity and uniformity.</p>
|
||
<p><span class="target" id="design.mps.bt.fun.find"></span><a class="mpstag reference internal" href="#design.mps.bt.fun.find">.fun.find:</a> The four external find functions
|
||
(<a class="reference internal" href="#BTFindShortResRange" title="BTFindShortResRange"><tt class="xref c c-func docutils literal"><span class="pre">BTFindShortResRange()</span></tt></a>, <a class="reference internal" href="#BTFindShortResRangeHigh" title="BTFindShortResRangeHigh"><tt class="xref c c-func docutils literal"><span class="pre">BTFindShortResRangeHigh()</span></tt></a>,
|
||
<a class="reference internal" href="#BTFindLongResRange" title="BTFindLongResRange"><tt class="xref c c-func docutils literal"><span class="pre">BTFindLongResRange()</span></tt></a>, <a class="reference internal" href="#BTFindLongResRangeHigh" title="BTFindLongResRangeHigh"><tt class="xref c c-func docutils literal"><span class="pre">BTFindLongResRangeHigh()</span></tt></a>) simply
|
||
call through to one of the two internal functions:
|
||
<a class="reference internal" href="#BTFindResRange" title="BTFindResRange"><tt class="xref c c-func docutils literal"><span class="pre">BTFindResRange()</span></tt></a> and <a class="reference internal" href="#BTFindResRangeHigh" title="BTFindResRangeHigh"><tt class="xref c c-func docutils literal"><span class="pre">BTFindResRangeHigh()</span></tt></a>.</p>
|
||
<dl class="function">
|
||
<dt id="BTFindResRange">
|
||
<a class="reference internal" href="type.html#Bool" title="Bool">Bool</a> <tt class="descname">BTFindResRange</tt><big>(</big><a class="reference internal" href="type.html#Index" title="Index">Index</a><em> *baseReturn</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> *limitReturn</em>, BT<em> bt</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> searchBase</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> searchLimit</em>, Count<em> minLength</em>, Count<em> maxLength</em><big>)</big><a class="headerlink" href="#BTFindResRange" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
<dl class="function">
|
||
<dt id="BTFindResRangeHigh">
|
||
<a class="reference internal" href="type.html#Bool" title="Bool">Bool</a> <tt class="descname">BTFindResRangeHigh</tt><big>(</big><a class="reference internal" href="type.html#Index" title="Index">Index</a><em> *baseReturn</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> *limitReturn</em>, BT<em> bt</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> searchBase</em>, <a class="reference internal" href="type.html#Index" title="Index">Index</a><em> searchLimit</em>, Count<em> minLength</em>, Count<em> maxLength</em><big>)</big><a class="headerlink" href="#BTFindResRangeHigh" title="Permalink to this definition">¶</a></dt>
|
||
<dd></dd></dl>
|
||
|
||
<p>There are two length parameters, one specifying the minimum length of
|
||
the range to be found, the other the maximum length. For
|
||
<tt class="xref c c-func docutils literal"><span class="pre">BTFindShort()</span></tt> and <tt class="xref c c-func docutils literal"><span class="pre">BTFindShortHigh()</span></tt>, <tt class="docutils literal"><span class="pre">maxLength</span></tt> is
|
||
equal to <tt class="docutils literal"><span class="pre">minLength</span></tt> when passed; for <tt class="xref c c-func docutils literal"><span class="pre">BTFindLong()</span></tt> and
|
||
<tt class="xref c c-func docutils literal"><span class="pre">BTFindLongHigh()</span></tt>, <tt class="docutils literal"><span class="pre">maxLength`</span> <span class="pre">is</span> <span class="pre">equal</span> <span class="pre">to</span> <span class="pre">the</span> <span class="pre">maximum</span>
|
||
<span class="pre">possible</span> <span class="pre">range,</span> <span class="pre">namely</span> <span class="pre">``searchLimit</span> <span class="pre">-</span> <span class="pre">searchBase</span></tt>.</p>
|
||
<p><span class="target" id="design.mps.bt.fun.find-res-range"></span><a class="mpstag reference internal" href="#design.mps.bt.fun.find-res-range">.fun.find-res-range:</a> <a class="reference internal" href="#BTFindResRange" title="BTFindResRange"><tt class="xref c c-func docutils literal"><span class="pre">BTFindResRange()</span></tt></a>. Iterate within
|
||
the search boundaries, identifying candidate ranges by searching for a
|
||
reset bit. The <a class="reference internal" href="../mmref/bib.html#bm77"><em>Boyer–Moore algorithm</em></a> is used (it’s
|
||
particularly easy to implement when there are only two symbols, 0 and
|
||
1, in the alphabet). For each candidate range, iterate backwards over
|
||
the bits from the end of the range towards the beginning. If a set bit
|
||
is found, this candidate has failed and a new candidate range is
|
||
selected. If when scanning for the set bit a range of reset bits was
|
||
found before finding the set bit, then this (small) range of reset
|
||
bits is used as the start of the next candidate. Additionally the end
|
||
of this small range of reset bits (the end of the failed candidate
|
||
range) is remembered so that we don’t have to iterate over this range
|
||
again. But if no reset bits were found in the candidate range, then
|
||
iterate again (starting from the end of the failed candidate) to look
|
||
for one. If during the backwards search no set bit is found, then we
|
||
have found a sufficiently large range of reset bits; now extend the
|
||
valid range as far as possible up to the maximum length by iterating
|
||
forwards up to the maximum limit looking for a set bit. The iterations
|
||
make use of the <a class="reference internal" href="#ACT_ON_RANGE" title="ACT_ON_RANGE"><tt class="xref c c-func docutils literal"><span class="pre">ACT_ON_RANGE()</span></tt></a> and <a class="reference internal" href="#ACT_ON_RANGE_HIGH" title="ACT_ON_RANGE_HIGH"><tt class="xref c c-func docutils literal"><span class="pre">ACT_ON_RANGE_HIGH()</span></tt></a>
|
||
macros, which can use <tt class="docutils literal"><span class="pre">goto</span></tt> to effect an early termination of the
|
||
iteration when a set/reset (as appropriate) bit is found. The macro
|
||
<tt class="xref c c-func docutils literal"><span class="pre">ACTION_FIND_SET_BIT()</span></tt> is used in the iterations. It
|
||
efficiently finds the first (that is, with lowest index or weight) set
|
||
bit in a word or subword.</p>
|
||
<p><span class="target" id="design.mps.bt.fun.find-res-range.improve"></span><a class="mpstag reference internal" href="#design.mps.bt.fun.find-res-range.improve">.fun.find-res-range.improve:</a> Various other performance
|
||
improvements have been suggested in the past, including some from
|
||
request.epcore.170534. Here is a list of potential improvements which
|
||
all sound plausible, but which have not led to performance
|
||
improvements in practice:</p>
|
||
<ul class="simple">
|
||
<li><span class="target" id="design.mps.bt.fun.find-res-range.improve.step.partial"></span><a class="mpstag reference internal" href="#design.mps.bt.fun.find-res-range.improve.step.partial">.fun.find-res-range.improve.step.partial:</a> When the top
|
||
index in a candidate range fails, skip partial words as well as
|
||
whole words, using, for example, lookup tables.</li>
|
||
<li><span class="target" id="design.mps.bt.fun.find-res-range.improve.lookup"></span><a class="mpstag reference internal" href="#design.mps.bt.fun.find-res-range.improve.lookup">.fun.find-res-range.improve.lookup:</a> When testing a
|
||
candidate run, examine multiple bits at once (for example, 8), using
|
||
lookup tables for (for example) index of first set bit, index of
|
||
last set bit, number of reset bits, length of maximum run of reset
|
||
bits.</li>
|
||
</ul>
|
||
<p><span class="target" id="design.mps.bt.fun.find-res-range-high"></span><a class="mpstag reference internal" href="#design.mps.bt.fun.find-res-range-high">.fun.find-res-range-high:</a> <a class="reference internal" href="#BTFindResRangeHigh" title="BTFindResRangeHigh"><tt class="xref c c-func docutils literal"><span class="pre">BTFindResRangeHigh()</span></tt></a>.
|
||
Exactly the same algorithm as in <a class="reference internal" href="#BTFindResRange" title="BTFindResRange"><tt class="xref c c-func docutils literal"><span class="pre">BTFindResRange()</span></tt></a> (see
|
||
<a class="reference internal" href="#design.mps.bt.fun.find-res-range">.fun.find-res-range</a> above), but moving over the table in
|
||
the opposite direction.</p>
|
||
<p><span class="target" id="design.mps.bt.fun.copy-simple-range"></span><a class="mpstag reference internal" href="#design.mps.bt.fun.copy-simple-range">.fun.copy-simple-range:</a> <a class="reference internal" href="#BTCopyRange" title="BTCopyRange"><tt class="xref c c-func docutils literal"><span class="pre">BTCopyRange()</span></tt></a>. Uses
|
||
<a class="reference internal" href="#ACT_ON_RANGE" title="ACT_ON_RANGE"><tt class="xref c c-func docutils literal"><span class="pre">ACT_ON_RANGE()</span></tt></a> (see <a class="reference internal" href="#design.mps.bt.iteration">.iteration</a> above) with the
|
||
obvious implementation. Should be fast.</p>
|
||
<p><span class="target" id="design.mps.bt.fun.copy-offset-range"></span><a class="mpstag reference internal" href="#design.mps.bt.fun.copy-offset-range">.fun.copy-offset-range:</a> <a class="reference internal" href="#BTCopyOffsetRange" title="BTCopyOffsetRange"><tt class="xref c c-func docutils literal"><span class="pre">BTCopyOffsetRange()</span></tt></a>. Uses a
|
||
simple iteration loop, reading bits with <a class="reference internal" href="#BTGet" title="BTGet"><tt class="xref c c-func docutils literal"><span class="pre">BTGet()</span></tt></a> and setting
|
||
them with <a class="reference internal" href="#BTSet" title="BTSet"><tt class="xref c c-func docutils literal"><span class="pre">BTSet()</span></tt></a>. Doesn’t use <a class="reference internal" href="#ACT_ON_RANGE" title="ACT_ON_RANGE"><tt class="xref c c-func docutils literal"><span class="pre">ACT_ON_RANGE()</span></tt></a> because
|
||
the two ranges will not, in general, be similarly word-aligned.</p>
|
||
<p><span class="target" id="design.mps.bt.fun.copy-invert-range"></span><a class="mpstag reference internal" href="#design.mps.bt.fun.copy-invert-range">.fun.copy-invert-range:</a> <a class="reference internal" href="#BTCopyInvertRange" title="BTCopyInvertRange"><tt class="xref c c-func docutils literal"><span class="pre">BTCopyInvertRange()</span></tt></a>. Uses
|
||
<a class="reference internal" href="#ACT_ON_RANGE" title="ACT_ON_RANGE"><tt class="xref c c-func docutils literal"><span class="pre">ACT_ON_RANGE()</span></tt></a> (see <a class="reference internal" href="#design.mps.bt.iteration">.iteration</a> above) with the
|
||
obvious implementation. Should be fast—although there are no speed
|
||
requirements.</p>
|
||
</div>
|
||
</div>
|
||
<div class="section" id="testing">
|
||
<h2>2.11. Testing<a class="headerlink" href="#testing" title="Permalink to this headline">¶</a></h2>
|
||
<p><span class="target" id="design.mps.bt.test"></span><a class="mpstag reference internal" href="#design.mps.bt.test">.test:</a> The following tests are available or have been used
|
||
during development.</p>
|
||
<p><span class="target" id="design.mps.bt.test.btcv"></span><a class="mpstag reference internal" href="#design.mps.bt.test.btcv">.test.btcv:</a> <tt class="docutils literal"><span class="pre">btcv.c</span></tt>. This is supposed to be a coverage
|
||
test, intended to execute all of the module’s code in at least some
|
||
minimal way.</p>
|
||
<p><span class="target" id="design.mps.bt.test.cbstest"></span><a class="mpstag reference internal" href="#design.mps.bt.test.cbstest">.test.cbstest:</a> <tt class="docutils literal"><span class="pre">cbstest.c</span></tt>. This was written as a test of
|
||
the <tt class="xref c c-type docutils literal"><span class="pre">CBS</span></tt> module (design.mps.cbs(2)). It compares
|
||
the functional operation of a <tt class="xref c c-type docutils literal"><span class="pre">CBS</span></tt> with that of a
|
||
<tt class="xref c c-type docutils literal"><span class="pre">BT</span></tt> so is a good functional test of either module.</p>
|
||
<p><span class="target" id="design.mps.bt.test.mmqa.120"></span><a class="mpstag reference internal" href="#design.mps.bt.test.mmqa.120">.test.mmqa.120:</a> MMQA_test_function!210.c. This is used
|
||
because it has a fair amount of segment allocation and freeing so
|
||
exercises the arena code that uses Bit Tables.</p>
|
||
<p><span class="target" id="design.mps.bt.test.bttest"></span><a class="mpstag reference internal" href="#design.mps.bt.test.bttest">.test.bttest:</a> <tt class="docutils literal"><span class="pre">bttest.c</span></tt>. This is an interactive test that
|
||
can be used to exercise some of the <tt class="xref c c-type docutils literal"><span class="pre">BT</span></tt> functionality by hand.</p>
|
||
<p><span class="target" id="design.mps.bt.test.dylan"></span><a class="mpstag reference internal" href="#design.mps.bt.test.dylan">.test.dylan:</a> It is possible to modify Dylan so that it uses
|
||
Bit Tables more extensively. See change.mps.epcore.brisling.160181
|
||
TEST1 and TEST2.</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="#">2. Bit tables</a><ul>
|
||
<li><a class="reference internal" href="#introduction">2.1. Introduction</a></li>
|
||
<li><a class="reference internal" href="#history">2.2. History</a></li>
|
||
<li><a class="reference internal" href="#definitions">2.3. Definitions</a></li>
|
||
<li><a class="reference internal" href="#requirements">2.4. Requirements</a></li>
|
||
<li><a class="reference internal" href="#non-requirements">2.5. Non requirements</a></li>
|
||
<li><a class="reference internal" href="#background">2.6. Background</a></li>
|
||
<li><a class="reference internal" href="#clients">2.7. Clients</a></li>
|
||
<li><a class="reference internal" href="#overview">2.8. Overview</a></li>
|
||
<li><a class="reference internal" href="#interface">2.9. Interface</a></li>
|
||
<li><a class="reference internal" href="#detailed-design">2.10. Detailed design</a><ul>
|
||
<li><a class="reference internal" href="#data-structures">2.10.1. Data structures</a></li>
|
||
<li><a class="reference internal" href="#functions">2.10.2. Functions</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#testing">2.11. Testing</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
<h4>Previous topic</h4>
|
||
<p class="topless"><a href="arena.html"
|
||
title="previous chapter">1. Arena</a></p>
|
||
<h4>Next topic</h4>
|
||
<p class="topless"><a href="cbs.html"
|
||
title="next chapter">3. Coalescing block structure</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="cbs.html" title="3. Coalescing block structure"
|
||
>next</a> |</li>
|
||
<li class="right" >
|
||
<a href="arena.html" title="1. Arena"
|
||
>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> |