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:
parent
78c80805e8
commit
26cf4ba954
15 changed files with 8205 additions and 6 deletions
14
mps/manual/source/copyright.rst
Normal file
14
mps/manual/source/copyright.rst
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
Copyright and licence
|
||||
=====================
|
||||
|
||||
The Memory Pool System documentation is copyright © 1997–2012 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.**
|
||||
186
mps/manual/source/glossary.rst
Normal file
186
mps/manual/source/glossary.rst
Normal 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
|
||||
|
||||
??
|
||||
|
|
@ -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`
|
||||
|
||||
|
|
|
|||
7
mps/manual/source/pool/index.rst
Normal file
7
mps/manual/source/pool/index.rst
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
Pool reference
|
||||
==============
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
pool-amc
|
||||
7505
mps/manual/source/reference/index.rst
Normal file
7505
mps/manual/source/reference/index.rst
Normal file
File diff suppressed because it is too large
Load diff
47
mps/manual/source/topic/allocation.rst
Normal file
47
mps/manual/source/topic/allocation.rst
Normal 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(&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(&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>
|
||||
109
mps/manual/source/topic/cache.rst
Normal file
109
mps/manual/source/topic/cache.rst
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
.. _topic-cache:
|
||||
|
||||
Allocation caches
|
||||
=================
|
||||
|
||||
|
||||
|
||||
<pre>
|
||||
void *p;
|
||||
Foo *foo;
|
||||
|
||||
res = mps_sac_alloc(&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 < 3)
|
||||
# error "Too many classes!"
|
||||
#endif
|
||||
|
||||
res = mps_sac_create(&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(&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>
|
||||
35
mps/manual/source/topic/error.rst
Normal file
35
mps/manual/source/topic/error.rst
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
.. _topic-error:
|
||||
|
||||
Error handing
|
||||
=============
|
||||
|
||||
|
||||
|
||||
|
||||
<h4>Example</h4>
|
||||
|
||||
<pre>
|
||||
switch(mps_alloc(&(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(&pool, arena, class, params) ) {
|
||||
case MPS_RES_PARAM:
|
||||
bomb("Can't make a pool with those specifications");
|
||||
break;
|
||||
|
||||
/* ... */
|
||||
|
||||
}
|
||||
</pre>
|
||||
5
mps/manual/source/topic/frame.rst
Normal file
5
mps/manual/source/topic/frame.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
.. _topic-frame:
|
||||
|
||||
Allocation frames
|
||||
=================
|
||||
|
||||
15
mps/manual/source/topic/index.rst
Normal file
15
mps/manual/source/topic/index.rst
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
Topic reference
|
||||
===============
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
allocation
|
||||
error
|
||||
scanning
|
||||
moving
|
||||
root
|
||||
cache
|
||||
platform
|
||||
pattern
|
||||
frame
|
||||
4
mps/manual/source/topic/moving.rst
Normal file
4
mps/manual/source/topic/moving.rst
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
.. _topic-moving:
|
||||
|
||||
Moving pools
|
||||
============
|
||||
110
mps/manual/source/topic/pattern.rst
Normal file
110
mps/manual/source/topic/pattern.rst
Normal 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>
|
||||
|
||||
|
||||
5
mps/manual/source/topic/platform.rst
Normal file
5
mps/manual/source/topic/platform.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
.. _topic-platform:
|
||||
|
||||
Supporting MPS on a new platform
|
||||
================================
|
||||
|
||||
26
mps/manual/source/topic/root.rst
Normal file
26
mps/manual/source/topic/root.rst
Normal 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>
|
||||
129
mps/manual/source/topic/scanning.rst
Normal file
129
mps/manual/source/topic/scanning.rst
Normal 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 < length; ++i) {
|
||||
res = mps_fix(ss, &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 < length; ++i) {
|
||||
mps_addr_t ref = array[i];
|
||||
if(MPS_FIX1(ss, ref)) {
|
||||
/* if(((Object*)ref)->type == ScannableType) { */
|
||||
/* You can do something here, but in the end, you must call MPS_FIX2. */
|
||||
res = MPS_FIX2(ss, &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 < length; ++i) {
|
||||
res = MPS_FIX(ss, &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 < length; ++i) {
|
||||
res = MPS_FIX12(ss, &array[i]);
|
||||
if(res != MPS_RES_OK)
|
||||
return res;
|
||||
}
|
||||
MPS_SCAN_END(ss);
|
||||
|
||||
return res;
|
||||
}
|
||||
</pre>
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue