mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-26 07:11:34 -08:00
455 lines
No EOL
36 KiB
HTML
455 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>15. 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="16. Allocation patterns" href="pattern.html" />
|
|
<link rel="prev" title="14. 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="16. Allocation patterns"
|
|
accesskey="N">next</a> |</li>
|
|
<li class="right" >
|
|
<a href="location.html" title="14. 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>15. 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>15.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-type 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>15.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="#">15. Segregated allocation caches</a><ul>
|
|
<li><a class="reference internal" href="#cache-interface">15.1. Cache interface</a></li>
|
|
<li><a class="reference internal" href="#allocation-interface">15.2. Allocation interface</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
|
|
<h4>Previous topic</h4>
|
|
<p class="topless"><a href="location.html"
|
|
title="previous chapter">14. Location dependency</a></p>
|
|
<h4>Next topic</h4>
|
|
<p class="topless"><a href="pattern.html"
|
|
title="next chapter">16. Allocation patterns</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="pattern.html" title="16. Allocation patterns"
|
|
>next</a> |</li>
|
|
<li class="right" >
|
|
<a href="location.html" title="14. 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> 2013, Ravenbrook Limited.
|
|
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
|
|
</div>
|
|
</body>
|
|
</html> |