1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-02 10:11:05 -08:00

12% of the way through converting the mps reference manual to sphinx documentation.

Copied from Perforce
 Change: 179792
 ServerID: perforce.ravenbrook.com
This commit is contained in:
Gareth Rees 2012-10-09 17:54:22 +01:00
parent 78c80805e8
commit 26cf4ba954
15 changed files with 8205 additions and 6 deletions

View file

@ -0,0 +1,14 @@
Copyright and licence
=====================
The Memory Pool System documentation is copyright © 19972012 by `Ravenbrook Limited <http://ravenbrook.com>`_. All rights reserved. This is an open source license. Contact Ravenbrook for commercial licensing options.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Redistributions in any form must be accompanied by information on how to obtain complete source code for this software and any accompanying software that uses this software. The source code must either be included in the distribution or be available for no more than the cost of distribution plus a nominal fee, and must be freely redistributable under reasonable conditions. For an executable file, complete source code means the source code for all modules it contains. It does not include source code for modules or files that typically accompany the major components of the operating system on which the executable file runs.
**This software is provided by the copyright holders and contributors "as is" and any express or implied warranties, including, but not limited to, the implied warranties of merchantability, fitness for a particular purpose, or non-infringement, are disclaimed. In no event shall the copyright holders and contributors be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including, but not limited to, procurement of substitute goods or services; loss of use, data, or profits; or business interruption) however caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this software, even if advised of the possibility of such damage.**

View file

@ -0,0 +1,186 @@
.. _glossary:
Glossary
========
.. glossary::
address
??
address space
??
alignment
The address modulus to which all :term:`objects <object>` in
an :term:`object format` must be aligned. That is, if an
alignment of 4 is specified for a format, then the
:term:`address` of any object in that format will always be 0,
modulo 4. In the MPS, an alignment must be a positive power of
2.
allocation frame
??
allocation pattern
??
allocation point
??
arena commit limit
??
block
??
class structure
??
client program
??
constant root
??
data object
??
dead
??
double free
??
format method
??
formatted object
??
formatted root
??
hardware write barrier
??
live
??
object
A contiguous region of memory forming a single logical structure.
object format
?? See the topic :ref:`topic-scanning`.
object pointer
??
pad object
??
page
??
parked
??
pointer
??
pool
??
protectable root
??
ramp pattern
??
rank
??
reference
A link from one :term:`object` to another, usually in the form
of a :term:`pointer`.
reservoir
??
result code
A value returned from an MPS function, represented by the type
:c:type:`mps_res_t`. The result code :c:macro:`MPS_RES_OK`
indicates success; other values indicate errors. See the topic
:ref:`topic-errors`.
root
??
root mode
??
scan function
A function that examines a block of memory to find
:term:`references <reference>` and indicate them to the MPS. A
scan function forms part of an :term:`object format`. See
the topic :ref:`topic-scanning`.
scan state
?? See the topic :ref:`topic-scanning`.
segregated allocation cache
??
size
??
size class
??
table root
??
virtual memory
??

View file

@ -1,22 +1,24 @@
.. Memory Pool System documentation master file, created by
sphinx-quickstart on Tue Oct 9 11:21:17 2012.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to Memory Pool System's documentation!
==============================================
Contents:
Memory Pool System
==================
.. toctree::
:maxdepth: 2
guide/index
topic/index
pool/index
reference/index
glossary
copyright
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View file

@ -0,0 +1,7 @@
Pool reference
==============
.. toctree::
:maxdepth: 2
pool-amc

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,47 @@
.. _topic-allocation:
Allocation
==========
This example seems to be wrong (no function "mps_pool_alloc" in the public interface).
<pre>
{
mps_addr_t new_block;
mps_res_t res;
thingy *tp;
res = mps_pool_alloc(&amp;new_block, pool, sizeof(thingy));
if(res != MPS_RES_OK) return res;
tp = new_block;
/* ... */
}
</pre>
Some :term:`pools <pool>` and :term:`allocation protocols
<allocation protocol>` accept an alignment as an option. This
ensures that objects in the pool or objects allocated observe a
stricter alignment than that of the object format.
<h4>Example</h4>
<pre>
mps_res_t res;
mps_addr_t p;
res = mps_alloc(&amp;p, pool, size);
if(res != MPS_RES_OK) {
/* p hasn't been touched in this case. */
handle error;
}
/* p now contains the result, which is the address of the new block */
/* in this case. */
</pre>

View file

@ -0,0 +1,109 @@
.. _topic-cache:
Allocation caches
=================
<pre>
void *p;
Foo *foo;
res = mps_sac_alloc(&amp;p, sac, FooSIZE, is_in_panic);
if (res != MPS_RES_OK) {
printf("Failed to alloc foo!\n");
exit(1);
}
foo = p;
/* use foo */
mps_sac_free(sac, p, FooSIZE);
</pre>
What does this mean? (from mps_sac_alloc):
The client is responsible for synchronising the access to the
cache, but if the cache decides to access the pool, the MPS will
properly synchronize with any other threads that might be
accessing the same pool.
<pre>
void *p;
Foo *foo;
mps_res_t res;
MPS_SAC_ALLOC_FAST(res, p, sac, FooSIZE, is_in_panic);
if (res != MPS_RES_OK) {
printf("Failed to alloc foo!\n");
exit(1);
}
foo = p;
/* use foo */
MPS_SAC_FREE_FAST(sac, p, FooSIZE);
</pre>
<h4>Example</h4>
<pre>
mps_sac_t sac;
mps_sac_class_s classes[3] = { {8, 38, 1}, {136, 19, 3}, {512, 4, 1} };
#if (MPS_SAC_CLASS_LIMIT &lt; 3)
# error "Too many classes!"
#endif
res = mps_sac_create(&amp;sac, pool, 3, classes);
if (res != MPS_RES_OK) {
printf("Failed to create the allocation cache!");
exit(1);
}
</pre>
<h4>Example</h4>
<pre>
void *p;
Foo *foo;
res = mps_sac_alloc(&amp;p, sac, FooSIZE, is_in_panic);
if (res != MPS_RES_OK) {
printf("Failed to alloc foo!\n");
exit(1);
}
foo = p;
/* use foo */
mps_sac_free(sac, p, FooSIZE);
</pre>
<h4>Example</h4>
<pre>
void *p;
Foo *foo;
mps_res_t res;
MPS_SAC_ALLOC_FAST(res, p, sac, FooSIZE, is_in_panic);
if (res != MPS_RES_OK) {
printf("Failed to alloc foo!\n");
exit(1);
}
foo = p;
/* use foo */
MPS_SAC_FREE_FAST(sac, p, FooSIZE);
</pre>

View file

@ -0,0 +1,35 @@
.. _topic-error:
Error handing
=============
<h4>Example</h4>
<pre>
switch(mps_alloc(&amp;(mps_addr_t)object, pool, size)) {
case MPS_RES_LIMIT:
bomb("The MPS has reached an internal limit");
break;
/* ... */
}
</pre>
<h4>Example</h4>
<pre>
switch( res = mps_pool_create_v(&amp;pool, arena, class, params) ) {
case MPS_RES_PARAM:
bomb("Can't make a pool with those specifications");
break;
/* ... */
}
</pre>

View file

@ -0,0 +1,5 @@
.. _topic-frame:
Allocation frames
=================

View file

@ -0,0 +1,15 @@
Topic reference
===============
.. toctree::
:maxdepth: 2
allocation
error
scanning
moving
root
cache
platform
pattern
frame

View file

@ -0,0 +1,4 @@
.. _topic-moving:
Moving pools
============

View file

@ -0,0 +1,110 @@
.. _topic-pattern:
Allocation patterns
===================
<pre>
{
mps_ap_alloc_pattern_begin(ap, mps_alloc_pattern_ramp());
do_lots_of_work();
mps_ap_alloc_pattern_end(ap, mps_alloc_pattern_ramp());
}
</pre>
<h4>Example</h4>
<pre>
{
mps_ap_alloc_pattern_begin(ap, mps_alloc_pattern_ramp_collect_all());
do_lots_of_work();
mps_ap_alloc_pattern_end(ap, mps_alloc_pattern_ramp_collect_all());
wait_for_collection_statistics_while_doing_other_allocation();
}
</pre>
<h4>Example</h4>
<pre>
{
res = mps_ap_alloc_pattern_begin(ap, mps_alloc_pattern_ramp());
assert(res == mps_res_ok);
do_some_work(); /* Leaves stuff lying around */
res = mps_ap_alloc_pattern_begin(ap, mps_alloc_pattern_ramp());
assert(res == mps_res_ok);
do_some_more_work(); /* Tidies up after itself */
res = mps_ap_alloc_pattern_end(ap, mps_alloc_pattern_ramp());
assert(res == mps_res_ok);
tidy_up_first_work();
res = mps_ap_alloc_pattern_end(ap, mps_alloc_pattern_ramp());
assert(res == mps_res_ok);
}
</pre>
<pre>
{
res = mps_ap_alloc_pattern_begin(ap, mps_alloc_pattern_ramp());
assert(res == mps_res_ok);
do_some_work(); /* Leaves stuff lying around */
res = mps_ap_alloc_pattern_begin(ap, mps_alloc_pattern_ramp());
assert(res == mps_res_ok);
do_some_more_work(); /* Tidies up after itself */
res = mps_ap_alloc_pattern_end(ap, mps_alloc_pattern_ramp());
assert(res == mps_res_ok);
tidy_up_first_work();
res = mps_ap_alloc_pattern_end(ap, mps_alloc_pattern_ramp());
assert(res == mps_res_ok);
}
</pre>
<h4>Example</h4>
<pre>
{
res = mps_ap_alloc_pattern_begin(ap, mps_alloc_pattern_ramp());
assert(res == mps_res_ok);
do_some_work(); /* Leaves stuff lying around */
res = mps_ap_alloc_pattern_begin(ap, mps_alloc_pattern_ramp());
assert(res == mps_res_ok);
res = do_some_more_work(); /* Tidies up after itself */
if(res != mps_res_ok) {
res = mps_ap_alloc_pattern_reset(ap);
assert(res == mps_res_ok);
return;
}
res = mps_ap_alloc_pattern_end(ap, mps_alloc_pattern_ramp());
assert(res == mps_res_ok);
tidy_up_first_work();
res = mps_ap_alloc_pattern_end(ap, mps_alloc_pattern_ramp());
assert(res == mps_res_ok);
}
</pre>

View file

@ -0,0 +1,5 @@
.. _topic-platform:
Supporting MPS on a new platform
================================

View file

@ -0,0 +1,26 @@
.. _topic-root:
Roots
=====
<p><code><a href="#MPS_RM_CONST">MPS_RM_CONST</a></code> is a preprocessor macro defining a constant that can be OR'ed with other <code>MPS_RM_*</code> constants, and passed as the root mode argument to certain root creation functions (<code><a href="#mps_root_create">mps_root_create</a></code>, <code><a href="#mps_root_create_fmt">mps_root_create_fmt</a></code>, <code><a href="#mps_root_create_table">mps_root_create_table</a></code>, <code><a href="#mps_root_create_table_masked">mps_root_create_table_masked</a></code>, <code><a href="#mps_root_create_reg">mps_root_create_reg</a></code> ).</p>
from MPS_RM_PROT:
<p>No page may contain parts of two or more roots with <code><a
href="#MPS_RM_PROT">MPS_RM_PROT</a></code> [how does one prevent
that?]. You mustn't specify <code><a
href="#MPS_RM_PROT">MPS_RM_PROT</a></code> if the client program or
anything other than (this instance of) the MPS is going to protect or
unprotect the relevant pages.</p>
<h4>Internal Notes</h4>
<p>Future meaning: The MPS may place a hardware read and/or write barrier on any pages which any part of the root covers. Format methods and scanning functions (except for the one for this root) may not read or write data in this root. You may specify <code><a href="#MPS_RM_PROT">MPS_RM_PROT</a></code> on a root allocated from the MPS, as long as it's not from a GCd pool. - drj 1997-12-18</p>
<p>This feature is far too technical for most of our clients: we should think about producing some guidelines on how to use it. - pekka 1998-01-27</p>
<p>There may be problems if the client wants the OS to access the root. Lots of OSes can't cope with writing to protected pages. So we'll need to document that caveat too. drj 1998-05-20</p>

View file

@ -0,0 +1,129 @@
.. _topic-scanning:
Scanning
========
<h4>Returned Values</h4>
<p>Returns a result code, see ERROR HANDLING.</p>
<p>If the reference rank of the object being scanned is not <code><a href="#MPS_RANK_AMBIG">MPS_RANK_AMBIG</a></code> then the reference pointed to by <code>ref_io</code> may be modified by <code><a href="#mps_fix">mps_fix</a></code>.</p>
<h4>Description</h4>
<p>This function is the part of the scanning protocol used to indicate references. Scanning functions apply it, or <code><a href="#MPS_FIX12">MPS_FIX12</a></code>, or <code><a href="#MPS_FIX1">MPS_FIX1</a></code> and <code><a href="#MPS_FIX2">MPS_FIX2</a></code> to the references in the object being scanned.</p>
<p>It may only be called from within a scanning function. If it is called within a <code><a href="#MPS_SCAN_BEGIN">MPS_SCAN_BEGIN</a></code> block, <code><a href="#MPS_FIX_CALL">MPS_FIX_CALL</a></code> must be used (yes, really).</p>
<p>This function does not perform any particular operation. The MPS may call scanning functions for a number of reasons, and <code><a href="#mps_fix">mps_fix</a></code> may take different actions depending on those reasons.</p>
<h4>Example</h4>
<pre>
mps_res_t scan_array(mps_ss_t ss, mps_addr_t object, size_t length)
{
size_t i;
mps_res_t res;
mps_addr_t *array = (mps_addr_t *)object;
for(i = 0; i &lt; length; ++i) {
res = mps_fix(ss, &amp;array[i]);
if(res != MPS_RES_OK) return res;
}
return res;
}
</pre>
<h4>Error Handling</h4>
<p>The function returns <code><a href="#MPS_RES_OK">MPS_RES_OK</a></code> if it was successful, in which case the scanning function should continue to scan the rest of the object, applying <code><a href="#mps_fix">mps_fix</a></code> to the remaining references. If <code><a href="#mps_fix">mps_fix</a></code> returns a value other than <code><a href="#MPS_RES_OK">MPS_RES_OK</a></code>, the scanning function must return that value, and may return without scanning further references. Generally, it is better if it returns as soon as possible.</p>
<h4>Example</h4>
<pre>
mps_res_t scan_array(mps_ss_t ss, Array object, size_t length)
{
size_t i;
mps_res_t res;
mps_addr_t *array = (mps_addr_t *)object;
MPS_SCAN_BEGIN(ss)
for(i = 0; i &lt; length; ++i) {
mps_addr_t ref = array[i];
if(MPS_FIX1(ss, ref)) {
/* if(((Object*)ref)-&gt;type == ScannableType) { */
/* You can do something here, but in the end, you must call MPS_FIX2. */
res = MPS_FIX2(ss, &amp;array[i]);
if(res != MPS_RES_OK)
return res;
/* } */
}
}
MPS_SCAN_END(ss);
return res;
}
</pre>
<h4>Example</h4>
<pre>
mps_res_t scan_array(mps_ss_t ss, mps_addr_t object, size_t length) {
size_t i;
mps_res_t res;
mps_addr_t *array = (mps_addr_t *)object;
MPS_SCAN_BEGIN(ss)
for(i = 0; i &lt; length; ++i) {
res = MPS_FIX(ss, &amp;array[i]);
if(res != MPS_RES_OK)
return res;
}
MPS_SCAN_END(ss);
return res;
}
</pre>
<h4>Error Handling</h4>
<p>The macro returns <code><a href="#MPS_RES_OK">MPS_RES_OK</a></code> if it was successful, in which case the scanning function should continue to scan the rest of the object, fixing the remaining references. If <code><a href="#MPS_FIX12">MPS_FIX12</a></code> returns a value other than <code><a href="#MPS_RES_OK">MPS_RES_OK</a></code>, the scanning function must return that value, and may return without scanning further references. Generally, it is better if it returns as soon as possible.</p>
<h4>Example</h4>
<pre>
mps_res_t scan_array(mps_ss_t ss, mps_addr_t object, size_t length)
{
size_t i;
mps_res_t res;
mps_addr_t *array = (mps_addr_t *)object;
MPS_SCAN_BEGIN(ss)
for(i = 0; i &lt; length; ++i) {
res = MPS_FIX12(ss, &amp;array[i]);
if(res != MPS_RES_OK)
return res;
}
MPS_SCAN_END(ss);
return res;
}
</pre>