mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-26 23:31:55 -08:00
Check in HTML version of the manual (writable on client) so that it will display automatically on the Ravenbrook server and so that we can easily include it in product releases. Copied from Perforce Change: 180338 ServerID: perforce.ravenbrook.com
443 lines
No EOL
36 KiB
HTML
443 lines
No EOL
36 KiB
HTML
|
|
|
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
|
|
|
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
|
|
<title>14. Segregated allocation caches — Memory Pool System 1.111.0 documentation</title>
|
|
|
|
<link rel="stylesheet" href="../_static/mps.css" type="text/css" />
|
|
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
|
|
|
<script type="text/javascript">
|
|
var DOCUMENTATION_OPTIONS = {
|
|
URL_ROOT: '../',
|
|
VERSION: '1.111.0',
|
|
COLLAPSE_INDEX: false,
|
|
FILE_SUFFIX: '.html',
|
|
HAS_SOURCE: true
|
|
};
|
|
</script>
|
|
<script type="text/javascript" src="../_static/jquery.js"></script>
|
|
<script type="text/javascript" src="../_static/underscore.js"></script>
|
|
<script type="text/javascript" src="../_static/doctools.js"></script>
|
|
<link rel="copyright" title="Copyright" href="../copyright.html" />
|
|
<link rel="top" title="Memory Pool System 1.111.0 documentation" href="../index.html" />
|
|
<link rel="up" title="Reference" href="index.html" />
|
|
<link rel="next" title="15. Allocation patterns" href="pattern.html" />
|
|
<link rel="prev" title="13. Location dependency" href="location.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="pattern.html" title="15. Allocation patterns"
|
|
accesskey="N">next</a> |</li>
|
|
<li class="right" >
|
|
<a href="location.html" title="13. Location dependency"
|
|
accesskey="P">previous</a> |</li>
|
|
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> »</li>
|
|
<li><a href="index.html" accesskey="U">Reference</a> »</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="document">
|
|
<div class="documentwrapper">
|
|
<div class="bodywrapper">
|
|
<div class="body">
|
|
|
|
<div class="section" id="segregated-allocation-caches">
|
|
<span id="topic-cache"></span><span id="index-0"></span><h1>14. Segregated allocation caches<a class="headerlink" href="#segregated-allocation-caches" title="Permalink to this headline">¶</a></h1>
|
|
<p>A <em class="dfn">segregated allocation cache</em> is a data structure that can be
|
|
attached to any <a class="reference internal" href="../glossary/m.html#term-manual-memory-management"><em class="xref std std-term">manually managed</em></a>
|
|
<a class="reference internal" href="../glossary/p.html#term-pool"><em class="xref std std-term">pool</em></a>, that maintains a <a class="reference internal" href="../glossary/s.html#term-segregated-free-list"><em class="xref std std-term">segregated free list</em></a>, that is,
|
|
a reserve of free blocks segregated by size.</p>
|
|
<p>Create a segregated allocation cache by preparing an array of
|
|
structures of type <a class="reference internal" href="#mps_sac_class_s" title="mps_sac_class_s"><tt class="xref c c-type docutils literal"><span class="pre">mps_sac_class_s</span></tt></a> and passing them to
|
|
<a class="reference internal" href="#mps_sac_create" title="mps_sac_create"><tt class="xref c c-func docutils literal"><span class="pre">mps_sac_create()</span></tt></a>. The values in these structures are hints as
|
|
to the size of the blocks, the number of blocks of each size, and the
|
|
relative frequency of allocations and deallocations at that size.</p>
|
|
<p>For example, suppose we have a pool where we expect to allocate a
|
|
small number of relatively long-lived 128-byte objects, and a large
|
|
number of relatively short-lived 8-byte objects, we might create a
|
|
cache as follows:</p>
|
|
<div class="highlight-c"><div class="highlight"><pre><span class="n">mps_sac_class_s</span> <span class="n">classes</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="o">=</span> <span class="p">{{</span><span class="mi">8</span><span class="p">,</span> <span class="mi">100</span><span class="p">,</span> <span class="mi">10</span><span class="p">},</span> <span class="p">{</span><span class="mi">128</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">1</span><span class="p">}};</span>
|
|
<span class="n">mps_sac_t</span> <span class="n">sac</span><span class="p">;</span>
|
|
|
|
<span class="n">res</span> <span class="o">=</span> <span class="n">mps_sac_create</span><span class="p">(</span><span class="o">&</span><span class="n">sac</span><span class="p">,</span> <span class="n">pool</span><span class="p">,</span> <span class="k">sizeof</span> <span class="n">classes</span> <span class="o">/</span> <span class="k">sizeof</span> <span class="n">classes</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">classes</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="n">res</span> <span class="o">!=</span> <span class="n">MPS_RES_OK</span><span class="p">)</span>
|
|
<span class="n">error</span><span class="p">(</span><span class="s">"failed to create allocation cache"</span><span class="p">);</span>
|
|
</pre></div>
|
|
</div>
|
|
<p>Allocations through the cache (using <a class="reference internal" href="#mps_sac_alloc" title="mps_sac_alloc"><tt class="xref c c-func docutils literal"><span class="pre">mps_sac_alloc()</span></tt></a> or
|
|
<a class="reference internal" href="#MPS_SAC_ALLOC_FAST" title="MPS_SAC_ALLOC_FAST"><tt class="xref c c-func docutils literal"><span class="pre">MPS_SAC_ALLOC_FAST()</span></tt></a>) are serviced from the cache if possible,
|
|
otherwise from the pool. Similarly, deallocations through the cache
|
|
(using <a class="reference internal" href="#mps_sac_free" title="mps_sac_free"><tt class="xref c c-func docutils literal"><span class="pre">mps_sac_free()</span></tt></a> or <a class="reference internal" href="#MPS_SAC_FREE_FAST" title="MPS_SAC_FREE_FAST"><tt class="xref c c-func docutils literal"><span class="pre">MPS_SAC_FREE_FAST()</span></tt></a>) return
|
|
the block to the appopriate free list for its size. For example:</p>
|
|
<div class="highlight-c"><div class="highlight"><pre><span class="n">Foo</span> <span class="o">*</span><span class="n">foo</span><span class="p">;</span>
|
|
<span class="n">mps_addr_t</span> <span class="n">p</span><span class="p">;</span>
|
|
<span class="n">mps_res_t</span> <span class="n">res</span><span class="p">;</span>
|
|
|
|
<span class="n">res</span> <span class="o">=</span> <span class="n">mps_sac_alloc</span><span class="p">(</span><span class="o">&</span><span class="n">p</span><span class="p">,</span> <span class="n">sac</span><span class="p">,</span> <span class="k">sizeof</span> <span class="o">*</span><span class="n">foo</span><span class="p">,</span> <span class="nb">false</span><span class="p">);</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="n">res</span> <span class="o">!=</span> <span class="n">MPS_RES_OK</span><span class="p">)</span>
|
|
<span class="n">error</span><span class="p">(</span><span class="s">"failed to alloc foo"</span><span class="p">);</span>
|
|
<span class="n">foo</span> <span class="o">=</span> <span class="n">p</span><span class="p">;</span>
|
|
|
|
<span class="cm">/* use 'foo' */</span>
|
|
|
|
<span class="n">mps_sac_free</span><span class="p">(</span><span class="n">sac</span><span class="p">,</span> <span class="n">p</span><span class="p">,</span> <span class="k">sizeof</span> <span class="o">*</span><span class="n">foo</span><span class="p">);</span>
|
|
</pre></div>
|
|
</div>
|
|
<p>The macros <a class="reference internal" href="#MPS_SAC_ALLOC_FAST" title="MPS_SAC_ALLOC_FAST"><tt class="xref c c-func docutils literal"><span class="pre">MPS_SAC_ALLOC_FAST()</span></tt></a> and
|
|
<a class="reference internal" href="#MPS_SAC_FREE_FAST" title="MPS_SAC_FREE_FAST"><tt class="xref c c-func docutils literal"><span class="pre">MPS_SAC_FREE_FAST()</span></tt></a> allow allocation and deallocation to be
|
|
inlined in the calling functions, in the case where a free block is
|
|
found in the cache.</p>
|
|
<div class="admonition-note admonition">
|
|
<p class="first admonition-title">Note</p>
|
|
<p>It is recommended that you deallocate a block via the same
|
|
segregated allocation cache that you allocated it from. However,
|
|
the system is more general than that, and in fact a block that was
|
|
allocated from cache A can be deallocated via cache B, provided
|
|
that:</p>
|
|
<ol class="last arabic simple">
|
|
<li>the two caches are attached to the same pool; and</li>
|
|
<li>the two caches have the same <em class="dfn">class structure</em>, that is,
|
|
they were created by passing identical arrays of <a class="reference internal" href="../glossary/s.html#term-size-class"><em class="xref std std-term">size
|
|
classes</em></a>.</li>
|
|
</ol>
|
|
</div>
|
|
<div class="admonition warning">
|
|
<p class="first admonition-title">Warning</p>
|
|
<p class="last">Segregated allocation caches work poorly with debugging pool
|
|
classes: the debugging checks only happen when blocks are moved
|
|
between the cache and the pool.</p>
|
|
</div>
|
|
<div class="section" id="cache-interface">
|
|
<span id="index-1"></span><h2>14.1. Cache interface<a class="headerlink" href="#cache-interface" title="Permalink to this headline">¶</a></h2>
|
|
<dl class="type">
|
|
<dt id="mps_sac_t">
|
|
<tt class="descname">mps_sac_t</tt><a class="headerlink" href="#mps_sac_t" title="Permalink to this definition">¶</a></dt>
|
|
<dd><p>The type of <a class="reference internal" href="../glossary/s.html#term-segregated-allocation-cache"><em class="xref std std-term">segregated allocation caches</em></a>.</p>
|
|
</dd></dl>
|
|
|
|
<dl class="macro">
|
|
<dt id="MPS_SAC_CLASS_LIMIT">
|
|
<tt class="descname">MPS_SAC_CLASS_LIMIT</tt><a class="headerlink" href="#MPS_SAC_CLASS_LIMIT" title="Permalink to this definition">¶</a></dt>
|
|
<dd><p>The number of <a class="reference internal" href="../glossary/s.html#term-size-class"><em class="xref std std-term">size classes</em></a> that <a class="reference internal" href="#mps_sac_create" title="mps_sac_create"><tt class="xref c c-func docutils literal"><span class="pre">mps_sac_create()</span></tt></a>
|
|
is guaranteed to accept.</p>
|
|
<p>More might be accepted: in fact, there might not be any limit in
|
|
the implementation on the maximum number of size classes, but if
|
|
you specify more than this many, you should be prepared to handle
|
|
the <a class="reference internal" href="../glossary/r.html#term-result-code"><em class="xref std std-term">result code</em></a> <a class="reference internal" href="error.html#MPS_RES_LIMIT" title="MPS_RES_LIMIT"><tt class="xref c c-macro docutils literal"><span class="pre">MPS_RES_LIMIT</span></tt></a>.</p>
|
|
</dd></dl>
|
|
|
|
<dl class="type">
|
|
<dt id="mps_sac_class_s">
|
|
<tt class="descname">mps_sac_class_s</tt><a class="headerlink" href="#mps_sac_class_s" title="Permalink to this definition">¶</a></dt>
|
|
<dd><p>The type of the structure describing a <a class="reference internal" href="../glossary/s.html#term-size-class"><em class="xref std std-term">size class</em></a> in a
|
|
<a class="reference internal" href="../glossary/s.html#term-segregated-allocation-cache"><em class="xref std std-term">segregated allocation cache</em></a>.</p>
|
|
<div class="highlight-c"><div class="highlight"><pre><span class="k">typedef</span> <span class="k">struct</span> <span class="n">mps_sac_class_s</span> <span class="p">{</span>
|
|
<span class="kt">size_t</span> <span class="n">mps_block_size</span><span class="p">;</span>
|
|
<span class="kt">size_t</span> <span class="n">mps_cached_count</span><span class="p">;</span>
|
|
<span class="kt">unsigned</span> <span class="n">mps_frequency</span><span class="p">;</span>
|
|
<span class="p">}</span> <span class="n">mps_sac_class_s</span><span class="p">;</span>
|
|
</pre></div>
|
|
</div>
|
|
<p>An array of these structures must be passed to
|
|
<a class="reference internal" href="#mps_sac_create" title="mps_sac_create"><tt class="xref c c-func docutils literal"><span class="pre">mps_sac_create()</span></tt></a> when creating a segregated allocation
|
|
cache.</p>
|
|
<p><tt class="docutils literal"><span class="pre">mps_block_size</span></tt> is the maximum <a class="reference internal" href="../glossary/s.html#term-size"><em class="xref std std-term">size</em></a> of any <a class="reference internal" href="../glossary/b.html#term-block"><em class="xref std std-term">block</em></a>
|
|
in this size class. It must be a multiple of the alignment of the
|
|
<a class="reference internal" href="../glossary/a.html#term-alignment"><em class="xref std std-term">alignment</em></a> of the <a class="reference internal" href="../glossary/p.html#term-pool"><em class="xref std std-term">pool</em></a> to which the cache belongs.</p>
|
|
<p><tt class="docutils literal"><span class="pre">mps_cached_count</span></tt> is the number of blocks of this size class to
|
|
cache. It is advice to the MPS on how many blocks to cache, not an
|
|
absolute limit. The cache policy tries to accommodate fluctuations
|
|
in the population and minimize the cost of responding to client
|
|
requests; the purpose of this parameter is to limit how much
|
|
memory the <a class="reference internal" href="../glossary/c.html#term-client-program"><em class="xref std std-term">client program</em></a> is willing to set aside for this
|
|
purpose. However, a <tt class="docutils literal"><span class="pre">cached_count</span></tt> of zero prevents any caching of
|
|
blocks falling into that size class.</p>
|
|
<p><tt class="docutils literal"><span class="pre">mps_frequency</span></tt> is a number that describes the frequency of
|
|
requests (allocation and deallocation combined) in this size class
|
|
relative to the other size classes in the cache.</p>
|
|
</dd></dl>
|
|
|
|
<dl class="function">
|
|
<dt id="mps_sac_create">
|
|
<a class="reference internal" href="error.html#mps_res_t" title="mps_res_t">mps_res_t</a> <tt class="descname">mps_sac_create</tt><big>(</big><a class="reference internal" href="#mps_sac_t" title="mps_sac_t">mps_sac_t</a><em> *sac_o</em>, <a class="reference internal" href="pool.html#mps_pool_t" title="mps_pool_t">mps_pool_t</a><em> pool</em>, size_t<em> classes_count</em>, <a class="reference internal" href="#mps_sac_class_s" title="mps_sac_class_s">mps_sac_class_s</a><em> *classes</em><big>)</big><a class="headerlink" href="#mps_sac_create" title="Permalink to this definition">¶</a></dt>
|
|
<dd><p>Create a <a class="reference internal" href="../glossary/s.html#term-segregated-allocation-cache"><em class="xref std std-term">segregated allocation cache</em></a> for a <a class="reference internal" href="../glossary/p.html#term-pool"><em class="xref std std-term">pool</em></a>.</p>
|
|
<p><tt class="docutils literal"><span class="pre">sac_o</span></tt> points to a location that will hold the address of the
|
|
segregated allocation cache.</p>
|
|
<p><tt class="docutils literal"><span class="pre">pool</span></tt> is the pool the cache is attached to.</p>
|
|
<p><tt class="docutils literal"><span class="pre">classes_count</span></tt> is the number of <a class="reference internal" href="../glossary/s.html#term-size-class"><em class="xref std std-term">size classes</em></a> in the
|
|
cache.</p>
|
|
<p><tt class="docutils literal"><span class="pre">classes</span></tt> points to an array describing the size classes in the
|
|
cache.</p>
|
|
<p>Returns <a class="reference internal" href="error.html#MPS_RES_OK" title="MPS_RES_OK"><tt class="xref c c-macro docutils literal"><span class="pre">MPS_RES_OK</span></tt></a> if the segregated allocation cache
|
|
is created successfully. Returns <a class="reference internal" href="error.html#MPS_RES_MEMORY" title="MPS_RES_MEMORY"><tt class="xref c c-macro docutils literal"><span class="pre">MPS_RES_MEMORY</span></tt></a> or
|
|
<a class="reference internal" href="error.html#MPS_RES_COMMIT_LIMIT" title="MPS_RES_COMMIT_LIMIT"><tt class="xref c c-macro docutils literal"><span class="pre">MPS_RES_COMMIT_LIMIT</span></tt></a> when it fails to allocate memory
|
|
for the internal cache structure. Returns <a class="reference internal" href="error.html#MPS_RES_LIMIT" title="MPS_RES_LIMIT"><tt class="xref c c-macro docutils literal"><span class="pre">MPS_RES_LIMIT</span></tt></a>
|
|
if you ask for too many size classes: in this case, combine some
|
|
small adjacent classes. Returns <a class="reference internal" href="error.html#MPS_RES_PARAM" title="MPS_RES_PARAM"><tt class="xref c c-macro docutils literal"><span class="pre">MPS_RES_PARAM</span></tt></a> if the
|
|
pool doesn’t support segregated allocation caches.</p>
|
|
<p>After this function returns, the array of size classes pointed to
|
|
be <tt class="docutils literal"><span class="pre">classes</span></tt> is no longer needed and may be discarded. The
|
|
segregated allocation cache pointed to by <tt class="docutils literal"><span class="pre">sac_o</span></tt> persists until
|
|
it is destroyed by calling <a class="reference internal" href="#mps_sac_destroy" title="mps_sac_destroy"><tt class="xref c c-func docutils literal"><span class="pre">mps_sac_destroy()</span></tt></a>.</p>
|
|
<p>This function creates an allocation cache whose <a class="reference internal" href="../glossary/f.html#term-free-list"><em class="xref std std-term">free list</em></a>
|
|
is segregated into the given size classes. The cache can get more
|
|
memory from the given pool, or return memory to it.</p>
|
|
<p>Segregated allocation caches can be associated with any pool that
|
|
supports <a class="reference internal" href="../glossary/m.html#term-manual-memory-management"><em class="xref std std-term">manual</em></a> allocation with
|
|
the functions <a class="reference internal" href="allocation.html#mps_alloc" title="mps_alloc"><tt class="xref c c-func docutils literal"><span class="pre">mps_alloc()</span></tt></a> and <a class="reference internal" href="allocation.html#mps_free" title="mps_free"><tt class="xref c c-func docutils literal"><span class="pre">mps_free()</span></tt></a>.</p>
|
|
<p>The size classes are described by an array of element type
|
|
<a class="reference internal" href="#mps_sac_class_s" title="mps_sac_class_s"><tt class="xref c c-func docutils literal"><span class="pre">mps_sac_class_s()</span></tt></a>. This array is used to initialize the
|
|
segregated allocation cache, and is not needed
|
|
after:c:func:<cite>mps_sac_create</cite> returns. The following constraints
|
|
apply to the array:</p>
|
|
<ul class="simple">
|
|
<li>You must specify at least one size class.</li>
|
|
<li>All size classes must have different sizes.</li>
|
|
<li>The size classes must be given in the order of increasing size.</li>
|
|
<li>The smallest size must be at least as large as <tt class="docutils literal"><span class="pre">sizeof(void</span> <span class="pre">*)</span></tt>.</li>
|
|
<li>Each size must be a multiple of the <a class="reference internal" href="../glossary/a.html#term-alignment"><em class="xref std std-term">alignment</em></a> of the
|
|
pool.</li>
|
|
<li>There might be a limit on how many classes can be described, but
|
|
it will be at least <a class="reference internal" href="#MPS_SAC_CLASS_LIMIT" title="MPS_SAC_CLASS_LIMIT"><tt class="xref c c-macro docutils literal"><span class="pre">MPS_SAC_CLASS_LIMIT</span></tt></a>.</li>
|
|
</ul>
|
|
<p>The MPS automatically provides an “overlarge” size class for
|
|
arbitrarily large allocations above the largest size class
|
|
described. Allocations falling into the overlarge size class are
|
|
not cached.</p>
|
|
<p>Any allocations whose size falls between two size classes are
|
|
allocated from the larger size class.</p>
|
|
<div class="admonition-note admonition">
|
|
<p class="first admonition-title">Note</p>
|
|
<p class="last">Too many size classes will slow down allocation; too few size
|
|
classes waste more space in internal fragmentation. It is
|
|
assumed that overlarge allocations are rare; otherwise, you
|
|
would add another size class for them, or even create separate
|
|
allocation caches or pools for them.</p>
|
|
</div>
|
|
</dd></dl>
|
|
|
|
<dl class="function">
|
|
<dt id="mps_sac_destroy">
|
|
void <tt class="descname">mps_sac_destroy</tt><big>(</big><a class="reference internal" href="#mps_sac_t" title="mps_sac_t">mps_sac_t</a><em> sac</em><big>)</big><a class="headerlink" href="#mps_sac_destroy" title="Permalink to this definition">¶</a></dt>
|
|
<dd><p>Destroy a <a class="reference internal" href="../glossary/s.html#term-segregated-allocation-cache"><em class="xref std std-term">segregated allocation cache</em></a>.</p>
|
|
<p><tt class="docutils literal"><span class="pre">sac</span></tt> is the segregated allocation cache to destroy.</p>
|
|
<p>Returns all memory in the cache to the associated <a class="reference internal" href="../glossary/p.html#term-pool"><em class="xref std std-term">pool</em></a>.
|
|
The pool might then return some memory to the <a class="reference internal" href="../glossary/a.html#term-arena"><em class="xref std std-term">arena</em></a>, but
|
|
that’s up to the pool’s usual policy.</p>
|
|
<p>Destroying the cache has no effect on blocks allocated through it.</p>
|
|
</dd></dl>
|
|
|
|
<dl class="function">
|
|
<dt id="mps_sac_flush">
|
|
void <tt class="descname">mps_sac_flush</tt><big>(</big><a class="reference internal" href="#mps_sac_t" title="mps_sac_t">mps_sac_t</a><em> sac</em><big>)</big><a class="headerlink" href="#mps_sac_flush" title="Permalink to this definition">¶</a></dt>
|
|
<dd><p>Flush a <a class="reference internal" href="../glossary/s.html#term-segregated-allocation-cache"><em class="xref std std-term">segregated allocation cache</em></a>, returning all memory
|
|
held in it to the associated <a class="reference internal" href="../glossary/p.html#term-pool"><em class="xref std std-term">pool</em></a>.</p>
|
|
<p><tt class="docutils literal"><span class="pre">sac</span></tt> is the segregated allocation cache to flush.</p>
|
|
<p>This is something that you’d typically do when you know you won’t
|
|
be using the segregated allocation cache for awhile, but want to
|
|
hold on to the cache itself. Destroying a cache has the effect of
|
|
flushing it.</p>
|
|
<p>Flushing the segregated allocation cache might well cause the pool
|
|
to return some memory to the <a class="reference internal" href="../glossary/a.html#term-arena"><em class="xref std std-term">arena</em></a>, but that’s up to the
|
|
pool’s usual policy.</p>
|
|
<div class="admonition-note admonition">
|
|
<p class="first admonition-title">Note</p>
|
|
<p class="last">The MPS might also decide to take memory from the segregated
|
|
allocation cache without the <a class="reference internal" href="../glossary/c.html#term-client-program"><em class="xref std std-term">client program</em></a> requesting
|
|
a flush.</p>
|
|
</div>
|
|
<div class="admonition-note admonition">
|
|
<p class="first admonition-title">Note</p>
|
|
<p class="last">The <a class="reference internal" href="../glossary/c.html#term-client-program"><em class="xref std std-term">client program</em></a> is responsible for synchronizing
|
|
the access to the cache, but if the cache decides to access
|
|
the pool, the MPS will properly synchronize with any other
|
|
<a class="reference internal" href="../glossary/t.html#term-thread"><em class="xref std std-term">threads</em></a> that might be accessing the same
|
|
pool.</p>
|
|
</div>
|
|
</dd></dl>
|
|
|
|
</div>
|
|
<div class="section" id="allocation-interface">
|
|
<span id="index-2"></span><h2>14.2. Allocation interface<a class="headerlink" href="#allocation-interface" title="Permalink to this headline">¶</a></h2>
|
|
<dl class="function">
|
|
<dt id="mps_sac_alloc">
|
|
<a class="reference internal" href="error.html#mps_res_t" title="mps_res_t">mps_res_t</a> <tt class="descname">mps_sac_alloc</tt><big>(</big><a class="reference internal" href="interface.html#mps_addr_t" title="mps_addr_t">mps_addr_t</a><em> *p_o</em>, <a class="reference internal" href="#mps_sac_t" title="mps_sac_t">mps_sac_t</a><em> sac</em>, size_t<em> size</em>, <a class="reference internal" href="interface.html#mps_bool_t" title="mps_bool_t">mps_bool_t</a><em> has_reservoir_permit</em><big>)</big><a class="headerlink" href="#mps_sac_alloc" title="Permalink to this definition">¶</a></dt>
|
|
<dd><p>Allocate a <a class="reference internal" href="../glossary/b.html#term-block"><em class="xref std std-term">block</em></a> using a <a class="reference internal" href="../glossary/s.html#term-segregated-allocation-cache"><em class="xref std std-term">segregated allocation
|
|
cache</em></a>. If no suitable block exists in the cache, ask for more
|
|
memory from the associated <a class="reference internal" href="../glossary/p.html#term-pool"><em class="xref std std-term">pool</em></a>.</p>
|
|
<p><tt class="docutils literal"><span class="pre">p_o</span></tt> points to a location that will hold the address of the
|
|
allocated block.</p>
|
|
<p><tt class="docutils literal"><span class="pre">sac</span></tt> is the segregated allocation cache.</p>
|
|
<p><tt class="docutils literal"><span class="pre">size</span></tt> is the <a class="reference internal" href="../glossary/s.html#term-size"><em class="xref std std-term">size</em></a> of the block to allocate. It does not
|
|
have to be one of the <a class="reference internal" href="../glossary/s.html#term-size-class"><em class="xref std std-term">size classes</em></a> of the cache; nor does
|
|
it have to be aligned.</p>
|
|
<p><tt class="docutils literal"><span class="pre">has_reservoir_permit</span></tt> should be false.</p>
|
|
<p>Returns <a class="reference internal" href="error.html#MPS_RES_OK" title="MPS_RES_OK"><tt class="xref c c-macro docutils literal"><span class="pre">MPS_RES_OK</span></tt></a> if successful: in this case the
|
|
address of the allocated block is <tt class="docutils literal"><span class="pre">*p_o</span></tt>. The allocated block
|
|
can be larger than requested. Blocks not matching any size class
|
|
are allocated from the next largest class, and blocks larger than
|
|
the largest size class are simply allocated at the requested size
|
|
(rounded up to alignment, as usual).</p>
|
|
<p>Returns <a class="reference internal" href="error.html#MPS_RES_MEMORY" title="MPS_RES_MEMORY"><tt class="xref c c-macro docutils literal"><span class="pre">MPS_RES_MEMORY</span></tt></a> if there wasn’t enough memory,
|
|
<a class="reference internal" href="error.html#MPS_RES_COMMIT_LIMIT" title="MPS_RES_COMMIT_LIMIT"><tt class="xref c c-macro docutils literal"><span class="pre">MPS_RES_COMMIT_LIMIT</span></tt></a> if the <a class="reference internal" href="../glossary/c.html#term-commit-limit"><em class="xref std std-term">commit limit</em></a> was
|
|
exceeded, or <a class="reference internal" href="error.html#MPS_RES_RESOURCE" title="MPS_RES_RESOURCE"><tt class="xref c c-macro docutils literal"><span class="pre">MPS_RES_RESOURCE</span></tt></a> if it ran out of
|
|
<a class="reference internal" href="../glossary/v.html#term-virtual-memory"><em class="xref std std-term">virtual memory</em></a>.</p>
|
|
<div class="admonition-note admonition">
|
|
<p class="first admonition-title">Note</p>
|
|
<p class="last">There’s also a macro <a class="reference internal" href="#MPS_SAC_ALLOC_FAST" title="MPS_SAC_ALLOC_FAST"><tt class="xref c c-func docutils literal"><span class="pre">MPS_SAC_ALLOC_FAST()</span></tt></a> that does
|
|
the same thing. The macro is faster, but generates more code
|
|
and does less checking.</p>
|
|
</div>
|
|
<div class="admonition-note admonition">
|
|
<p class="first admonition-title">Note</p>
|
|
<p class="last">The <a class="reference internal" href="../glossary/c.html#term-client-program"><em class="xref std std-term">client program</em></a> is responsible for synchronizing
|
|
the access to the cache, but if the cache decides to access
|
|
the pool, the MPS will properly synchronize with any other
|
|
<a class="reference internal" href="../glossary/t.html#term-thread"><em class="xref std std-term">threads</em></a> that might be accessing the same
|
|
pool.</p>
|
|
</div>
|
|
<div class="admonition-note admonition">
|
|
<p class="first admonition-title">Note</p>
|
|
<p class="last">Blocks allocated through a segregated allocation cache should
|
|
only be freed through a segregated allocation cache with the
|
|
same class structure. Calling <a class="reference internal" href="allocation.html#mps_free" title="mps_free"><tt class="xref c c-func docutils literal"><span class="pre">mps_free()</span></tt></a> on them can
|
|
cause <a class="reference internal" href="../glossary/m.html#term-memory-leak"><em class="xref std std-term">memory leaks</em></a>, because the size of
|
|
the block might be larger than you think. Naturally, the cache
|
|
must also be attached to the same pool.</p>
|
|
</div>
|
|
</dd></dl>
|
|
|
|
<dl class="function">
|
|
<dt id="MPS_SAC_ALLOC_FAST">
|
|
<tt class="descname">MPS_SAC_ALLOC_FAST</tt><big>(</big><a class="reference internal" href="error.html#mps_res_t" title="mps_res_t">mps_res_t</a><em> res_v</em>, <a class="reference internal" href="interface.html#mps_addr_t" title="mps_addr_t">mps_addr_t</a><em> *p_v</em>, <a class="reference internal" href="#mps_sac_t" title="mps_sac_t">mps_sac_t</a><em> sac</em>, size_t<em> size</em>, <a class="reference internal" href="interface.html#mps_bool_t" title="mps_bool_t">mps_bool_t</a><em> has_reservoir_permit</em><big>)</big><a class="headerlink" href="#MPS_SAC_ALLOC_FAST" title="Permalink to this definition">¶</a></dt>
|
|
<dd><p>A macro alternative to <a class="reference internal" href="#mps_sac_alloc" title="mps_sac_alloc"><tt class="xref c c-func docutils literal"><span class="pre">mps_sac_alloc()</span></tt></a>. It is faster than
|
|
the function, but generates more code, does less checking.</p>
|
|
<p>It takes an lvalue <tt class="docutils literal"><span class="pre">p_v</span></tt> which is assigned the address of the
|
|
allocated block (instead of a pointer to a location to store
|
|
it). It takes an additional first argument, the lvalue <tt class="docutils literal"><span class="pre">res_v</span></tt>,
|
|
which is assigned the <a class="reference internal" href="../glossary/r.html#term-result-code"><em class="xref std std-term">result code</em></a>.</p>
|
|
<div class="admonition-note admonition">
|
|
<p class="first admonition-title">Note</p>
|
|
<p class="last"><a class="reference internal" href="#MPS_SAC_ALLOC_FAST" title="MPS_SAC_ALLOC_FAST"><tt class="xref c c-func docutils literal"><span class="pre">MPS_SAC_ALLOC_FAST()</span></tt></a> may evaluate its arguments
|
|
multiple times, except for <tt class="docutils literal"><span class="pre">has_reservoir_permit</span></tt>, which it
|
|
evaluates at most once, and only if it decides to access the
|
|
pool.</p>
|
|
</div>
|
|
</dd></dl>
|
|
|
|
<dl class="function">
|
|
<dt id="mps_sac_free">
|
|
void <tt class="descname">mps_sac_free</tt><big>(</big><a class="reference internal" href="#mps_sac_t" title="mps_sac_t">mps_sac_t</a><em> sac</em>, <a class="reference internal" href="interface.html#mps_addr_t" title="mps_addr_t">mps_addr_t</a><em> p</em>, size_t<em> size</em><big>)</big><a class="headerlink" href="#mps_sac_free" title="Permalink to this definition">¶</a></dt>
|
|
<dd><p>Free a <a class="reference internal" href="../glossary/b.html#term-block"><em class="xref std std-term">block</em></a> using a <a class="reference internal" href="../glossary/s.html#term-segregated-allocation-cache"><em class="xref std std-term">segregated allocation
|
|
cache</em></a>. If the cache would become too full, some blocks may be
|
|
returned to the associated <a class="reference internal" href="../glossary/p.html#term-pool"><em class="xref std std-term">pool</em></a>.</p>
|
|
<p><tt class="docutils literal"><span class="pre">sac</span></tt> is the segregated allocation cache.</p>
|
|
<p><tt class="docutils literal"><span class="pre">p</span></tt> points to the block to be freed. This block must have been
|
|
allocated through a segregated allocation cache with the same
|
|
class structure, attached to the same pool. (Usually, you’d use
|
|
the same cache to allocate and deallocate a block, but the MPS is
|
|
more flexible.)</p>
|
|
<p><tt class="docutils literal"><span class="pre">size</span></tt> is the <a class="reference internal" href="../glossary/s.html#term-size"><em class="xref std std-term">size</em></a> of the block. It should be the size
|
|
that was specified when the block was allocated (the cache knows
|
|
what the real size of the block is).</p>
|
|
<div class="admonition-note admonition">
|
|
<p class="first admonition-title">Note</p>
|
|
<p class="last">The <a class="reference internal" href="../glossary/c.html#term-client-program"><em class="xref std std-term">client program</em></a> is responsible for synchronizing
|
|
the access to the cache, but if the cache decides to access
|
|
the pool, the MPS will properly synchronize with any other
|
|
<a class="reference internal" href="../glossary/t.html#term-thread"><em class="xref std std-term">threads</em></a> that might be accessing the same
|
|
pool.</p>
|
|
</div>
|
|
<div class="admonition-note admonition">
|
|
<p class="first admonition-title">Note</p>
|
|
<p class="last">There’s also a macro <a class="reference internal" href="#MPS_SAC_FREE_FAST" title="MPS_SAC_FREE_FAST"><tt class="xref c c-func docutils literal"><span class="pre">MPS_SAC_FREE_FAST()</span></tt></a> that does the
|
|
same thing. The macro is faster, but generates more code and
|
|
does no checking.</p>
|
|
</div>
|
|
<div class="admonition-note admonition">
|
|
<p class="first admonition-title">Note</p>
|
|
<p class="last"><a class="reference internal" href="#mps_sac_free" title="mps_sac_free"><tt class="xref c c-func docutils literal"><span class="pre">mps_sac_free()</span></tt></a> does very little checking: it’s
|
|
optimized for speed. <a class="reference internal" href="../glossary/d.html#term-double-free"><em class="xref std std-term">Double frees</em></a> and
|
|
other mistakes will only be detected when the cache is flushed
|
|
(either by calling <a class="reference internal" href="#mps_sac_flush" title="mps_sac_flush"><tt class="xref c c-func docutils literal"><span class="pre">mps_sac_flush()</span></tt></a> or automatically),
|
|
and may not be detected at all, if intervening operations have
|
|
obscured symptoms.</p>
|
|
</div>
|
|
</dd></dl>
|
|
|
|
<dl class="function">
|
|
<dt id="MPS_SAC_FREE_FAST">
|
|
<tt class="descname">MPS_SAC_FREE_FAST</tt><big>(</big><a class="reference internal" href="#mps_sac_t" title="mps_sac_t">mps_sac_t</a><em> sac</em>, <a class="reference internal" href="interface.html#mps_addr_t" title="mps_addr_t">mps_addr_t</a><em> p</em>, size_t<em> size</em><big>)</big><a class="headerlink" href="#MPS_SAC_FREE_FAST" title="Permalink to this definition">¶</a></dt>
|
|
<dd><p>A macro alternative to <a class="reference internal" href="#mps_sac_free" title="mps_sac_free"><tt class="xref c c-func docutils literal"><span class="pre">mps_sac_free()</span></tt></a> that is faster than
|
|
the function but does no checking. The arguments are identical to
|
|
the function.</p>
|
|
</dd></dl>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sphinxsidebar">
|
|
<div class="sphinxsidebarwrapper">
|
|
<p class="logo"><a href="../index.html">
|
|
<img class="logo" src="../_static/logo.png" alt="Logo"/>
|
|
</a></p>
|
|
<h3><a href="../index.html">Table Of Contents</a></h3>
|
|
<ul>
|
|
<li><a class="reference internal" href="#">14. Segregated allocation caches</a><ul>
|
|
<li><a class="reference internal" href="#cache-interface">14.1. Cache interface</a></li>
|
|
<li><a class="reference internal" href="#allocation-interface">14.2. Allocation interface</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
|
|
<h4>Previous topic</h4>
|
|
<p class="topless"><a href="location.html"
|
|
title="previous chapter">13. Location dependency</a></p>
|
|
<h4>Next topic</h4>
|
|
<p class="topless"><a href="pattern.html"
|
|
title="next chapter">15. Allocation patterns</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="pattern.html" title="15. Allocation patterns"
|
|
>next</a> |</li>
|
|
<li class="right" >
|
|
<a href="location.html" title="13. Location dependency"
|
|
>previous</a> |</li>
|
|
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> »</li>
|
|
<li><a href="index.html" >Reference</a> »</li>
|
|
</ul>
|
|
</div>
|
|
<div class="footer">
|
|
© <a href="../copyright.html">Copyright</a> 2012, Ravenbrook Limited.
|
|
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
|
|
</div>
|
|
</body>
|
|
</html> |