1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-24 14:30:43 -08:00
emacs/mps/manual/reference/index.html
Richard Brooksby 4bcbc771ba Merging version 1.100 to masters so that we can merge to gg-epcore and send to pekka.
Copied from Perforce
 Change: 30459
 ServerID: perforce.ravenbrook.com
2002-06-24 13:32:06 +01:00

10099 lines
270 KiB
HTML

<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title> Memory Pool System Reference Manual </title>
</head>
<body bgcolor="#FFFFFF" text="#000000" link="#000099" vlink="#660066" alink="#FF0000">
<div align="center">
<p>
<a href="/">Ravenbrook</a> /
<a href="/project/">Projects</a> /
<a href="/project/mps/">Memory Pool System</a> /
<a href="/project/mps/master/">Master Product Sources</a> /
<a href="/project/mps/master/manual/">Product Manuals</a>
</p>
<p><i><a href="/project/mps/">Memory Pool System Project</a></i></p>
<hr />
<h1> Memory Pool System Reference Manual </h1>
<address>
<a href="mailto:rb@ravenbrook.com">Richard Brooksby</a>,
<a href="http://www.ravenbrook.com/">Ravenbrook Limited</a>,
2002-05-28
</address>
</div>
<h2> Contents </h2>
<ul>
<li> <a href="#section-1">1. Introduction</a> </li>
<li> <a href="#section-2">2. Overview</a> </li>
<li> <a href="#section-3">3. Reference</a> </li>
<li> <a href="#section-4">4. Undocumented Symbols</a> </li>
<li> <a href="#section-A">A. References</a> </li>
<li> <a href="#section-B">B. Document History</a> </li>
<li> <a href="#section-C">C. Copyright and License</a> </li>
</ul>
<h2> <a id="section-1" name="section-1">1. Introduction</a> </h2>
<p>This is the reference manual for the Memory Pool System.</p>
<p><strong>This document is quite incomplete. At present it consists
simply of reference descriptions of a number of MPS symbols (<a
href="#section-3">section 3</a>). Many MPS symbols are not described
here (see <a href="#section-4">section 4</a> for a list). There are
also no overview or protocol-oriented sections.</strong></p>
<h2> <a id="section-2" name="section-2">2. Overview</a> </h2>
<h2> <a id="section-3" name="section-3">3. Reference</a> </h2>
<ul>
<li> <code><a href="#MPS_ARCH_AL">MPS_ARCH_AL</a></code> </li>
<li> function <code><a href="#mps_fix">mps_fix</a></code> </li>
<li> macro <code><a href="#MPS_FIX1">MPS_FIX1</a></code> </li>
<li> macro <code><a href="#MPS_FIX12">MPS_FIX12</a></code> </li>
<li> macro <code><a href="#MPS_FIX2">MPS_FIX2</a></code> </li>
<li> macro <code><a href="#MPS_FIX_CALL">MPS_FIX_CALL</a></code> </li>
<li> constant <code><a href="#MPS_RES_LIMIT">MPS_RES_LIMIT</a></code> </li>
<li> constant <code><a href="#MPS_RES_MEMORY">MPS_RES_MEMORY</a></code> </li>
<li> <code><a href="#MPS_RES_PARAM">MPS_RES_PARAM</a></code> </li>
<li> <code><a href="#MPS_RM_CONST">MPS_RM_CONST</a></code> </li>
<li> <code><a href="#MPS_RM_PROT">MPS_RM_PROT</a></code> </li>
<li> function <code><a href="#mps_sac_alloc">mps_sac_alloc</a></code> </li>
<li> macro <code><a href="#MPS_SAC_ALLOC_FAST">MPS_SAC_ALLOC_FAST</a></code> </li>
<li> constant <code><a href="#MPS_SAC_CLASS_LIMIT">MPS_SAC_CLASS_LIMIT</a></code> </li>
<li> function <code><a href="#mps_sac_free">mps_sac_free</a></code> </li>
<li> macro <code><a href="#MPS_SAC_FREE_FAST">MPS_SAC_FREE_FAST</a></code> </li>
<li> macro <code><a href="#MPS_SCAN_BEGIN">MPS_SCAN_BEGIN</a></code> </li>
<li> macro <code><a href="#MPS_SCAN_END">MPS_SCAN_END</a></code> </li>
<li> type <code><a href="#MPS_T_WORD">MPS_T_WORD</a></code> </li>
<li> constant <code><a href="#MPS_WORD_SHIFT">MPS_WORD_SHIFT</a></code> </li>
<li> constant <code><a href="#MPS_WORD_WIDTH">MPS_WORD_WIDTH</a></code> </li>
<li> type <code><a href="#mps_addr_t">mps_addr_t</a></code> </li>
<li> type <code><a href="#mps_align_t">mps_align_t</a></code> </li>
<li> function <code><a href="#mps_alloc">mps_alloc</a></code> </li>
<li> <code><a href="#mps_alloc_pattern_ramp">mps_alloc_pattern_ramp</a></code> </li>
<li> <code><a href="#mps_alloc_pattern_ramp_collect_all">mps_alloc_pattern_ramp_collect_all</a></code> </li>
<li> <code><a href="#mps_amc_apply">mps_amc_apply</a></code> </li>
<li> <code><a href="#mps_ap_alloc_pattern_begin">mps_ap_alloc_pattern_begin</a></code> </li>
<li> <code><a href="#mps_ap_alloc_pattern_end">mps_ap_alloc_pattern_end</a></code> </li>
<li> function <code><a href="#mps_ap_alloc_pattern_reset">mps_ap_alloc_pattern_reset</a></code> </li>
<li> function <code><a href="#mps_ap_frame_pop">mps_ap_frame_pop</a></code> </li>
<li> function <code><a href="#mps_ap_frame_push">mps_ap_frame_push</a></code> </li>
<li> function <code><a href="#mps_arena_clamp">mps_arena_clamp</a></code> </li>
<li> function <code><a href="#mps_arena_class_cl">mps_arena_class_cl</a></code> </li>
<li> type <code><a href="#mps_arena_class_t">mps_arena_class_t</a></code> </li>
<li> function <code><a href="#mps_arena_class_vm">mps_arena_class_vm</a></code> </li>
<li> function <code><a href="#mps_arena_class_vmnz">mps_arena_class_vmnz</a></code> </li>
<li> function <code><a href="#mps_arena_collect">mps_arena_collect</a></code> </li>
<li> function <code><a href="#mps_arena_commit_limit">mps_arena_commit_limit</a></code> </li>
<li> function <code><a href="#mps_arena_commit_limit_set">mps_arena_commit_limit_set</a></code> </li>
<li> Function <code><a href="#mps_arena_committed">mps_arena_committed</a></code> </li>
<li> function <code><a href="#mps_arena_create">mps_arena_create</a></code> </li>
<li> function <code><a href="#mps_arena_create_v">mps_arena_create_v</a></code> </li>
<li> function <code><a href="#mps_arena_formatted_objects_walk">mps_arena_formatted_objects_walk</a></code> </li>
<li> function <code><a href="#mps_arena_park">mps_arena_park</a></code> </li>
<li> function <code><a href="#mps_arena_release">mps_arena_release</a></code> </li>
<li> function <code><a href="#mps_arena_roots_walk">mps_arena_roots_walk</a></code> </li>
<li> function <code><a href="#mps_arena_spare_commit_limit">mps_arena_spare_commit_limit</a></code> </li>
<li> function <code><a href="#mps_arena_spare_commit_limit_set">mps_arena_spare_commit_limit_set</a></code> </li>
<li> function <code><a href="#mps_arena_spare_committed">mps_arena_spare_committed</a></code> </li>
<li> function <code><a href="#mps_bool_t">mps_bool_t</a></code> </li>
<li> function <code><a href="#mps_class_amc">mps_class_amc</a></code> </li>
<li> function <code><a href="#mps_class_mvff">mps_class_mvff</a></code> </li>
<li> function <code><a href="#mps_class_snc">mps_class_snc</a></code> </li>
<li> <code><a href="#mps_class_mvt">mps_class_mvt</a></code> </li>
<li> Type <code><a href="#mps_class_t">mps_class_t</a></code> </li>
<li> function <code><a href="#mps_finalize">mps_finalize</a></code> </li>
<li> type <code><a href="#mps_fmt_A_s">mps_fmt_A_s</a></code> </li>
<li> type <code><a href="#mps_fmt_A_t">mps_fmt_A_t</a></code> </li>
<li> type <code><a href="#mps_fmt_B_s">mps_fmt_B_s</a></code> </li>
<li> Type <code><a href="#mps_fmt_B_t">mps_fmt_B_t</a></code> </li>
<li> type <code><a href="#mps_fmt_auto_header_s">mps_fmt_auto_header_s</a></code> </li>
<li> type <code><a href="#mps_fmt_class_t">mps_fmt_class_t</a></code> </li>
<li> type <code><a href="#mps_fmt_copy_t">mps_fmt_copy_t</a></code> </li>
<li> function <code><a href="#mps_fmt_create_A">mps_fmt_create_A</a></code> </li>
<li> function <code><a href="#mps_fmt_create_B">mps_fmt_create_B</a></code> </li>
<li> function <code><a href="#mps_fmt_create_auto_header">mps_fmt_create_auto_header</a></code> </li>
<li> type <code><a href="#mps_fmt_fwd_t">mps_fmt_fwd_t</a></code> </li>
<li> type <code><a href="#mps_fmt_isfwd_t">mps_fmt_isfwd_t</a></code> </li>
<li> type <code><a href="#mps_fmt_pad_t">mps_fmt_pad_t</a></code> </li>
<li> type <code><a href="#mps_fmt_scan_t">mps_fmt_scan_t</a></code> </li>
<li> type <code><a href="#mps_fmt_skip_t">mps_fmt_skip_t</a></code> </li>
<li> type <code><a href="#mps_fmt_t">mps_fmt_t</a></code> </li>
<li> type <code><a href="#mps_formatted_objects_stepper_t">mps_formatted_objects_stepper_t</a></code> </li>
<li> function <code><a href="#mps_free">mps_free</a></code> </li>
<li> function <code><a href="#mps_lib_memcmp">mps_lib_memcmp</a></code> </li>
<li> function <code><a href="#mps_lib_memcpy">mps_lib_memcpy</a></code> </li>
<li> function <code><a href="#mps_lib_memset">mps_lib_memset</a></code> </li>
<li> <code><a href="#mps_lib_telemetry_control">mps_lib_telemetry_control</a></code> </li>
<li> function <code><a href="#mps_message_discard">mps_message_discard</a></code> </li>
<li> function <code><a href="#mps_message_finalization_ref">mps_message_finalization_ref</a></code> </li>
<li> function <code><a href="#mps_message_gc_condemned_size">mps_message_gc_condemned_size</a></code> </li>
<li> function <code><a href="#mps_message_gc_live_size">mps_message_gc_live_size</a></code> </li>
<li> function <code><a href="#mps_message_gc_not_condemned_size">mps_message_gc_not_condemned_size</a></code> </li>
<li> function <code><a href="#mps_message_get">mps_message_get</a></code> </li>
<li> <code><a href="#mps_message_poll">mps_message_poll</a></code> </li>
<li> function <code><a href="#mps_message_queue_type">mps_message_queue_type</a></code> </li>
<li> type <code><a href="#mps_message_t">mps_message_t</a></code> </li>
<li> function <code><a href="#mps_message_type">mps_message_type</a></code> </li>
<li> function <code><a href="#mps_message_type_disable">mps_message_type_disable</a></code> </li>
<li> function <code><a href="#mps_message_type_enable">mps_message_type_enable</a></code> </li>
<li> function <code><a href="#mps_message_type_finalization">mps_message_type_finalization</a></code> </li>
<li> function <code><a href="#mps_message_type_gc">mps_message_type_gc</a></code> </li>
<li> type <code><a href="#mps_message_type_t">mps_message_type_t</a></code> </li>
<li> function <code><a href="#mps_pool_check_fenceposts">mps_pool_check_fenceposts</a></code> </li>
<li> structure <code><a href="#mps_pool_debug_option_s">mps_pool_debug_option_s</a></code> </li>
<li> function <code><a href="#mps_rank_ambig">mps_rank_ambig</a></code> </li>
<li> function <code><a href="#mps_rank_exact">mps_rank_exact</a></code> </li>
<li> type <code><a href="#mps_rank_t">mps_rank_t</a></code> </li>
<li> function <code><a href="#mps_rank_weak">mps_rank_weak</a></code> </li>
<li> type <code><a href="#mps_reg_scan_t">mps_reg_scan_t</a></code> </li>
<li> type <code><a href="#mps_res_t">mps_res_t</a></code> </li>
<li> function <code><a href="#mps_root_create">mps_root_create</a></code> </li>
<li> function <code><a href="#mps_root_create_fmt">mps_root_create_fmt</a></code> </li>
<li> function <code><a href="#mps_root_create_reg">mps_root_create_reg</a></code> </li>
<li> function <code><a href="#mps_root_create_table">mps_root_create_table</a></code> </li>
<li> function <code><a href="#mps_root_create_table_masked">mps_root_create_table_masked</a></code> </li>
<li> type <code><a href="#mps_root_scan_t">mps_root_scan_t</a></code> </li>
<li> type <code><a href="#mps_roots_stepper_t">mps_roots_stepper_t</a></code> </li>
<li> type <code><a href="#mps_sac_class_s">mps_sac_class_s</a></code> </li>
<li> function <code><a href="#mps_sac_create">mps_sac_create</a></code> </li>
<li> function <code><a href="#mps_sac_destroy">mps_sac_destroy</a></code> </li>
<li> function <code><a href="#mps_sac_flush">mps_sac_flush</a></code> </li>
<li> type <code><a href="#mps_sac_t">mps_sac_t</a></code> </li>
<li> function <code><a href="#mps_stack_scan_ambig">mps_stack_scan_ambig</a></code> </li>
<li> function <code><a href="#mps_telemetry_control">mps_telemetry_control</a></code> </li>
<li> function <code><a href="#mps_telemetry_flush">mps_telemetry_flush</a></code> </li>
<li> function <code><a href="#mps_telemetry_intern">mps_telemetry_intern</a></code> </li>
<li> function <code><a href="#mps_telemetry_label">mps_telemetry_label</a></code> </li>
<li> type <code><a href="#mps_thr_t">mps_thr_t</a></code> </li>
</ul>
<h3><code><a id="MPS_ARCH_AL" name="MPS_ARCH_AL">MPS_ARCH_AL</a></code></h3>
<h4>Name</h4>
<p><code><a href="#MPS_ARCH_AL">MPS_ARCH_AL</a></code></p>
<h4>Summary</h4>
<p><code><a href="#MPS_ARCH_AL">MPS_ARCH_AL</a></code> is a C
preprocessor macro that indicates, if defined, that the target
processor architecture of the compilation is a member of the DEC Alpha
family. It is defined, if appropriate, by "mpstd.h".</p>
<h4>Associated Protocols</h4>
<p>None.</p>
<h4>Resources</h4>
<p>mpstd.h.</p>
<h4>Description</h4>
<p>See summary.</p>
<h4>Example</h4>
<pre>
#ifdef MPS_ARCH_AL
typedef struct RegisterFile {
unsigned long v0;
unsigned long t0, t1, t2, t3, t4, t5, t6, t7;
unsigned long s0, s1, s2, s3, s4, s5;
unsigned long fp;
unsigned long a0, a1, a2, a3, a4, a5;
unsigned long t8, t9, t10, t11;
unsigned long ra;
unsigned long t12;
unsigned long at, gp, sp, zero;
unsigned long fir;
unsigned psr;
} RegisterFile;
#endif /* MPS_ARCH_AL */
</pre>
<h4>Error Handling</h4>
<p>Not applicable.</p>
<h4>See Also</h4>
<p>
<code>MPS_PF_*</code>,
<code>MPS_OS_*</code>,
<code>MPS_BUILD_*</code>,
<code>MPS_ARCH_*</code></p>
<h4>Notes</h4>
<h4>Internal Notes</h4>
<p>I'm not sure that the user ought to be using these symbols. GavinM
1997-05-01</p>
<h3>function <code><a id="mps_fix" name="mps_fix">mps_fix</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_fix">mps_fix</a></code></p>
<h4>Summary</h4>
<p>The function <code><a href="#mps_fix">mps_fix</a></code> is the
part of the scanning protocol used to indicate references to the
MPS. It may only be called from within a scanning function.</p>
<h4>Associated Protocols</h4>
<p>Scanning.</p>
<h4>Syntax</h4>
<p><code>mps_res_t mps_fix(mps_ss_t mps_ss, mps_addr_t *ref_io)</code></p>
<h4>Arguments</h4>
<p><code>mps_ss</code> the scan state argument that was passed to the
scanning function</p>
<p><code>ref_io</code> a pointer to a reference within the object
being scanned</p>
<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>Resources</h4>
<p>mps.h</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> tothe 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>See Also</h4>
<p>
<code><a href="#mps_ss_t">mps_ss_t</a></code>,
<code><a href="#mps_root_scan_t">mps_root_scan_t</a></code>,
<code><a href="#mps_fmt_scan_t">mps_fmt_scan_t</a></code>,
<code><a href="#mps_reg_scan_t">mps_reg_scan_t</a></code>,
<code><a href="#MPS_SCAN_BEGIN">MPS_SCAN_BEGIN</a></code>,
<code><a href="#MPS_SCAN_END">MPS_SCAN_END</a></code>,
<code><a href="#MPS_FIX12">MPS_FIX12</a></code>,
<code><a href="#MPS_FIX1">MPS_FIX1</a></code>,
<code><a href="#MPS_FIX2">MPS_FIX2</a></code>,
<code><a href="#MPS_FIX_CALL">MPS_FIX_CALL</a></code>
</p>
<h3>macro <code><a id="MPS_FIX1" name="MPS_FIX1">MPS_FIX1</a></code></h3>
<h4>Name</h4>
<p><code><a href="#MPS_FIX1">MPS_FIX1</a></code></p>
<h4>Summary</h4>
<p>The macro <code><a href="#MPS_FIX1">MPS_FIX1</a></code> is the part
of the scanning protocol used to indicate references to the MPS. It
may only be used from within <code><a
href="#MPS_SCAN_BEGIN">MPS_SCAN_BEGIN</a></code> and <code><a
href="#MPS_SCAN_END">MPS_SCAN_END</a></code>.</p>
<h4>Associated Protocols</h4>
<p>Format.</p>
<h4>Syntax</h4>
<p><code>MPS_FIX1(mps_ss, ref)</code></p>
<h4>Arguments</h4>
<p><code><a href="#mps_ss">mps_ss</a></code> the scan state argument
that was passed to the scanning function</p>
<p><code>ref</code> a reference within the object being scanned, type
<code><a href="#mps_addr_t">mps_addr_t</a></code></p>
<h4>Returned Values</h4>
<p>Returns a truth value (type <code><a
href="#mps_bool_t">mps_bool_t</a></code>) indicating whether the
reference is likely to be interesting to the MPS.</p>
<h4>Resources</h4>
<p>mps.h.</p>
<h4>Description</h4>
<p><code><a href="#MPS_FIX1">MPS_FIX1</a></code> and <code><a
href="#MPS_FIX2">MPS_FIX2</a></code> are a trick to speed up scanning
by splitting <code><a href="#MPS_FIX12">MPS_FIX12</a></code> into two
macros. <code><a href="#MPS_FIX1">MPS_FIX1</a></code> is a fast test
to see if the reference is likely to be interesting to the MPS; if it
returns false, the scanner can proceed to the next reference. If it
returns true, the scan method must invoke <code><a
href="#MPS_FIX2">MPS_FIX2</a></code>, which does the actual
fixing.</p>
<p>This macro may only be used in code textually between <code><a
href="#MPS_SCAN_BEGIN">MPS_SCAN_BEGIN</a></code> and <code><a
href="#MPS_SCAN_END">MPS_SCAN_END</a></code>.</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>See Also</h4>
<p>
<code><a href="#MPS_FIX12">MPS_FIX12</a></code>,
<code><a href="#MPS_FIX2">MPS_FIX2</a></code>,
<code><a href="#mps_fix">mps_fix</a></code>,
<code><a href="#mps_ss_t">mps_ss_t</a></code>,
<code><a href="#mps_root_scan_t">mps_root_scan_t</a></code>,
<code><a href="#mps_fmt_scan_t">mps_fmt_scan_t</a></code>,
<code><a href="#mps_reg_scan_t">mps_reg_scan_t</a></code>,
<code><a href="#MPS_SCAN_BEGIN">MPS_SCAN_BEGIN</a></code>,
<code><a href="#MPS_SCAN_END">MPS_SCAN_END</a></code>,
<code><a href="#MPS_FIX_CALL">MPS_FIX_CALL</a></code></p>
<h3>macro <code><a id="MPS_FIX12" name="MPS_FIX12">MPS_FIX12</a></code></h3>
<h4>Name</h4>
<p><code><a href="#MPS_FIX12">MPS_FIX12</a></code></p>
<h4>Summary</h4>
<p>The macro <code><a href="#MPS_FIX12">MPS_FIX12</a></code> is the
part of the scanning protocol used to indicate references to the
MPS. It may only be used from within <code><a
href="#MPS_SCAN_BEGIN">MPS_SCAN_BEGIN</a></code> and <code><a
href="#MPS_SCAN_END">MPS_SCAN_END</a></code>.</p>
<h4>Associated Protocols</h4>
<p>Scanning.</p>
<h4>Syntax</h4>
<p><code>MPS_FIX12(mps_ss, ref_io);</code></p>
<h4>Arguments</h4>
<p><code><a href="#mps_ss">mps_ss</a></code> the scan state argument that was passed to the scanning function</p>
<p><code>ref_io</code> a pointer to a reference within the object
being scanned, type <code>mps_addr_t *</code></p>
<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_FIX12">MPS_FIX12</a></code>.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>This macro is used in the scanning protocol to indicate
references. Scanning functions apply it or <code><a
href="#mps_fix">mps_fix</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 used in code textually between <code><a
href="#MPS_SCAN_BEGIN">MPS_SCAN_BEGIN</a></code> and <code><a
href="#MPS_SCAN_END">MPS_SCAN_END</a></code>.</p>
<p>It is permitted for the reference (<code>*ref_io</code>) to point
outside the MPS arena being scanned, or to be NULL; in that case, it
is simply ignored.</p>
<p>This macro 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;
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>See Also</h4>
<p>
<code><a href="#mps_fix">mps_fix</a></code>,
<code><a href="#mps_ss_t">mps_ss_t</a></code>,
<code><a href="#mps_root_scan_t">mps_root_scan_t</a></code>,
<code><a href="#mps_fmt_scan_t">mps_fmt_scan_t</a></code>,
<code><a href="#mps_reg_scan_t">mps_reg_scan_t</a></code>,
<code><a href="#MPS_SCAN_BEGIN">MPS_SCAN_BEGIN</a></code>,
<code><a href="#MPS_SCAN_END">MPS_SCAN_END</a></code>,
<code><a href="#MPS_FIX1">MPS_FIX1</a></code>,
<code><a href="#MPS_FIX2">MPS_FIX2</a></code>,
<code><a href="#MPS_FIX_CALL">MPS_FIX_CALL</a></code></p>
<h4>Notes</h4>
<p><code><a href="#MPS_FIX12">MPS_FIX12</a></code> is so called, as it basically performs the work of both <code><a href="#MPS_FIX1">MPS_FIX1</a></code> and <code><a href="#MPS_FIX2">MPS_FIX2</a></code>.</p>
<h3>macro <code><a id="MPS_FIX2" name="MPS_FIX2">MPS_FIX2</a></code></h3>
<h4>Name</h4>
<p><code><a href="#MPS_FIX2">MPS_FIX2</a></code></p>
<h4>Summary</h4>
<p>The macro <code><a href="#MPS_FIX2">MPS_FIX2</a></code>, together with <code><a href="#MPS_FIX1">MPS_FIX1</a></code>, is the part of the scanning protocol used to indicate references to the MPS. It may only be used from within <code><a href="#MPS_SCAN_BEGIN">MPS_SCAN_BEGIN</a></code> and <code><a href="#MPS_SCAN_END">MPS_SCAN_END</a></code>.</p>
<h4>Associated Protocols</h4>
<p>Scanning.</p>
<h4>Syntax</h4>
<p><code>MPS_FIX2(mps_ss, ref_io);</code></p>
<h4>Arguments</h4>
<p><code><a href="#mps_ss">mps_ss</a></code> the scan state argument
that was passed to the scanning function</p>
<p><code>ref_io</code> a pointer to a reference within the object
being scanned, type <code>mps_addr_t *</code></p>
<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_FIX2">MPS_FIX2</a></code>.</p>
<h4>Resources</h4>
<p>mps.h.</p>
<h4>Description</h4>
<p><code><a href="#MPS_FIX1">MPS_FIX1</a></code> and <code><a
href="#MPS_FIX2">MPS_FIX2</a></code> are a trick to speed up scanning
by splitting <code><a href="#MPS_FIX12">MPS_FIX12</a></code> into two
macros. <code><a href="#MPS_FIX1">MPS_FIX1</a></code> is a fast test
to see if the reference is likely to be interesting to the MPS; if it
returns false, the scanner can proceed to the next reference. If it
returns true, the scan method must invoke <code><a
href="#MPS_FIX2">MPS_FIX2</a></code>, which does the actual
fixing.</p>
<p>This macro may only be used in code textually between <code><a href="#MPS_SCAN_BEGIN">MPS_SCAN_BEGIN</a></code> and <code><a href="#MPS_SCAN_END">MPS_SCAN_END</a></code>.</p>
<p>This macro does not perform any particular operation. The MPS may call scanning functions for a number of reasons, and <code><a href="#MPS_FIX2">MPS_FIX2</a></code> may take different actions depending on those reasons.</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>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_FIX2">MPS_FIX2</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>See Also</h4>
<p>
<code><a href="#MPS_FIX12">MPS_FIX12</a></code>,
<code><a href="#MPS_FIX1">MPS_FIX1</a></code>,
<code><a href="#mps_fix">mps_fix</a></code>,
<code><a href="#mps_ss_t">mps_ss_t</a></code>,
<code><a href="#mps_root_scan_t">mps_root_scan_t</a></code>,
<code><a href="#mps_fmt_scan_t">mps_fmt_scan_t</a></code>,
<code><a href="#mps_reg_scan_t">mps_reg_scan_t</a></code>,
<code><a href="#MPS_SCAN_BEGIN">MPS_SCAN_BEGIN</a></code>,
<code><a href="#MPS_SCAN_END">MPS_SCAN_END</a></code>,
<code><a href="#MPS_FIX_CALL">MPS_FIX_CALL</a></code></p>
<h3>macro <code><a id="MPS_FIX_CALL" name="MPS_FIX_CALL">MPS_FIX_CALL</a></code></h3>
<h4>Name</h4>
<p><code><a href="#MPS_FIX_CALL">MPS_FIX_CALL</a></code></p>
<h4>Summary</h4>
<p><code><a href="#MPS_FIX_CALL">MPS_FIX_CALL</a></code> is used to call a scanning function from within <code><a href="#MPS_SCAN_BEGIN">MPS_SCAN_BEGIN</a></code> and <code><a href="#MPS_SCAN_END">MPS_SCAN_END</a></code>.</p>
<h4>Associated Protocols</h4>
<p>Scanning.</p>
<h4>Syntax</h4>
<p><code>MPS_FIX_CALL(ss, call);</code></p>
<h4>Arguments</h4>
<p><code><a href="#mps_ss">mps_ss</a></code> the scan state argument that was passed to the scanning function</p>
<p><code>call</code> an expression (containing a call to a scanning function)</p>
<h4>Returned Values</h4>
<p>None.</p>
<h4>Resources</h4>
<p>mps.h.</p>
<h4>Description</h4>
<p>When using the <code><a
href="#MPS_SCAN_BEGIN">MPS_SCAN_BEGIN</a></code> and <code><a
href="#MPS_SCAN_END">MPS_SCAN_END</a></code> macros, you can't
directly call a separate function to do part of the scanning, because
between <code><a href="#MPS_SCAN_BEGIN">MPS_SCAN_BEGIN</a></code> and
<code><a href="#MPS_SCAN_END">MPS_SCAN_END</a></code>, the
<code>scan_state</code> parameter is in a strange state, so you
shouldn't pass it as an argument to a function. However, if you
really want to do it (say, because you have an embedded structure
shared between two scan methods), you can pass the scan state
correctly using <code><a
href="#MPS_FIX_CALL">MPS_FIX_CALL</a></code>.</p>
<p>Note that you must receive the return value of the scanning
function called, and pass it on as described in the ERROR HANDLING
section.</p>
<h4>Example</h4>
<pre>
mps_res_t foo_scan(mps_ss_t scan_state, mps_addr_t base, mps_addr_t limit)
{
Object *obj;
Object *obj_limit;
mps_res_t res;
obj_limit = limit;
MPS_SCAN_BEGIN(scan_state)
for(obj = base; obj &lt; obj_limit; obj++) {
if(MPS_FIX12(scan_state, &amp;obj-&gt;left) != MPS_RES_OK)
return res;
MPS_FIX_CALL(scan_state,
res = scan_data(scan_state, &amp;obj-&gt;data));
if(res != MPS_RES_OK) return res;
if(MPS_FIX12(scan_state, &amp;obj-&gt;right) != MPS_RES_OK)
return res;
}
MPS_SCAN_END(scan_state);
return MPS_RES_OK;
}
</pre>
<h4>Error Handling</h4>
<p>You must receive the return value of the function called. Like all
scanning functions, itreturns <code><a
href="#MPS_RES_OK">MPS_RES_OK</a></code> if it was successful, in
which case the caller should continue to scan the rest of the object,
fixing the remaining references. If it returns a value other
than<code><a href="#MPS_RES_OK">MPS_RES_OK</a></code>, the calling
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>See Also</h4>
<p>
<code><a href="#mps_fix">mps_fix</a></code>,
<code><a href="#mps_ss_t">mps_ss_t</a></code>,
<code><a href="#mps_root_scan_t">mps_root_scan_t</a></code>,
<code><a href="#mps_fmt_scan_t">mps_fmt_scan_t</a></code>,
<code><a href="#mps_reg_scan_t">mps_reg_scan_t</a></code>,
<code><a href="#MPS_SCAN_BEGIN">MPS_SCAN_BEGIN</a></code>,
<code><a href="#MPS_SCAN_END">MPS_SCAN_END</a></code>,
<code><a href="#MPS_FIX12">MPS_FIX12</a></code>,
<code><a href="#MPS_FIX1">MPS_FIX1</a></code>,
<code><a href="#MPS_FIX2">MPS_FIX2</a></code></p>
<h3>constant <code><a id="MPS_RES_LIMIT" name="MPS_RES_LIMIT">MPS_RES_LIMIT</a></code></h3>
<h4>Name</h4>
<p><code><a href="#MPS_RES_LIMIT">MPS_RES_LIMIT</a></code></p>
<h4>Summary</h4>
<p><code><a href="#MPS_RES_LIMIT">MPS_RES_LIMIT</a></code> is a result
code, indicating that an operation failed because an internal limit
was reached.</p>
<h4>Resources</h4>
<p>mps.h.</p>
<h4>Description</h4>
<p>This result code is returned if an operation could not be completed
as requested because of an internal limitation of the MPS. The precise
meaning depends on the function that returned the code. Refer to the
documentation of that function for details.</p>
<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>See Also</h4>
<p>
<code><a href="#mps_res_t">mps_res_t</a></code></p>
<h3>constant <code><a id="MPS_RES_MEMORY" name="MPS_RES_MEMORY">MPS_RES_MEMORY</a></code></h3>
<h4>Name</h4>
<p><code><a href="#MPS_RES_MEMORY">MPS_RES_MEMORY</a></code></p>
<h4>Summary</h4>
<p><code><a href="#MPS_RES_MEMORY">MPS_RES_MEMORY</a></code> is a result code, indicating that an operation failed because it ran out of memory.</p>
<h4>Associated Protocols</h4>
<p>All.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>This result code is returned if an operation could not be completed
because there wasn't enough memory available. You need to deallocate
something or allow the garbage collector to reclaim something to free
enough memory, or expand the arena (if you're using an arena for which
that does not happen automatically).</p>
<p>Note that failing to acquire enough memory because the arena commit
limit would have been exceeded is indicated by returning <code><a
href="#MPS_RES_COMMIT_LIMIT">MPS_RES_COMMIT_LIMIT</a></code>, not
<code><a href="#MPS_RES_MEMORY">MPS_RES_MEMORY</a></code>.</p>
<p>Note that running out of address space (as might happen in virtual
memory systems) is indicated by returning <code><a
href="#MPS_RES_RESOURCE">MPS_RES_RESOURCE</a></code>, not <code><a
href="#MPS_RES_MEMORY">MPS_RES_MEMORY</a></code>.</p>
<h4>Example</h4>
<h4>See Also</h4>
<p>
<code><a href="#mps_res_t">mps_res_t</a></code>,
<code><a href="#MPS_RES_RESOURCE">MPS_RES_RESOURCE</a></code>,
<code><a
href="#MPS_RES_COMMIT_LIMIT">MPS_RES_COMMIT_LIMIT</a></code></p>
<h3><code><a id="MPS_RES_PARAM" name="MPS_RES_PARAM">MPS_RES_PARAM</a></code></h3>
<h4>Name</h4>
<p><code><a href="#MPS_RES_PARAM">MPS_RES_PARAM</a></code></p>
<h4>Summary</h4>
<p><code><a href="#MPS_RES_PARAM">MPS_RES_PARAM</a></code> is a result
code, indicating that an operation failed because an invalid parameter
was specified for the operation.</p>
<h4>Associated Protocols</h4>
<p>All.</p>
<h4>Type</h4>
<p><code><a href="#mps_res_t">mps_res_t</a></code></p>
<h4>Resources</h4>
<p>mps.h.</p>
<h4>Description</h4>
<p>This result code is returned if an operation could not be completed
as requested because an invalid parameter was specified for the
operation. The precise meaning depends on the function that returned
the code. Refer to the documentation of that function for details.</p>
<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>
<h4>See Also</h4>
<p>
<code><a href="#mps_res_t">mps_res_t</a></code></p>
<h4>Notes</h4>
<h4>Internal Notes</h4>
<h3><code><a id="MPS_RM_CONST" name="MPS_RM_CONST">MPS_RM_CONST</a></code></h3>
<h4>Name</h4>
<p><code><a href="#MPS_RM_CONST">MPS_RM_CONST</a></code></p>
<h4>Summary</h4>
<p><code><a href="#MPS_RM_CONST">MPS_RM_CONST</a></code> is a constant used in root mode arguments to indicate constant roots.</p>
<h4>Associated Protocols</h4>
<p>Root.</p>
<h4>Type</h4>
<p>Integral constant.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<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>
<p>Passing <code><a href="#MPS_RM_CONST">MPS_RM_CONST</a></code> means
that the client program will not change the root after it is
declared. I.e., scanning the root will produce the same set of
references every time. Furthermore, for formatted and table roots, the
client program may not write to the root at all.</p>
<h4>Example</h4>
<pre>
res = mps_root_create_table(&amp;mmRoot,
arena,
MPS_RANK_EXACT,
MPS_RM_CONST,
(mps_addr_t)&amp;Objects,
rootCOUNT);
</pre>
<h4>See Also</h4>
<p>
<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>
<h4>Notes</h4>
<h4>Internal Notes</h4>
<p>Currently ignored. -- drj 1997-12-18.</p>
<h3><code><a id="MPS_RM_PROT" name="MPS_RM_PROT">MPS_RM_PROT</a></code></h3>
<h4>Name</h4>
<p><code><a href="#MPS_RM_PROT">MPS_RM_PROT</a></code></p>
<h4>Summary</h4>
<p><code><a href="#MPS_RM_PROT">MPS_RM_PROT</a></code> is a constant used in root mode arguments to indicate protectable roots.</p>
<h4>Associated Protocols</h4>
<p>Root.</p>
<h4>Type</h4>
<p>Integral constant.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p><code><a href="#MPS_RM_PROT">MPS_RM_PROT</a></code> is a
preprocessor macro defining a constant that can be OR'ed with other
<code>MPS_RM_*</code> contants, and passed as the root mode argument
to certain root creation functions (<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>).</p>
<p>Passing <code><a href="#MPS_RM_PROT">MPS_RM_PROT</a></code> means
that the MPS may place a hardware write barrier on any pages which any
part of the root covers. Format methods and any scanning function
(except for the one for this root) may not write data in this
root. They may read it.</p>
<p>You mustn't specify <code><a
href="#MPS_RM_PROT">MPS_RM_PROT</a></code> on a root allocated from
the MPS.</p>
<h4>Example</h4>
<pre>
res = mps_root_create_table(&amp;mmRoot,
arena,
MPS_RANK_EXACT,
MPS_RM_PROT,
(mps_addr_t)&amp;Objects,
rootCOUNT);
</pre>
<h4>See Also</h4>
<p>
<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>.</p>
<h4>Notes</h4>
<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 thisroot) 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>
<h3>function <code><a id="mps_sac_alloc" name="mps_sac_alloc">mps_sac_alloc</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_sac_alloc">mps_sac_alloc</a></code></p>
<h4>Summary</h4>
<p>This function allocates a block using the segregated allocation
cache given.</p>
<h4>Associated Protocols</h4>
<p>Allocation cache</p>
<h4>Type</h4>
<p><code>mps_res_t mps_sac_alloc(mps_addr_t *p_o, mps_sac_t sac, size_t size, mps_bool_t has_reservoir_permit);</code></p>
<h4>Arguments</h4>
<p>p_o a pointer to a variable to hold the address of the new block</p>
<p>sac the segregated allocation cache</p>
<p>size the size of the block requested</p>
<p><code>has_reservoir_permit</code> regulates access to the reservoir</p>
<h4>Returned Values</h4>
<p>If the return value is <code><a
href="#MPS_RES_OK">MPS_RES_OK</a></code>, the address of a new block
is <code>*p_o </code>.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>This function allocates a block using the cache given. If no
suitable block exists in the cache, it will ask for more memory from
the associated pool. <code>size</code> does not have to be one of the
class sizes of the cache; it does not have to be aligned.</p>
<p>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.</p>
<p><code>has_reservoir_permit</code> regulates whether the pool has
permission to get more memory from the reservoir to satisfy this
request.</p>
<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>Error Handling</h4>
<p><code><a href="#mps_sac_alloc">mps_sac_alloc</a></code> returns
<code><a href="#MPS_RES_MEMORY">MPS_RES_MEMORY</a></code> when it
fails to find enough memory; see the documentation for this return
code for recovery options. It returns <code><a
href="#MPS_RES_COMMIT_LIMIT">MPS_RES_COMMIT_LIMIT</a></code> if it
can't allocate without exceeding the arena commit limit; Free
something to make more space or increase the limit using <code><a
href="#mps_arena_commit_limit_set">mps_arena_commit_limit_set</a></code>. It
returns <code><a href="#MPS_RES_RESOURCE">MPS_RES_RESOURCE</a></code>
if it has run out of swap space; Free something or terminate other
processes on the same machine.</p>
<h4>See Also</h4>
<p>
<code><a href="#MPS_SAC_ALLOC_FAST">MPS_SAC_ALLOC_FAST</a></code>,
<code><a href="#mps_sac_free">mps_sac_free</a></code>,
<code><a href="#MPS_SAC_FREE_FAST">MPS_SAC_FREE_FAST</a></code>,
<code><a href="#mps_sac_t">mps_sac_t</a></code>,
<code><a
href="#mps_reservoir_limit_set">mps_reservoir_limit_set</a></code>,
<code><a
href="#mps_arena_commit_limit_set">mps_arena_commit_limit_set</a></code>,
<code><a href="#MPS_RES_MEMORY">MPS_RES_MEMORY</a></code>,
<code><a href="#MPS_RES_COMMIT_LIMIT">MPS_RES_COMMIT_LIMIT</a></code>,
<code><a href="#MPS_RES_RESOURCE">MPS_RES_RESOURCE</a></code></p>
<h4>Notes</h4>
<p>There's also a macro called <code><a
href="#MPS_SAC_ALLOC_FAST">MPS_SAC_ALLOC_FAST</a></code>, that does
the same thing. The macro is faster, but generates more code and does
less checking.</p>
<p>The block allocated can be larger than requested. Blocks not
matching any class size are allocated from the next largest class, and
blocks larger than the largest class size are simply allocated at the
requested size (rounded up to alignment, as usual).</p>
<p>Objects allocated through a segregated allocation cache should only
be freed through a segregated allocation cache with the same class
structure. Using <code><a href="#mps_free">mps_free</a></code> on
them can cause memory leaks, because the size of the block might be
larger than you think. Naturally, the cache must also be attached to
the same pool.</p>
<h3>macro <code><a id="MPS_SAC_ALLOC_FAST" name="MPS_SAC_ALLOC_FAST">MPS_SAC_ALLOC_FAST</a></code></h3>
<h4>Name</h4>
<p><code><a href="#MPS_SAC_ALLOC_FAST">MPS_SAC_ALLOC_FAST</a></code></p>
<h4>Summary</h4>
<p>This macro allocates a block using the segregated allocation cache
given.</p>
<h4>Associated Protocols</h4>
<p>Allocation cache</p>
<h4>Syntax</h4>
<p><code>MPS_SAC_ALLOC_FAST(res_o, p_o, sac, size, has_reservoir_permit)</code></p>
<h4>Arguments</h4>
<table>
<tr>
<td> <code>res_o</code> </td>
<td> <code><a href="#mps_res_t">mps_res_t</a></code> </td>
<td> an lvalue to hold the result code </td>
</tr>
<tr>
<td> <code>p_o</code> </td>
<td> <code><a href="#mps_addr_t">mps_addr_t</a></code> </td>
<td> an lvalue to hold the address of the new block </td>
</tr>
<tr>
<td> <code>sac</code> </td>
<td> <code><a href="#mps_sac_t">mps_sac_t</a></code> </td>
<td> the segregated allocation cache </td>
</tr>
<tr>
<td> <code>size</code> </td>
<td> <code>size_t</code> </td>
<td> the size of the block requested </td>
</tr>
<tr>
<td> <code>has_reservoir_permit</code> </td>
<td> <code><a href="#mps_bool_t">mps_bool_t</a></code> </td>
<td> regulates access to the reservoir </td>
</tr>
</table>
<h4>Returned Values</h4>
<p><code>res_o</code> will be set to the return code. If this is
<code><a href="#MPS_RES_OK">MPS_RES_OK</a></code>, the address of the
new block is in <code>p_o</code>.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>This macro allocates a block using the cache given. If no suitable
block exists in the cache, it will ask for more memory from the
associated pool. <code>size</code> does not have to be one of the
class sizes of the cache; it does not have to be aligned.</p>
<p>The client 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 threads that might be accessing
the same pool.</p>
<p><code>has_reservoir_permit</code> regulates whether the pool has
permission to get more memory from the reservoir to satisfy this
request.</p>
<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>
<h4>Error Handling</h4>
<p><code><a href="#MPS_SAC_ALLOC_FAST">MPS_SAC_ALLOC_FAST</a></code>
returns <code><a href="#MPS_RES_MEMORY">MPS_RES_MEMORY</a></code> when
it fails to find enough memory; see the documentation for this return
code for recovery options. It returns <code><a
href="#MPS_RES_COMMIT_LIMIT">MPS_RES_COMMIT_LIMIT</a></code> if it
can't allocate without exceeding the arena commit limit; free something
to make more space or increase the limit using <code><a
href="#mps_arena_commit_limit_set">mps_arena_commit_limit_set</a></code>. It
returns <code><a href="#MPS_RES_RESOURCE">MPS_RES_RESOURCE</a></code>
if it has run out of swap space; free something or terminate other
processes on the same machine.</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_sac_alloc">mps_sac_alloc</a></code>,
<code><a href="#MPS_SAC_FREE_FAST">MPS_SAC_FREE_FAST</a></code>,
<code><a href="#mps_sac_free">mps_sac_free</a></code>,
<code><a href="#mps_sac_t">mps_sac_t</a></code>,
<code><a
href="#mps_reservoir_limit_set">mps_reservoir_limit_set</a></code>,
<code><a
href="#mps_arena_commit_limit_set">mps_arena_commit_limit_set</a></code>,
<code><a href="#MPS_RES_MEMORY">MPS_RES_MEMORY</a></code>,
<code><a href="#MPS_RES_COMMIT_LIMIT">MPS_RES_COMMIT_LIMIT</a></code>,
<code><a href="#MPS_RES_RESOURCE">MPS_RES_RESOURCE</a></code></p>
<h4>Notes</h4>
<p>There's also a function called <code><a
href="#mps_sac_alloc">mps_sac_alloc</a></code>, that does the same
thing.</p>
<p>The block allocated can be larger than requested. Blocks not
matching any class size are allocated from the next largest class, and
blocks larger than the largest class size are simply allocated at the
requested size (rounded up to alignment, as usual).</p>
<p>Objects allocated through a segregated allocation cache should only
be freed through a segregated allocation cache with the same class
structure. Using <code><a href="#mps_free">mps_free</a></code> on them
can cause memory leaks or assertions, because the size of the block
might be larger than you think. Naturally, the cache must also be
attached to the same pool.</p>
<p>The macro doesn't evaluate <code>has_reservoir_permit</code>,
unless it decides to access the pool.</p>
<h3>constant <code><a id="MPS_SAC_CLASS_LIMIT" name="MPS_SAC_CLASS_LIMIT">MPS_SAC_CLASS_LIMIT</a></code></h3>
<h4>Name</h4>
<p><code><a href="#MPS_SAC_CLASS_LIMIT">MPS_SAC_CLASS_LIMIT</a></code></p>
<h4>Summary</h4>
<p><code><a href="#MPS_SAC_CLASS_LIMIT">MPS_SAC_CLASS_LIMIT</a></code> specifies how many classes <code><a href="#mps_sac_create">mps_sac_create</a></code> is guaranteed to accept.</p>
<h4>Type</h4>
<p>size_t</p>
<h4>Associated Protocols</h4>
<p>Allocation cache</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p><code><a href="#MPS_SAC_CLASS_LIMIT">MPS_SAC_CLASS_LIMIT</a></code> specifies a lower limit on the maximum number of classesthat can be described in a call to <code><a href="#mps_sac_create">mps_sac_create</a></code>, i.e., the MPS guarantees to acceptat least this many classes. More might be accepted -- in fact, there might not be any limit in theimplementation on the maximum number of classes, but if you specify more than this, you should beprepared to handle the error.</p>
<p><code><a href="#MPS_SAC_CLASS_LIMIT">MPS_SAC_CLASS_LIMIT</a></code> is a macro suitable for use in a constant expression, bothin a #if directive and wherever else constant expressions may be used.</p>
<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>See Also</h4>
<p>
<code><a href="#mps_sac_create">mps_sac_create</a></code></p>
<h4>Notes</h4>
<p>If you ask for too many size classes, <code><a href="#mps_sac_create">mps_sac_create</a></code> returns <code><a href="#MPS_RES_LIMIT">MPS_RES_LIMIT</a></code>; you can recover by combining some small adjacent classes.</p>
<h3>function <code><a id="mps_sac_free" name="mps_sac_free">mps_sac_free</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_sac_free">mps_sac_free</a></code></p>
<h4>Summary</h4>
<p>This function frees an object using the segregated allocation cache given.</p>
<h4>Associated Protocols</h4>
<p>Allocation cache</p>
<h4>Type</h4>
<p><code>void mps_sac_free(mps_sac_t sac, mps_addr_t p, size_t size);</code></p>
<h4>Arguments</h4>
<p>sac the segregated allocation cache</p>
<p>p a pointer to the block being freed</p>
<p>size the size of the block being freed</p>
<h4>Returned Values</h4>
<p>None.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>
This function frees an object using the cache given. If the cache would become too full,some blocks are returned to the associated pool.
<code>size</code>
should be the size that wasspecified when the object was allocated (the cache knows what the real size of the block is). Theobject must have been allocated through a segregated allocation cache with the same class structure,attached to the same pool.
</p>
<p>The client is responsible for synchronising the access to the cache, but if the cachedecides to access the pool, the MPS will properly synchronize with any other threads that might beaccessing the same pool.</p>
<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>See Also</h4>
<p>
<code><a href="#MPS_SAC_FREE_FAST">MPS_SAC_FREE_FAST</a></code>,
<code><a href="#mps_sac_alloc">mps_sac_alloc</a></code>,
<code><a href="#MPS_SAC_ALLOC_FAST">MPS_SAC_ALLOC_FAST</a></code>,
<code><a href="#mps_sac_t">mps_sac_t</a></code></p>
<h4>Notes</h4>
<p>Usually, you'd use the same cache to allocate and deallocate an object.</p>
<p>There's also a macro called <code><a href="#MPS_SAC_FREE_FAST">MPS_SAC_FREE_FAST</a></code>, that does the same thing. The macro is faster, but generates more code and does no checking.</p>
<p>Note that <code><a href="#mps_sac_free">mps_sac_free</a></code> does very little checking; it's optimized for speed.Double frees and other mistakes will only be detected when the cache is flushed (which can happen bydemand through <code><a href="#mps_sac_flush">mps_sac_flush</a></code> or automatically), unless intervening operations have obscured symptom.</p>
<h3>macro <code><a id="MPS_SAC_FREE_FAST" name="MPS_SAC_FREE_FAST">MPS_SAC_FREE_FAST</a></code></h3>
<h4>Name</h4>
<p><code><a href="#MPS_SAC_FREE_FAST">MPS_SAC_FREE_FAST</a></code></p>
<h4>Summary</h4>
<p><code><a href="#MPS_SAC_FREE_FAST">MPS_SAC_FREE_FAST</a></code> frees an object using the segregated allocation cache given.</p>
<h4>Associated Protocols</h4>
<p>Allocation cache</p>
<h4>Syntax</h4>
<p><code>MPS_SAC_FREE_FAST(sac, p, size)</code></p>
<h4>Arguments</h4>
<table>
<tr>
<td>
<code>sac</code>
</td>
<td>
<code><a href="#mps_sac_t">mps_sac_t</a></code>
</td>
<td>
the segregated allocation cache
</td>
</tr>
<tr>
<td>
<code>p</code>
</td>
<td>
<code><a href="#mps_addt_t">mps_addt_t</a></code>
</td>
<td>
the address of the object to be freed
</td>
</tr>
<tr>
<td>
<code>size</code>
</td>
<td>
<code> size_t</code>
</td>
<td>
the size of the object
</td>
</tr>
</table>
<h4>Returned Values</h4>
<p>None.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>
This macro frees an object using the cache given. If the cache would become too full, someblocks are returned to the associated pool.
<code>size</code>
should be the size that was specifiedwhen the object was allocated (the cache knows what the real size of the block is). The objects musthave been allocated through a segregated allocation cache with the same class structure, attachedto the same pool.
</p>
<p>The client is responsible for synchronizing the access to the cache, but if the cachedecides to access the pool, the MPS will properly synchronize with any other threads that might beaccessing the same pool.</p>
<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>
<h4>See Also</h4>
<p>
<code><a href="#mps_sac_free">mps_sac_free</a></code>,
<code><a href="#MPS_SAC_ALLOC_FAST">MPS_SAC_ALLOC_FAST</a></code>,
<code><a href="#mps_sac_alloc">mps_sac_alloc</a></code>,
<code><a href="#mps_sac_t">mps_sac_t</a></code></p>
<h4>Notes</h4>
<p>Usually, you'd use the same cache to allocate and deallocate an object.</p>
<p>There's also a function called <code><a href="#mps_sac_free">mps_sac_free</a></code>, that does the same thing. Themacro is faster, but generates more code and does no checking.</p>
<p>Note that <code><a href="#MPS_SAC_FREE_FAST">MPS_SAC_FREE_FAST</a></code> doesn't do any checking; it's optimized for speed. Double frees and other mistakes will only be detected when the cache is flushed (which can happen by demand through <code><a href="#mps_sac_flush">mps_sac_flush</a></code> or automatically), unless intervening operations have obscured symptom.</p>
<h3>macro <code><a id="MPS_SCAN_BEGIN" name="MPS_SCAN_BEGIN">MPS_SCAN_BEGIN</a></code></h3>
<h4>Name</h4>
<p><code><a href="#MPS_SCAN_BEGIN">MPS_SCAN_BEGIN</a></code></p>
<h4>Summary</h4>
<p>The macro <code><a href="#MPS_SCAN_BEGIN">MPS_SCAN_BEGIN</a></code> is part of the scanning protocol; together with <code><a href="#MPS_SCAN_END">MPS_SCAN_END</a></code>, it sets up local information used by <code>MPS_FIX*</code>.</p>
<h4>Associated Protocols</h4>
<p>Scanning.</p>
<h4>Syntax</h4>
<p><code>MPS_SCAN_BEGIN(ss)</code></p>
<h4>Arguments</h4>
<p>ss the scan state argument that was passed to the scanning function</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>This macro is used in the scanning protocol. Together with <code><a href="#MPS_SCAN_END">MPS_SCAN_END</a></code>, it sets up local information used by the fast <code>MPS_FIX*</code> macros.</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>
<h4>See Also</h4>
<p>
<code><a href="#MPS_SCAN_END">MPS_SCAN_END</a></code>,
<code><a href="#MPS_FIX12">MPS_FIX12</a></code>,
<code><a href="#MPS_FIX1">MPS_FIX1</a></code>,
<code><a href="#MPS_FIX2">MPS_FIX2</a></code>,
<code><a href="#MPS_FIX_CALL">MPS_FIX_CALL</a></code></p>
<h4>Notes</h4>
<p>Between <code><a href="#MPS_SCAN_BEGIN">MPS_SCAN_BEGIN</a></code> and <code><a href="#MPS_SCAN_END">MPS_SCAN_END</a></code>, you may not call another scanning functiondirectly, because the scan state parameter is in a strange state, so you shouldn't pass it as anargument to a function. However, you can pass the scan state using <code><a href="#MPS_FIX_CALL">MPS_FIX_CALL</a></code>. You also cannotnest <code><a href="#MPS_SCAN_BEGIN">MPS_SCAN_BEGIN</a></code> textually within another <code><a href="#MPS_SCAN_BEGIN">MPS_SCAN_BEGIN</a></code> -- <code><a href="#MPS_SCAN_END">MPS_SCAN_END</a></code> pair.</p>
<h3>macro <code><a id="MPS_SCAN_END" name="MPS_SCAN_END">MPS_SCAN_END</a></code></h3>
<h4>Name</h4>
<p><code><a href="#MPS_SCAN_END">MPS_SCAN_END</a></code></p>
<h4>Summary</h4>
<p>The macro <code><a href="#MPS_SCAN_END">MPS_SCAN_END</a></code> is part of the scanning protocol; it terminates a blockstarted by <code><a href="#MPS_SCAN_BEGIN">MPS_SCAN_BEGIN</a></code>.</p>
<h4>Associated Protocols</h4>
<p>Scanning.</p>
<h4>Syntax</h4>
<p><code>MPS_SCAN_END(ss);</code></p>
<h4>Arguments</h4>
<p>ss the scan state argument that was passed to the scanning function</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>This macro is used in the scanning protocol. Together with <code><a href="#MPS_SCAN_BEGIN">MPS_SCAN_BEGIN</a></code>, itsets up local information used by the fast <code>MPS_FIX*</code> macros. Note that <code><a href="#MPS_SCAN_END">MPS_SCAN_END</a></code> completes the scanning, so successful termination of the scanning mustinvoke it (error branches can return without passing through).</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>
<h4>See Also</h4>
<p>
<code><a href="#MPS_SCAN_BEGIN">MPS_SCAN_BEGIN</a></code>,
<code><a href="#MPS_FIX12">MPS_FIX12</a></code>,
<code><a href="#MPS_FIX1">MPS_FIX1</a></code>,
<code><a href="#MPS_FIX2">MPS_FIX2</a></code>,
<code><a href="#MPS_FIX_CALL">MPS_FIX_CALL</a></code></p>
<h4>Notes</h4>
<p>Between <code><a href="#MPS_SCAN_BEGIN">MPS_SCAN_BEGIN</a></code> and <code><a href="#MPS_SCAN_END">MPS_SCAN_END</a></code>, you may not call another scanning functiondirectly, because the scan state parameter is in a strange state, so you shouldn't pass it as anargument to a function. However, you can pass the scan state using <code><a href="#MPS_FIX_CALL">MPS_FIX_CALL</a></code>.</p>
<h3>type <code><a id="MPS_T_WORD" name="MPS_T_WORD">MPS_T_WORD</a></code></h3>
<h4>Name</h4>
<p><code><a href="#MPS_T_WORD">MPS_T_WORD</a></code></p>
<h4>Summary</h4>
<p><code><a href="#MPS_T_WORD">MPS_T_WORD</a></code> an unsigned integral type that is the same size as an object pointer.</p>
<h4>Resources</h4>
<p>mpstd.h.</p>
<h4>Description</h4>
<p><code><a href="#MPS_T_WORD">MPS_T_WORD</a></code> is a preprocessor macro defined in "mpstd.h". It is the name of an unsignedintegral type that is the same size as an object pointer (so <code>sizeof(MPS_T_WORD) == sizeof(void*)</code>).The exact identity of the type is platform-dependent.</p>
<h4>Example</h4>
<h4>See Also</h4>
<p>
<code><a href="#MPS_WORD_SHIFT">MPS_WORD_SHIFT</a></code>,
<code><a href="#MPS_WORD_WIDTH">MPS_WORD_WIDTH</a></code></p>
<h3>constant <code><a id="MPS_WORD_SHIFT" name="MPS_WORD_SHIFT">MPS_WORD_SHIFT</a></code></h3>
<h4>Name</h4>
<p><code><a href="#MPS_WORD_SHIFT">MPS_WORD_SHIFT</a></code></p>
<h4>Summary</h4>
<p><code><a href="#MPS_WORD_SHIFT">MPS_WORD_SHIFT</a></code> is log base 2 of <code><a href="#MPS_WORD_WIDTH">MPS_WORD_WIDTH</a></code>.</p>
<h4>Type</h4>
<p>Integral constant.</p>
<h4>Resources</h4>
<p>mpstd.h.</p>
<h4>Description</h4>
<p><code><a href="#MPS_WORD_SHIFT">MPS_WORD_SHIFT</a></code> is a preprocessor macro defined in "mpstd.h". It is the logarithm in base 2 of <code><a href="#MPS_WORD_WIDTH">MPS_WORD_WIDTH</a></code> (so <code>1 &lt;&lt; MPS_WORD_SHIFT == MPS_WORD_WIDTH</code>). The value of <code><a href="#MPS_WORD_SHIFT">MPS_WORD_SHIFT</a></code> is platform-dependent. Typical values are 5 and 6.</p>
<h4>Example</h4>
<h4>See Also</h4>
<p>
<code><a href="#MPS_T_WORD">MPS_T_WORD</a></code>,
<code><a href="#MPS_WORD_WIDTH">MPS_WORD_WIDTH</a></code></p>
<h3>constant <code><a id="MPS_WORD_WIDTH" name="MPS_WORD_WIDTH">MPS_WORD_WIDTH</a></code></h3>
<h4>Name</h4>
<p><code><a href="#MPS_WORD_WIDTH">MPS_WORD_WIDTH</a></code></p>
<h4>Summary</h4>
<p><code><a href="#MPS_WORD_WIDTH">MPS_WORD_WIDTH</a></code> is the width in bits of the type <code><a href="#MPS_T_WORD">MPS_T_WORD</a></code>.</p>
<h4>Type</h4>
<p>Integral constant.</p>
<h4>Resources</h4>
<p>mpstd.h.</p>
<h4>Description</h4>
<p><code><a href="#MPS_WORD_WIDTH">MPS_WORD_WIDTH</a></code> is a preprocessor macro defined in "mpstd.h" to be the width in bits of the type <code><a href="#MPS_T_WORD">MPS_T_WORD</a></code> (so <code>MPS_WORD_WIDTH == sizeof(MPS_T_WORD) * CHAR_BIT</code>).</p>
<p>This value is required for the use of the MPS C interface and the interpretation of "mps.h".It is platform-dependent. It is a power of 2; typical values are 32 and 64. It may be defined byincluding "mpstd.h" on a supported platform, or by defining it to be the width of <code><a href="#MPS_T_WORD">MPS_T_WORD</a></code> inbits.</p>
<h4>Example</h4>
<pre>
#define MPS_WORD_WIDTH 32
</pre>
<h4>See Also</h4>
<p>
<code><a href="#MPS_T_WORD">MPS_T_WORD</a></code>,
<code><a href="#MPS_WORD_SHIFT">MPS_WORD_SHIFT</a></code></p>
<h3>type <code><a id="mps_addr_t" name="mps_addr_t">mps_addr_t</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_addr_t">mps_addr_t</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_addr_t">mps_addr_t</a></code> is the type of addresses managed by the MPS, and also the type of references too bjects.</p>
<h4>Associated Protocols</h4>
<p>Allocation, allocation point, format, root, location dependency.</p>
<h4>Type</h4>
<p><code>typedef void *mps_addr_t;</code></p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p><code><a href="#mps_addr_t">mps_addr_t</a></code> is the type of addresses managed by the MPS, and also the type of referencesto objects. It is used in the MPS C interface where the MPS needs to pass a pointer to memory thatis under the control of the MPS.</p>
<p>In accordance with standard C practice, the value NULL of type <code><a href="#mps_addr_t">mps_addr_t</a></code> will never beused to represent the address of an object.</p>
<h4>Example</h4>
<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>
<h4>Error Handling</h4>
<p>Not applicable.</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_align_t">mps_align_t</a></code></p>
<h3>type <code><a id="mps_align_t" name="mps_align_t">mps_align_t</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_align_t">mps_align_t</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_align_t">mps_align_t</a></code> is the type of an alignment.</p>
<h4>Associated Protocols</h4>
<p>Format, pool, allocation.</p>
<h4>Type</h4>
<p><code>typedef size_t mps_align_t;</code></p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>An alignment specifies the address modulus to which all objects in an object format must bealigned. That is, if an alignment of 4 is specified, then the address of any object in that formatmodulo 4 will always be 0.</p>
<p><code><a href="#mps_align_t">mps_align_t</a></code> is a transparent type equivalent to the C type "size_t" and must be a positivepower of 2.</p>
<p>Some pools and allocation protocols accept an alignment as an option that can be used toensure that objects in the pool or objects allocated observe a stricter alignment than that of theobject format.</p>
<h4>Example</h4>
<pre>
mps_align_t floatAlign = 4;
mps_align_t doubleFloatAlign = 8;
</pre>
<h4>See Also</h4>
<p>
<code><a href="#mps_fmt_A_t">mps_fmt_A_t</a></code>,
<code><a href="#mps_addr_t">mps_addr_t</a></code></p>
<h3>function <code><a id="mps_alloc" name="mps_alloc">mps_alloc</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_alloc">mps_alloc</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_alloc">mps_alloc</a></code> allocates a block of memory in a pool.</p>
<h4>Associated Protocols</h4>
<p>Allocation.</p>
<h4>Syntax</h4>
<p><code>mps_res_t mps_alloc(mps_addr_t *p, mps_pool_t pool, size_t size, ...);</code></p>
<h4>Arguments</h4>
<p>p output parameter for a pointer to the block allocated</p>
<p>pool the pool to allocate in</p>
<p>size the size of the block to allocate in bytes</p>
<p>... (some pools can take additional arguments)</p>
<h4>Returned Values</h4>
<p>A return code.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p><code><a href="#mps_alloc">mps_alloc</a></code> allocates a block of memory in the given pool.</p>
<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>
<h4>Error Handling</h4>
<h4>See Also</h4>
<p>
<code><a href="#mps_free">mps_free</a></code></p>
<h3><code><a id="mps_alloc_pattern_ramp" name="mps_alloc_pattern_ramp">mps_alloc_pattern_ramp</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_alloc_pattern_ramp">mps_alloc_pattern_ramp</a></code></p>
<h4>Summary</h4>
<p>Returns a allocation pattern type indicating that allocation will follow a ramp pattern.</p>
<h4>Associated Protocols</h4>
<p>alloc-pattern-ramp</p>
<h4>Syntax</h4>
<p><code>mps_alloc_pattern_t mps_alloc_pattern_ramp();</code></p>
<h4>Arguments</h4>
<p>none</p>
<h4>Returned Values</h4>
<p>Returns the allocation pattern type for ramps.</p>
<h4>Description</h4>
<p>When declaring an allocation pattern for an AP, if the calls to <code><a href="#mps_ap_alloc_pattern_begin">mps_ap_alloc_pattern_begin</a></code> use ramp allocation patterns (such as the result of <code><a href="#mps_alloc_pattern_ramp">mps_alloc_pattern_ramp</a></code>), then the MPS willtake this as an indication that most of the objects allocated after the call to <code><a href="#mps_ap_alloc_pattern_begin">mps_ap_alloc_pattern_begin</a></code> are likely to be dead by the corresponding call to <code><a href="#mps_ap_alloc_pattern_end">mps_ap_alloc_pattern_end</a></code>.</p>
<p>This permits the client to indicate useful points for GC with minimal perturbation of the GCstrategy.</p>
<h4>Example</h4>
<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>Error Handling</h4>
<p>Cannot fail.</p>
<h4>See Also</h4>
<p>
<code><a
href="#mps_alloc_pattern_ramp_collect_all">mps_alloc_pattern_ramp_collect_all</a></code>,
<code><a
href="#mps_ap_alloc_pattern_begin">mps_ap_alloc_pattern_begin</a></code></p>
<h4>Notes</h4>
<h3><code><a id="mps_alloc_pattern_ramp_collect_all" name="mps_alloc_pattern_ramp_collect_all">mps_alloc_pattern_ramp_collect_all</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_alloc_pattern_ramp_collect_all">mps_alloc_pattern_ramp_collect_all</a></code></p>
<h4>Summary</h4>
<p>Returns a ramp allocation pattern type indicating that a full GC should be done.</p>
<h4>Associated Protocols</h4>
<p>GC, AP, ramps</p>
<h4>Syntax</h4>
<p><code>mps_alloc_pattern_t mps_alloc_pattern_ramp_collect_all();</code></p>
<h4>Arguments</h4>
<p>none</p>
<h4>Returned Values</h4>
<p>Returns the allocation pattern type for full collection ramps.</p>
<h4>Description</h4>
<p>This yields an allocation pattern for an AP that is similar to that returned by <code><a href="#mps_alloc_pattern_ramp">mps_alloc_pattern_ramp</a></code>, in that it declares a ramp allocation pattern, but additionally indicates tothe MPS that the next collection following the ramp should be a full GC.</p>
<p>This permits the client to indicate useful points for a full GC, either because most of theheap is likely to be dead, or because accurate statistics are required, with minimal perturbation ofthe GC strategy.</p>
<p>As usual, this allocation pattern should be used in matching <code><a href="#mps_ap_alloc_pattern_begin">mps_ap_alloc_pattern_begin</a></code> and <code><a href="#mps_ap_alloc_pattern_end">mps_ap_alloc_pattern_end</a></code> pairs. It may nest with, but should not otherwise overlap with allocationpatterns of type <code><a href="#mps_alloc_pattern_ramp">mps_alloc_pattern_ramp</a></code>. In this case, the MPS may defer the full GC until after allramp allocation patterns have ended.</p>
<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>Error Handling</h4>
<p>Cannot fail.</p>
<h4>See Also</h4>
<p>
<code><a
href="#mps_alloc_pattern_ramp">mps_alloc_pattern_ramp</a></code>,
<code><a
href="#mps_ap_alloc_pattern_begin">mps_ap_alloc_pattern_begin</a></code></p>
<h4>Notes</h4>
<h4>Internal Notes</h4>
<h3><code><a id="mps_amc_apply" name="mps_amc_apply">mps_amc_apply</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_amc_apply">mps_amc_apply</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_amc_apply">mps_amc_apply</a></code> is used to inspect objects in an AMC pool. You may only call it when thearena is parked (for example, after <code><a href="#mps_arena_collect">mps_arena_collect</a></code>).</p>
<h4>Associated Protocols</h4>
<p>Arena.</p>
<h4>Syntax</h4>
<p><code>extern void mps_amc_apply(mps_pool_t, void(*f)(mps_addr_t, void *, size_t), void *, size_t);</code></p>
<h4>Arguments</h4>
<p><code><a href="#mps_pool_t">mps_pool_t</a></code> the pool whose objects you want to inpect</p>
<p>f a supplied function</p>
<p><code><a href="#mps_addr_t">mps_addr_t</a></code> the address of the object you want to inspect</p>
<p>*</p>
<p>size_t</p>
<h4>Returned Values</h4>
<p>Not applicable.</p>
<h4>Resources</h4>
<p>Not applicable.</p>
<h4>Description</h4>
<p><code><a href="#mps_amc_apply">mps_amc_apply</a></code> is used to inspect objects in an AMC pool. You may only call it when thearena is parked (for example, after <code><a href="#mps_arena_collect">mps_arena_collect</a></code>). When called, <code><a href="#mps_amc_apply">mps_amc_apply</a></code> calls thesupplied function "f" once for each object in the pool, with the address of the object as its firstargument. "f" is given as its second and third arguments whatever values were given as the third andfourth arguments to <code><a href="#mps_amc_apply">mps_amc_apply</a></code>. (This is intended to make it easy to pass, for example, anarray and its size as parameters.)</p>
<p>"f" will be called on both data and pad objects, and it is "f"'s job to distinguish, ifrequired, between the two. Note (c.f. <code><a href="#mps_arena_collect">mps_arena_collect</a></code>, above) that it may be called onunreachable objects that the collector has not recycled or has not been able to recycle.</p>
<p>The function "f" may not allocate memory or access any automatically-managed memory exceptthe object at which it is pointed and, in the case of objects in Dylan Container Format, thatobject's wrapper.</p>
<h4>Example</h4>
<h4>Error Handling</h4>
<h4>See Also</h4>
<p>Functions that park the arena:
<code><a href="#mps_arena_park">mps_arena_park</a></code>,
<code><a href="#mps_arena_collect">mps_arena_collect</a></code>.</p>
<p>A more general heap walker which inspects all formatted objects in
the arena:
<code><a
href="#mps_arena_formatted_objects_walk">mps_arena_formatted_objects_walk</a></code></p>
<h4>Notes</h4>
<p>There is no equivalent function for other pool classes, but there is a more general heapwalker: <code><a href="#mps_arena_formatted_objects_walk">mps_arena_formatted_objects_walk</a></code>.</p>
<h4>Internal Notes</h4>
<p>Does "You must call it when the arena is parked" mean that (a) parking an arena requiresthat you call this function, or (b) you can only call this function when the arena is in the parkedstate? LMB</p>
<p>(b). Changed "must call" to "may only call" drj 1998-08-25</p>
<h3><code><a id="mps_ap_alloc_pattern_begin" name="mps_ap_alloc_pattern_begin">mps_ap_alloc_pattern_begin</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_ap_alloc_pattern_begin">mps_ap_alloc_pattern_begin</a></code></p>
<h4>Summary</h4>
<p>Indicates the start of allocation following a particular pattern.</p>
<h4>Associated Protocols</h4>
<p>AP, Allocation, Alloc-pattern-ramp.</p>
<h4>Syntax</h4>
<p><code>mps_res_t mps_ap_alloc_pattern_begin(mps_ap_t ap, mps_alloc_pattern_t alloc_pattern)</code></p>
<h4>Arguments</h4>
<p>ap The allocation point in which the patterned allocation will occur</p>
<p>alloc_pattern The pattern of the allocation</p>
<h4>Returned Values</h4>
<p>Result code indicating whether start of the allocation pattern was successfully registered.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>This function is used, together with <code><a href="#mps_ap_alloc_pattern_end">mps_ap_alloc_pattern_end</a></code>, to indicate periods ofallocation in an allocation point that follow some pattern of lifetime.</p>
<p>The nesting/overlapping restrictions on allocation patterns may vary depending on theparticular allocation pattern type, but in general, if <code><a href="#mps_ap_alloc_pattern_begin">mps_ap_alloc_pattern_begin</a></code> is used multipletimes on the same allocation point without intervening calls to <code><a href="#mps_ap_alloc_pattern_end">mps_ap_alloc_pattern_end</a></code>, the callsmatch in a stack-like way, outermost and innermost; that is, allocation patterns may nest, but nototherwise overlap.</p>
<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>
<h4>Error Handling</h4>
<p>Currently doesn't fail, but may in future if certain allocation patterns are inappropriatefor that allocation point at that point in time.</p>
<h4>See Also</h4>
<p>
<code><a
href="#mps_alloc_pattern_ramp">mps_alloc_pattern_ramp</a></code>,
<code><a
href="#mps_alloc_pattern_ramp_collect_all">mps_alloc_pattern_ramp_collect_all</a></code>,
<code><a
href="#mps_ap_alloc_pattern_end">mps_ap_alloc_pattern_end</a></code>,
<code><a
href="#mps_ap_alloc_pattern_reset">mps_ap_alloc_pattern_reset</a></code></p>
<h3><code><a id="mps_ap_alloc_pattern_end" name="mps_ap_alloc_pattern_end">mps_ap_alloc_pattern_end</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_ap_alloc_pattern_end">mps_ap_alloc_pattern_end</a></code></p>
<h4>Summary</h4>
<p>Indicates the end of allocation following a particular pattern.</p>
<h4>Associated Protocols</h4>
<p>AP, Allocation, Alloc-pattern-ramp.</p>
<h4>Syntax</h4>
<p><code>mps_res_t mps_ap_alloc_pattern_end(mps_ap_t ap, mps_alloc_pattern_t alloc_pattern)</code></p>
<h4>Arguments</h4>
<p>ap The allocation point in which the patterned allocation occurred</p>
<p>alloc_pattern The pattern of the allocation</p>
<h4>Returned Values</h4>
<p>Result code indicating whether end of the allocation pattern was successfully registered.</p>
<h4>Description</h4>
<p>This function is used, together with <code><a href="#mps_ap_alloc_pattern_begin">mps_ap_alloc_pattern_begin</a></code>, to indicate periods of allocation in an allocation point that follow some pattern of lifetime.</p>
<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>
<h4>Error Handling</h4>
<p>Will fail if there is no extant allocation pattern of that type. May fail in future ifcertain allocation patterns are inappropriate for that allocation point at that point in time.</p>
<h4>See Also</h4>
<p>
<code><a
href="#mps_alloc_pattern_ramp">mps_alloc_pattern_ramp</a></code>,
<code><a
href="#mps_alloc_pattern_ramp_collect_all">mps_alloc_pattern_ramp_collect_all</a></code>,
<code><a
href="#mps_ap_alloc_pattern_begin">mps_ap_alloc_pattern_begin</a></code>,
<code><a
href="#mps_ap_alloc_pattern_reset">mps_ap_alloc_pattern_reset</a></code></p>
<h3>function <code><a id="mps_ap_alloc_pattern_reset" name="mps_ap_alloc_pattern_reset">mps_ap_alloc_pattern_reset</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_ap_alloc_pattern_reset">mps_ap_alloc_pattern_reset</a></code></p>
<h4>Summary</h4>
<p>Indicates the end of allocation pattern on an allocation point.</p>
<h4>Associated Protocols</h4>
<p>AP, Alloc-pattern-ramp</p>
<h4>Syntax</h4>
<p><code>mps_res_t mps_ap_alloc_pattern_reset(mps_ap_t ap);</code></p>
<h4>Arguments</h4>
<p>ap The allocation point in which the patterned allocation occurred</p>
<h4>Returned Values</h4>
<p>Result code indicating whether end of the allocation patterns was successfully registered.</p>
<h4>Description</h4>
<p>This function may be used in place of <code><a href="#mps_ap_alloc_pattern_end">mps_ap_alloc_pattern_end</a></code> to end all extant allocationpatterns on an allocation point. It is anticipated that this may be used to recover from errorconditions.</p>
<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>
<h4>Error Handling</h4>
<p>Cannot fail at present. May fail in future if certain allocation patterns cannot be endedfor that allocation point at that point in time.</p>
<h4>See Also</h4>
<p>
<code><a
href="#mps_alloc_pattern_ramp">mps_alloc_pattern_ramp</a></code>,
<code><a
href="#mps_alloc_pattern_ramp_collect_all">mps_alloc_pattern_ramp_collect_all</a></code>,
<code><a
href="#mps_ap_alloc_pattern_begin">mps_ap_alloc_pattern_begin</a></code>,
<code><a
href="#mps_ap_alloc_pattern_end">mps_ap_alloc_pattern_end</a></code></p>
<h3>function <code><a id="mps_ap_frame_pop" name="mps_ap_frame_pop">mps_ap_frame_pop</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_ap_frame_pop">mps_ap_frame_pop</a></code></p>
<h4>Summary</h4>
<p>Declares that a set of objects in a particular frame are dead or likely to be dead.</p>
<h4>Associated Protocols</h4>
<p>AP Stack Protocol</p>
<h4>Type</h4>
<p><code>mps_res_t (mps_ap_frame_pop)(mps_ap_t /* ap */, mps_frame_t /* frame */)</code></p>
<h4>Arguments</h4>
<p>mps_ap_t ap</p>
<p>The allocation point in which the frame was pushed.</p>
<p>frame</p>
<p>The frame.</p>
<h4>Returned Values</h4>
<p>A result code in the usual way.</p>
<h4>Description</h4>
<p>This function pops the specified frame making its parent the current frame (frames areimplicitly created using the push operation, see <code><a href="#mps_ap_frame_push">mps_ap_frame_push</a></code>). Poppinginvalidates the specified frame and all frames pushed since the specified frame. Popping the framemakes a declaration about the set of objects which were allocated in the specified frame and alsoall frames which were pushed since the specified frame. It can be used to declare a set of objectsdead or likely to be mostly dead; the exact interpretation of the declaration depends on pool classthat the allocation point is in (the same pool class that that objects are in). Typically poolclasses which are mostly manually managed will use this declaration to mean that the objects aredead and their space can be reclaimed immediately, whereas pool classes which are mostlyautomatically managed will use this declaration to mean that the objects are likely to be mostlydead (the pool class may use this declaration to alter its collection decisions). Consult the poolclass documentation for details.</p>
<p>In general a frame other than the current frame can be popped (all frames pushed morerecently will be invalidated as well, as described above), but a particular pool class may imposethe restriction that only the current frame may be popped. This restriction means that every pushmust have a corresponding pop. Consult the pool class documentation for details.</p>
<p>It is illegal to pass invalid frames to any MPS function. In particular it is not possibleto pop frames out of order (so the sequence "A = push, B = push, pop A, pop B" is illegal) or to popto the same frame twice (so the sequence "A = push, pop A, pop A" is illegal).</p>
<p>More comprehensive documentation is available in the protocol document (AP Stack Protocol).</p>
<h4>Example</h4>
<p>&lt;example of how to use the symbol&gt;</p>
<h4>Error Handling</h4>
<p>&lt;how the client program should handle errors that the symbol returns, if applicable&gt;</p>
<h4>See Also</h4>
<p>mps.protocol.alloc-point.stack,
<code><a href="#mps_ap_frame_push">mps_ap_frame_push</a></code></p>
<h4>Notes</h4>
<p>None.</p>
<h3>function <code><a id="mps_ap_frame_push" name="mps_ap_frame_push">mps_ap_frame_push</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_ap_frame_push">mps_ap_frame_push</a></code></p>
<h4>Summary</h4>
<p>Declares a new frame as part of the AP stack protocol.</p>
<h4>Associated Protocols</h4>
<p>AP Stack Protocol</p>
<h4>Type</h4>
<p><code>mps_res_t (mps_ap_frame_push)(mps_frame_t * /* frameReturn */, mps_ap_t /* ap */);</code></p>
<h4>Arguments</h4>
<p><code>mps_frame_t *frameReturn</code> The frame return parameter. A new frame (declared by this function) is stored in thislocation if this function is successful.</p>
<p><code>mps_ap_t ap </code> The allocation point in which the new frame is declared.</p>
<h4>Returned Values</h4>
<p>A result code in the usual way. The creation of new frame objects (which is implicit in theaction of this function) can consume resources, so this function can fail because there areinsufficient resources. This function may fail if the correct protocol is not followed by theclient.</p>
<h4>Description</h4>
<p>This function declares a new frame in the specified allocation point, makes that new frame achild of the current frame, changes the current frame to be the newly created frame, and returns ahandle to the frame. Frames have two important features: A single frame identifies a set of objects(those objects that are "allocated in the frame") which can be destroyed (or declared dead) in a popoperation (see <code><a href="#mps_ap_frame_pop">mps_ap_frame_pop</a></code>); They are arranged in a partially ordered sequence (this isimportant when the pop operation is used). A fuller and more useful description is found in the APstack protocol document (protocol.mps.alloc-point.stack).</p>
<h4>Example</h4>
<p>[missing]</p>
<h4>Error Handling</h4>
<p>Errors can either be because the client hasn't followed the correct protocol in which casethere isn't much that we can recommend or else because some needed resource isn't available. Theusual course of actions when short of resources is recommended.</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_ap_frame_pop">mps_ap_frame_pop</a></code>,
protocol.mps.alloc-point.stack</p>
<h4>Notes</h4>
<h3>function <code><a id="mps_arena_clamp" name="mps_arena_clamp">mps_arena_clamp</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_arena_clamp">mps_arena_clamp</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_arena_clamp">mps_arena_clamp</a></code> puts the specified arena into the clamped state.</p>
<h4>Associated Protocols</h4>
<p>Arena.</p>
<h4>Syntax</h4>
<p><code>extern void mps_arena_clamp(mps_arena_t);</code></p>
<h4>Arguments</h4>
<p>arena -- the arena to be put i nto the clamped state</p>
<h4>Returned Values</h4>
<p>None.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p><code><a href="#mps_arena_clamp">mps_arena_clamp</a></code> puts the specified arena into the clamped state. In the clamped state, noobject motion will occur and the staleness of location dependencies will not change. All referencesto objects loaded while the arena is clamped will keep the same binary representation until after itis released.</p>
<p>In a clamped arena, incremental collection may still occur, but it will not be visible tothe mutator and no new collections will begin. Space used by unreachable objects will not berecycled until the arena becomes unclamped.</p>
<h4>Example</h4>
<h4>Error Handling</h4>
<h4>See Also</h4>
<p>
<code><a href="#mps_arena_park">mps_arena_park</a></code>,
<code><a href="#mps_arena_release">mps_arena_release</a></code></p>
<h4>Notes</h4>
<h3>function <code><a id="mps_arena_class_cl" name="mps_arena_class_cl">mps_arena_class_cl</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_arena_class_cl">mps_arena_class_cl</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_arena_class_cl">mps_arena_class_cl</a></code> returns the client arena class.</p>
<h4>Associated Protocols</h4>
<p>Arena.</p>
<h4>Type</h4>
<p><code>mps_arena_class_t mps_arena_class_cl(void)</code></p>
<h4>Arguments</h4>
<p>None.</p>
<h4>Returned Values</h4>
<p>Returns the client arena class.</p>
<h4>Resources</h4>
<p>mpsacl.h</p>
<h4>Description</h4>
<p>This function is used to get hold of the client arena class, for the purpose of passing itto <code><a href="#mps_arena_create">mps_arena_create</a></code>.</p>
<h4>Example</h4>
<pre>
mps_arena_t arena;
int main(void)
{
void *block;
mps_res_t res;
block = malloc(ARENA_SIZE);
if(block == NULL) {
printf("Not enough memory!");
exit(1);
}
res = mps_arena_create(&amp;arena, mps_arena_class_cl(), ARENA_SIZE, block);
if(res != MPS_RES_OK) {
printf("ARENA_SIZE too small");
exit(2);
}
/* rest of program */
}
</pre>
<h4>Error Handling</h4>
<p>None.</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_arena_create">mps_arena_create</a></code></p>
<h4>Notes</h4>
<p>A client arena gets its managed memory from the client. This memory block is passed when thearena is created. When creating a client arena, <code><a href="#mps_arena_create">mps_arena_create</a></code> takes two extraarguments:</p>
<p><code>mps_res_t mps_arena_create(mps_arena_t *mps_arena_o, mps_arena_class_t mps_arena_class_cl,size_t size, void *block)</code></p>
<p><code>block</code> is the address of the memory block managed by the arena, and<code>size </code> is its size in bytes. If <code><a href="#mps_arena_create">mps_arena_create</a></code> returns<code><a href="#MPS_RES_MEMORY">MPS_RES_MEMORY</a></code>, then the block was too small to hold the internal arena structures.Allocate a (much) larger one, and try again. <code><a href="#mps_arena_create">mps_arena_create</a></code> returns<code><a href="#MPS_RES_FAIL">MPS_RES_FAIL</a></code>, if the MPS library is copy-protected by a security device, such as adongle, and a valid security device cannot be found.</p>
<h3>type <code><a id="mps_arena_class_t" name="mps_arena_class_t">mps_arena_class_t</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_arena_class_t">mps_arena_class_t</a></code></p>
<h4>Summary</h4>
<p>"m ps_arena_class_t " is the type of arena classes.</p>
<h4>Associated Protocols</h4>
<p>Arena.</p>
<h4>Type</h4>
<p><code>typedef struct mps_arena_s *mps_arena_t;</code></p>
<p><code><a href="#mps_arena_class_s">mps_arena_class_s</a></code> is an incomplete structure type used only to declare the opaque type <code><a href="#mps_arena_class_t">mps_arena_class_t</a></code>.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p><code><a href="#mps_arena_class_t">mps_arena_class_t</a></code> is the type of arena classes. It is opaque.</p>
<h4>Example</h4>
<p>The definition of the client arena class in the "mpsacl.h" header:</p>
<p><code>extern mps_arena_class_t mps_arena_class_cl(void);</code></p>
<h4>See Also</h4>
<h4>Notes</h4>
<p>None.</p>
<h3>function <code><a id="mps_arena_class_vm" name="mps_arena_class_vm">mps_arena_class_vm</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_arena_class_vm">mps_arena_class_vm</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_arena_class_vm">mps_arena_class_vm</a></code> returns the virtual memory arena class.</p>
<h4>Associated Protocols</h4>
<p>Arena.</p>
<h4>Syntax</h4>
<p><code>mps_arena_class_t mps_arena_class_vm(void)</code></p>
<h4>Arguments</h4>
<p>None.</p>
<h4>Returned Values</h4>
<p>Returns the virtual memory arena class.</p>
<h4>Resources</h4>
<p>mpsavm.h</p>
<h4>Description</h4>
<p>This function is used to get hold of the virtual memory arena class, for the purpose ofpassing it to <code><a href="#mps_arena_create">mps_arena_create</a></code>. The VM arenas use the OS virtual memory interfaces toallocate memory. The chief consequence of this is that the arena can manage many more virtualaddresses than it needs to commit memory to. This gives it flexibility as to where to place objects,which reduces fragmentation and helps make garbage collection more efficient.</p>
<p>This class is similar to <code><a href="#mps_arena_class_vmnz">mps_arena_class_vmnz</a></code> but uses a more complex placementpolicy, which is more suited to copying garbage collection.</p>
<h4>Example</h4>
<pre>
mps_arena_t arena;
int main(void)
{
mps_res_t res;
res = mps_arena_create(&amp;arena, mps_arena_class_vm(), ARENA_SIZE);
if(res != MPS_RES_OK) {
printf("Not enough memory!");
exit(1);
}
/* rest of program */
}
</pre>
<h4>Error Handling</h4>
<p>None.</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_arena_create">mps_arena_create</a></code>,
<code><a
href="#mps_arena_class_vmnz">mps_arena_class_vmnz</a></code></p>
<h4>Notes</h4>
<p>A virtual memory arena gets its managed memory from the operating system's virtual memoryservices. An initial address space size is passed when the arena is created. When creating a virtualmemory arena, <code><a href="#mps_arena_create">mps_arena_create</a></code> takes one extra argument:</p>
<pre>mps_res_t mps_arena_create(mps_arena_t *arena_o,
mps_arena_class_t arena_class_vm,
size_t size)</pre>
<p><code>size</code> is the initial amount of virtual address space, in bytes, that the arenawill reserve (this space is initially reserved so that the arena can subsequently use it withoutinterference from other parts of the program, but most of it is not committed, so it don't requireany RAM or backing store). The arena may allocate more virtual address space beyond this initialreservation as and when it deems it necessary. The MPS is most efficient if you reserve an addressspace that is several times larger than your peak memory usage.</p>
<p><code><a href="#mps_arena_create">mps_arena_create</a></code> returns <code><a href="#MPS_RES_RESOURCE">MPS_RES_RESOURCE</a></code> if it fails to reserveadequate address space to place the arena in; possibly other parts of the program are reserving toomuch virtual memory. It returns <code><a href="#MPS_RES_MEMORY">MPS_RES_MEMORY</a></code> when it fails to allocate memory for theinternal arena structures; either <code>size</code> was far too small or you ran out of swap space.It returns <code><a href="#MPS_RES_FAIL">MPS_RES_FAIL</a></code>, if the library is copy-protected by a security device, suchas a dongle, and a valid security device cannot be found.</p>
<p>Virtual memory arenas are not available on the Mac platforms, other than MacOS X. You willget a linking error, if you attempt to use this function.</p>
<h3>function <code><a id="mps_arena_class_vmnz" name="mps_arena_class_vmnz">mps_arena_class_vmnz</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_arena_class_vmnz">mps_arena_class_vmnz</a></code></p>
<h4>Summary</h4>
<p>An arena class like <code><a href="#mps_arena_class_vm">mps_arena_class_vm</a></code> but with a different placement policy.</p>
<h4>Associated Protocols</h4>
<p>Arena.</p>
<h4>Syntax</h4>
<p><code>mps_arena_class_t mps_arena_class_vmnz(void);</code></p>
<h4>Arguments</h4>
<p>None.</p>
<h4>Returned Values</h4>
<p>Returns the VMNZ arena class.</p>
<h4>Resources</h4>
<p>mpsavm.h</p>
<h4>Description</h4>
<p>Returns the VMNZ arena class (stands for Virtual Memory No Zones, if you really care.) Thisclass can be passed to <code><a href="#mps_arena_create">mps_arena_create</a></code> in order to create a VMNZ arena. The VMNZarenas use the OS virtual memory interfaces to allocate memory. The chief consequence of this isthat the arena can manage many more virtual addresses than it needs to commit memory to. This givesit flexibility as to where to place objects.</p>
<p>This class is similar to <code><a href="#mps_arena_class_vm">mps_arena_class_vm</a></code> but uses a simpler placementpolicy, that makes it slightly faster.</p>
<h4>Example</h4>
<pre>
mps_arena_t arena;
int main(void)
{
mps_res_t res;
res = mps_arena_create(&amp;arena, mps_arena_class_vmnz(), ARENA_SIZE);
if(res != MPS_RES_OK) {
printf("Not enough memory!");
exit(1);
}
/* rest of program */
}
</pre>
<p></p>
<h4>Error Handling</h4>
<p>No errors.</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_arena_create">mps_arena_create</a></code>,
<code><a href="#mps_arena_class_vm">mps_arena_class_vm</a></code></p>
<h4>Notes</h4>
<p>This class takes an extra argument when used in <code><a href="#mps_arena_create">mps_arena_create</a></code> (see example).The extra parameter should be of type <code>size_t</code>. It specifies the amount of virtualaddress space, in bytes, that this arena should use. The arena will reserve this amount of virtualaddress space from the OS during initialization. It will not subsequently use any more address space(compare with <code><a href="#mps_arena_class_vm">mps_arena_class_vm</a></code> which can grow).</p>
<p><code><a href="#mps_arena_create">mps_arena_create</a></code> returns <code><a href="#MPS_RES_RESOURCE">MPS_RES_RESOURCE</a></code> if it fails to reserveadequate address space to place the arena in; possibly other parts of the program are reserving toomuch virtual memory. It returns <code><a href="#MPS_RES_MEMORY">MPS_RES_MEMORY</a></code> when it fails to allocate memory for theinternal arena structures; either <code>size</code> was far too small or you ran out of swap space.It returns <code><a href="#MPS_RES_FAIL">MPS_RES_FAIL</a></code>, if the library is copy-protected by a security device, suchas a dongle, and a valid security device cannot be found.</p>
<p>Virtual memory arenas are not available on the Mac platforms, other than MacOS X. You willget a linking error, if you attempt to use this function.</p>
<h3>function <code><a id="mps_arena_collect" name="mps_arena_collect">mps_arena_collect</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_arena_collect">mps_arena_collect</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_arena_collect">mps_arena_collect</a></code> collects the arena and puts it in the parked state.</p>
<h4>Associated Protocols</h4>
<p>Arena.</p>
<h4>Syntax</h4>
<p><code>void mps_arena_collect(mps_arena_t arena);</code></p>
<h4>Arguments</h4>
<p>arena the arena to collect</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p><code><a href="#mps_arena_collect">mps_arena_collect</a></code> collects the arena and puts it in the parked state. Collecting the arenaattempts to recycle as many unreachable objects as possible and reduce the size of the arena as muchas possible (though in some cases it may increase because it becomes more fragmented). If you do notwant the arena to be in the parked state, you must explicitly call <code><a href="#mps_arena_release">mps_arena_release</a></code> after<code><a href="#mps_arena_collect">mps_arena_collect</a></code>.</p>
<p>Note that the collector may not be able to recycle some objects (such as those near thedestination of ambiguous references) even though they are not reachable.</p>
<h4>Example</h4>
<p>[missing]</p>
<h4>Error Handling</h4>
<p>No errors.</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_arena_park">mps_arena_park</a></code>,
<code><a href="#mps_arena_release">mps_arena_release</a></code></p>
<h4>Notes</h4>
<p>None.</p>
<h3>function <code><a id="mps_arena_commit_limit" name="mps_arena_commit_limit">mps_arena_commit_limit</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_arena_commit_limit">mps_arena_commit_limit</a></code></p>
<h4>Summary</h4>
<p>Returns the current commit limit associated with the arena in bytes.</p>
<h4>Associated Protocols</h4>
<p>Arena</p>
<h4>Type</h4>
<p><code>size_t mps_arena_commit_limit(mps_arena_t arena)</code></p>
<h4>Arguments</h4>
<p>arena -- the arena</p>
<h4>Returned Values</h4>
<p>Returns the current commit limit as a number of bytes in a size_t</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>Returns the current commit limit associated with the arena in bytes. The commit limit can bechanged using the function <code><a href="#mps_commit_limit_set">mps_commit_limit_set</a></code>. The commit limit is used to control how much memorythe MPS can obtain from the OS. See Arena Protocol for details.</p>
<h4>Example</h4>
<p><code>limit = mps_arena_commit_limit(arena);</code></p>
<h4>Error Handling</h4>
<p>No errors.</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_arena_committed">mps_arena_committed</a></code>,
<code><a
href="#mps_arena_commit_limit_set">mps_arena_commit_limit_set</a></code></p>
<h4>Notes</h4>
<p>None.</p>
<h3>function <code><a id="mps_arena_commit_limit_set" name="mps_arena_commit_limit_set">mps_arena_commit_limit_set</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_arena_commit_limit_set">mps_arena_commit_limit_set</a></code></p>
<h4>Summary</h4>
<p>Changes the current commit limit associated with the arena.</p>
<h4>Associated Protocols</h4>
<p>Arena</p>
<h4>Type</h4>
<p><code>mps_res_t mps_arena_commit_limit_set(mps_arena_t arena, size_t limit)</code></p>
<h4>Arguments</h4>
<p>arena -- the arena</p>
<p>limit -- the new commit limit in bytes</p>
<h4>Returned Values</h4>
<p>Returns a result code.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>The commit limit of the arena is set to the limit given. The commit limit controls how muchmemory the MPS will obtain from the OS. See Arena Protocol for details. The commit limit cannot beset to a value that is lower than the number of bytes that the MPS is using. If an attempt is madeto set the commit limit to a value greater than or equal to that returned by<code><a href="#mps_arena_committed">mps_arena_committed</a></code> then it will succeed. If an attempt is made to set the commit limitto a value less than that returned by <code><a href="#mps_arena_committed">mps_arena_committed</a></code> then it will succeed only ifthe amount committed by the MPS can be reduced by reducing the amount of spare committed memory; insuch a case the spare committed memory will be reduced appropriately and the attempt will succeed.</p>
<h4>Example</h4>
<pre>
do {
res = mps_arena_commit_limit_set(arena, limit - 100 * 1024);
if(res != MPS_RES_OK)
flush_caches();
} while(res != MPS_RES_OK);
</pre>
<h4>Error Handling</h4>
<p>Returns <code><a href="#MPS_RES_OK">MPS_RES_OK</a></code> when successful, and some other result code when not.</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_arena_committed">mps_arena_committed</a></code>,
<code><a
href="#mps_arena_commit_limit">mps_arena_commit_limit</a></code>,
<code><a
href="#mps_arena_spare_commit_limit_set">mps_arena_spare_commit_limit_set</a></code></p>
<h4>Notes</h4>
<p><code><a href="#mps_arena_commit_limit_set">mps_arena_commit_limit_set</a></code> puts a limit on all memory committed by the MPS. The"spare committed" memory can be limited separately with <code><a href="#mps_arena_spare_commit_limit_set">mps_arena_spare_commit_limit_set</a></code>. Note that "spare committed" memory is subject toboth limits; there cannot be more spare committed memory than the spare commit limit, and therecan't be so much spare committed memory that there is more committed memory than the commit limit.</p>
<h3>Function <code><a id="mps_arena_committed" name="mps_arena_committed">mps_arena_committed</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_arena_committed">mps_arena_committed</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_arena_committed">mps_arena_committed</a></code> returns the amount of memory (backing store) in use by the arena, bothfor storing client objects and for its own data structures.</p>
<h4>Associated Protocols</h4>
<p>Arena.</p>
<h4>Syntax</h4>
<p><code>extern size_t mps_arena_committed(mps_arena_t arena)</code></p>
<h4>Arguments</h4>
<p>arena -- the arena</p>
<h4>Returned Values</h4>
<p>Returns a number of bytes (the amount of committed memory) as a size_t.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p><code><a href="#mps_arena_committed">mps_arena_committed</a></code> returns the amount of memory (backing store) in use by the arena (alsoknown as "committed memory"). The value returned is a number of bytes.</p>
<p>Committed memory may be used both for storing client objects and for storing MPS datastructures. In addition the MPS maintains committed memory which is not being used (for either ofthe above purposes). This memory is known as "spare committed" memory (see <code><a href="#mps_arena_spare_committed">mps_arena_spare_committed</a></code>). The amount of "spare committed" memory can change atany time, in particular in will be reduced as appropriate in order meet client requests.</p>
<p>The reasons that the committed memory (as return by this function) might be large than thesum of the sizes of client allocated objects are:</p>
<ul>
<li><p>some memory is used internally by the MPS to manage its own data structures and to recordinformation about client objects (such as free lists, page tables, colour tables, statistics, etc).</p></li>
<li><p>operating systems (and hardware) typically restrict programs to requesting and releasingmemory with a certain granularity (for example, pages), so extra memory is committed when thisrounding is necessary.</p></li>
<li><p>there might be "spare committed" memory.</p></li>
</ul>
<p>The amount of committed memory is a good measure of how much virtual memory resource ("swapspace") the MPS is using from the OS.</p>
<p>This function may be called whether the arena is unclamped, clamped or parked, if calledwhen the arena in unclamped then the value may change after this function returns. A possible usemight be to call it just after <code><a href="#mps_arena_collect">mps_arena_collect</a></code> to (over-)estimate the size of the heap.</p>
<p>If you want to know how much memory the MPS is using then you're probably interested in the value <code>mps_arena_committed() - mps_arena_spare_committed()</code>.</p>
<p>The amount of committed memory can be limited with the function <code><a href="#mps_arena_commit_limit">mps_arena_commit_limit</a></code>.</p>
<h4>Example</h4>
<h4>Error Handling</h4>
<h4>See Also</h4>
<p>
<code><a href="#mps_arena_collect">mps_arena_collect</a></code>,
<code><a href="#mps_arena_clamp">mps_arena_clamp</a></code>,
<code><a href="#mps_arena_park">mps_arena_park</a></code>,
<code><a href="#mps_arena_release">mps_arena_release</a></code></p>
<h4>Notes</h4>
<p>-</p>
<h3>function <code><a id="mps_arena_create" name="mps_arena_create">mps_arena_create</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_arena_create">mps_arena_create</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_arena_create">mps_arena_create</a></code> is used to create an arena.</p>
<h4>Associated Protocols</h4>
<p>Arena.</p>
<h4>Syntax</h4>
<p><code>mps_res_t mps_arena_create(mps_arena_t *mps_arena_o, mps_arena_class_t mps_arena_class, ...)</code></p>
<h4>Arguments</h4>
<p><code><a href="#mps_arena_o">mps_arena_o</a></code> pointer to a variable to store the new arena in</p>
<p><code><a href="#mps_arena_class">mps_arena_class</a></code> the arena class</p>
<p><code>...</code> initialization arguments for the arena class</p>
<h4>Initial/Default Values</h4>
<p>Different for each arena class. See <code>mps_arena_class_*</code>.</p>
<h4>Returned Values</h4>
<p>If the return value is <code><a href="#MPS_RES_OK">MPS_RES_OK</a></code>, the new arena is in <code>*mps_arena_o</code>.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p><code><a href="#mps_arena_create">mps_arena_create</a></code> is used to create an arena.</p>
<h4>Example</h4>
<pre>
mps_arena_t arena;
int main(void)
{
mps_res_t res;
res = mps_arena_create(&amp;arena, mps_arena_class_vm(), ARENA_SIZE);
if(res != MPS_ RES_OK) {
printf("Not enough memory!");
exit(1);
}
/* rest of program */
}
</pre>
<h4>Error Handling</h4>
<p><code><a href="#mps_arena_create">mps_arena_create</a></code> returns <code><a href="#MPS_RES_FAIL">MPS_RES_FAIL</a></code>, if the MPS library iscopy-protected by a security device, such as a dongle, and a valid security device cannot be found.Other error codes are specific to each arena class. See <code>mps_arena_class_*</code>.</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_arena_create_v">mps_arena_create_v</a></code>,
<code>mps_arena_class_*</code>,
<code><a href="#mps_arena_destroy">mps_arena_destroy</a></code></p>
<h3>function <code><a id="mps_arena_create_v" name="mps_arena_create_v">mps_arena_create_v</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_arena_create_v">mps_arena_create_v</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_arena_create_v">mps_arena_create_v</a></code> is used to create an arena.</p>
<h4>Associated Protocols</h4>
<p>Arena.</p>
<h4>Syntax</h4>
<p><code>mps_res_t mps_arena_create_v(mps_arena_t *mps_arena_o, mps_arena_class_t mps_arena_class, va_list args)</code></p>
<h4>Arguments</h4>
<p><code><a href="#mps_arena_o">mps_arena_o</a></code> pointer to a variable to store the new arena in</p>
<p><code><a href="#mps_arena_class">mps_arena_class</a></code> the arena class</p>
<p><code>args</code> initialization arguments for the arena class</p>
<h4>Initial/Default Values</h4>
<p>Different for each arena class. See <code>mps_arena_class_*</code>.</p>
<h4>Returned Values</h4>
<p>If the return value is <code><a href="#MPS_RES_OK">MPS_RES_OK</a></code>, the new arena is in <code>*mps_arena_o</code>.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p><code><a href="#mps_arena_create_v">mps_arena_create_v</a></code> is used to create an arena. It is exactly the same as <code><a href="#mps_arena_create">mps_arena_create</a></code>, except that it takes the arena class initialization arguments in a <code>va_list </code>.</p>
<h4>Error Handling</h4>
<p><code><a href="#mps_arena_create_v">mps_arena_create_v</a></code> returns <code><a href="#MPS_RES_FAIL">MPS_RES_FAIL</a></code>, if the MPS library is copy-protected by a security device, such as a dongle, and a valid security device cannot be found. Other error codes are specific to each arena class. See <code>mps_arena_class_*</code>.</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_arena_create">mps_arena_create</a></code>,
<code>mps_arena_class_*</code>,
<code><a href="#mps_arena_destroy">mps_arena_destroy</a></code></p>
<h3>function <code><a id="mps_arena_formatted_objects_walk" name="mps_arena_formatted_objects_walk">mps_arena_formatted_objects_walk</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_arena_formatted_objects_walk">mps_arena_formatted_objects_walk</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_arena_formatted_objects_walk">mps_arena_formatted_objects_walk</a></code> is used to iterate over all formatted objects in the MPS heap.</p>
<h4>Associated Protocols</h4>
<p>None.</p>
<h4>Syntax</h4>
<p><code>mps_arena_formatted_objects_walk(mps_arena, client_step_function, client_step_closure_p,client_step_closure_s);</code></p>
<h4>Type</h4>
<pre>
extern void mps_arena_formatted_objects_walk(mps_arena_t,
mps_formatted_objects_stepper_t, void *,
size_t);
</pre>
<h4>Arguments</h4>
<p><code>(mps_arena_t mps_arena, mps_formatted_objects_stepper_t stepper, void *p, size_t s)</code></p>
<p><code><a href="#mps_arena">mps_arena</a></code> in an MPS arena object.</p>
<p><code>stepper</code> is a client-supplied function (pointer) of the right type (see <code><a href="#mps_formatted_objects_stepper_t">mps_formatted_objects_stepper_t</a></code>). This function is applied to every object in allformatted pools. This function should take the argument list <code>(mps_addr_t object, mps_fmt_t format,mps_pool_t pool, void *p, size_t s)</code>. <code>object</code> is the object to which the function is being applied. <code>format</code> is the format (an MPS format object) of the object, <code>pool</code> is the pool in which the object resides, <code>p</code> and <code>s</code> are copies of the corresponding values that the client passed into <code><a href="#mps_arena_formatted_objects_walk">mps_arena_formatted_objects_walk</a></code> originally.</p>
<p><code>p</code> and <code>s</code> are passed into the function specified by the stepper argument whenever the MPS calls that function. See <code><a href="#mps_formatted_objects_stepper_t">mps_formatted_objects_stepper_t</a></code>.</p>
<h4>Returned Values</h4>
<p>None.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p><code><a href="#mps_arena_formatted_objects_walk">mps_arena_formatted_objects_walk</a></code> is used to iterate over all formatted objects in the MPSheap. A client-supplied function is called for every object in all formatted pools; the object, theformat, and the pool are passed to the user supplied function, as well as some closure variables.</p>
<p>Applies stepper function to a pool-class-specific collection of objects (that is, the poolclass determines which objects in its instances get walked). Typically pool classes will arrangethat all validly formatted objects are walked. During a trace this will in general be only the blackobjects, though the leaf pool class (LO), for example, will walk all objects since they are validlyformatted whether they are black or white. Padding objects may be walked at the pool classesdiscretion, the client should handle this case.</p>
<h4>Example</h4>
<p>[not yet]</p>
<h4>Error Handling</h4>
<p>There are none.</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_amc_apply">mps_amc_apply</a></code> (the
historical walker),
<code><a
href="#mps_formatted_objects_stepper_t">mps_formatted_objects_stepper_t</a></code></p>
<h4>Notes</h4>
<h3>function <code><a id="mps_arena_park" name="mps_arena_park">mps_arena_park</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_arena_park">mps_arena_park</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_arena_park">mps_arena_park</a></code> puts the specified arena into the parked state.</p>
<h4>Associated Protocols</h4>
<p>Arena.</p>
<h4>Syntax</h4>
<p><code>extern void mps_arena_park(mps_arena_t arena);</code></p>
<h4>Arguments</h4>
<p><code>arena</code> the arena to park</p>
<h4>Returned Values</h4>
<p>None.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p><code><a href="#mps_arena_park">mps_arena_park</a></code> puts the specified arena into the parked state. While an arena is parked,no object motion will occur and the staleness of location dependencies will not change. Allreferences to objects loaded while the arena is parked will keep the same binary representationuntil after it is released.</p>
<p>Any current collection is run to completion before the arena is parked, and no newcollections will start. When an arena is in the parked state, it is necessarily not in the middle ofa collection.</p>
<h4>Example</h4>
<h4>Error Handling</h4>
<p>Can't fail.</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_arena_clamp">mps_arena_clamp</a></code>,
<code><a href="#mps_arena_release">mps_arena_release</a></code></p>
<h4>Notes</h4>
<p>None.</p>
<h3>function <code><a id="mps_arena_release" name="mps_arena_release">mps_arena_release</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_arena_release">mps_arena_release</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_arena_release">mps_arena_release</a></code> puts the specified arena into the unclamped state.</p>
<h4>Associated Protocols</h4>
<p>Arena.</p>
<h4>Syntax</h4>
<p><code>extern void mps_arena_release(mps_arena_t);</code></p>
<h4>Arguments</h4>
<h4>Returned Values</h4>
<p>None.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p><code><a href="#mps_arena_release">mps_arena_release</a></code> puts the specified arena into the unclamped state. While an arena isunclamped, garbage collection, object motion, and other background activity can take place.</p>
<h4>Example</h4>
<h4>Error Handling</h4>
<p>Can't fail.</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_arena_clamp">mps_arena_clamp</a></code>,
<code><a href="#mps_arena_park">mps_arena_park</a></code></p>
<h4>Notes</h4>
<p>None.</p>
<h3>function <code><a id="mps_arena_roots_walk" name="mps_arena_roots_walk">mps_arena_roots_walk</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_arena_roots_walk">mps_arena_roots_walk</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_arena_roots_walk">mps_arena_roots_walk</a></code> is used to iterate over all roots of the MPS heap.</p>
<h4>Associated Protocols</h4>
<p>None.</p>
<h4>Syntax</h4>
<p><code>mps_arena_roots_walk(mps_arena, client_step_function, client_step_closure_p,client_step_closure_s);</code></p>
<h4>Type</h4>
<pre>
extern void mps_arena_roots_walk(mps_arena_t,
mps_roots_stepper_t, void *,
size_t);
</pre>
<h4>Arguments</h4>
<p><code>(mps_arena_t mps_arena, mps_roots_stepper_t stepper, void *p, size_t s) </code></p>
<p><code><a href="#mps_arena">mps_arena</a></code> in an MPS arena object.</p>
<p><code>stepper</code> is a client-supplied function (pointer) of the right type (see <code><a href="#mps_roots_stepper_t">mps_roots_stepper_t</a></code>). This function is applied to every reference to the heap fromevery root object registered with the arena. This function should take the argument list <code>(mps_addr_t *ref, mps_root_t root, void *p, size_t s)</code>. <code>ref</code> is the address of a root which references an object in the arena. <code>root</code> is the registered root (an MPS root object) of which <code>ref</code> is a single reference, <code>p</code> and <code>s</code> are copies of the corresponding values that the client passed into <code><a href="#mps_arena_roots_walk">mps_arena_roots_walk</a></code> originally.</p>
<p><code>p</code> and <code>s</code> are passed into the function specified by the stepper argument whenever the MPS calls that function. See <code><a href="#mps_roots_stepper_t">mps_roots_stepper_t</a></code></p>
<h4>Returned Values</h4>
<p>None.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p><code><a href="#mps_arena_roots_walk">mps_arena_roots_walk</a></code> is used to iterate over all roots of the MPS heap. A client-suppliedfunction is called for every root reference which points to an object in any automatically managedpools; the address of the root reference and the MPS root object are passed to the user suppliedfunction, as well as some closure variables.</p>
<p>May only be called when the arena is in the parked state.</p>
<p>Applies stepper to each reference in any roots registered with the arena and which point toobjects in automatically managed pools. If the root has rank <code><a href="#MPS_RANK_AMBIG">MPS_RANK_AMBIG</a></code> then the reference mightnot be to the start of an object; the client should handle this case. There is no guarantee that thereference corresponds to the actual location that holds the pointer to the object (since this mightbe a register, for example) - but the actual location will be passed if possible. This may aidanalysis of roots via a debugger.</p>
<p></p>
<h4>Example</h4>
<p>[not yet]</p>
<h4>Error Handling</h4>
<p>There are none.</p>
<h4>See Also</h4>
<p>
<code><a
href="#mps_roots_stepper_t">mps_roots_stepper_t</a></code></p>
<p>
<code><a
href="#mps_arena_formatted_objects_walk">mps_arena_formatted_objects_walk</a></code></p>
<h4>Notes</h4>
<h3>function <code><a id="mps_arena_spare_commit_limit" name="mps_arena_spare_commit_limit">mps_arena_spare_commit_limit</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_arena_spare_commit_limit">mps_arena_spare_commit_limit</a></code></p>
<h4>Summary</h4>
<p>Retrieves the value of the spare commit limit (previously set with <code><a href="#mps_arena_spare_commit_limit_set">mps_arena_spare_commit_limit_set</a></code>).</p>
<h4>Associated Protocols</h4>
<p>Arena.</p>
<h4>Type</h4>
<p><code>extern size_t mps_arena_spare_commit_limit(mps_arena_t arena)</code></p>
<h4>Arguments</h4>
<p><code><a href="#mps_arena_t">mps_arena_t</a></code> arena</p>
<p>Specifies the arena to retrieve the spare commit limit of.</p>
<h4>Returned Values</h4>
<p>Returns, as a size_t, the value of the spare commit limit.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>Returns the current value of the spare commit limit which is the value most recently setwith <code><a href="#mps_arena_spare_commit_limit_set">mps_arena_spare_commit_limit_set</a></code>. (See <code><a href="#mps_arena_spare_commit_limit_set">mps_arena_spare_commit_limit_set</a></code> fordetails).</p>
<h4>Example</h4>
<p>[missing]</p>
<h4>Error Handling</h4>
<p>There are no errors.</p>
<h4>See Also</h4>
<p>
<code><a
href="#mps_arena_spare_commit_limit_set">mps_arena_spare_commit_limit_set</a></code></p>
<h4>Notes</h4>
<p>None.</p>
<h3>function <code><a id="mps_arena_spare_commit_limit_set" name="mps_arena_spare_commit_limit_set">mps_arena_spare_commit_limit_set</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_arena_spare_commit_limit_set">mps_arena_spare_commit_limit_set</a></code></p>
<h4>Summary</h4>
<p>Sets the limit of the amount of spare committed memory.</p>
<h4>Associated Protocols</h4>
<p>Arena.</p>
<h4>Type</h4>
<p><code>extern void mps_arena_spare_commit_limit_set(mps_arena_t arena, size_t limit)</code></p>
<h4>Arguments</h4>
<p><code><a href="#mps_arena_t">mps_arena_t</a></code> arena</p>
<p>The arena to which the new limit should apply.</p>
<p>size_t limit</p>
<p>The value of the new limit (specified in bytes).</p>
<h4>Resources</h4>
<p>mps.h</p>
<p></p>
<h4>Description</h4>
<p>The limit argument specifies a new "spare commit limit". The spare commit limit specifiesthe maximum amount of bytes of "spare committed" memory the MPS is allowed to have. Setting it to avalue lower than the current amount of spare committed memory would immediately cause sufficientspare committed memory to be uncommitted so as to bring the value under the limit. In particularsetting to 0 will mean that the MPS will have no "spare committed" memory.</p>
<p>"spare committed" memory is the term for describing memory which the arena is managing asfree memory (so not in use by any pool and not otherwise in use for obscure internal reasons) butwhich remains committed (mapped from the OS). It is used by the arena to (attempt to) avoid callingthe OS to repeatedly unmap and map areas of VM. "spare committed" memory is counted as committedmemory as counted by <code><a href="#mps_arena_committed">mps_arena_committed</a></code> and restricted by <code><a href="#mps_arena_commit_limit">mps_arena_commit_limit</a></code>.</p>
<p>Non-VM arenas do not have this concept, but they support the two functions <code><a href="#mps_arena_spare_commit_limit">mps_arena_spare_commit_limit</a></code> and <code><a href="#mps_arena_spare_commit_limit_set">mps_arena_spare_commit_limit_set</a></code>. The functions simply get andretrieve a value but do nothing else in that case.</p>
<p>Initially the value is some configuration-dependent value.</p>
<p>The value of the limit can be retrieved with <code><a href="#mps_arena_spare_commit_limit">mps_arena_spare_commit_limit</a></code>.</p>
<h4>Example</h4>
<p>[missing]</p>
<h4>Error Handling</h4>
<p>There are no errors.</p>
<h4>See Also</h4>
<p>
<code><a
href="#mps_arena_spare_commit_limit">mps_arena_spare_commit_limit</a></code></p>
<h4>Notes</h4>
<p>None.</p>
<h3>function <code><a id="mps_arena_spare_committed" name="mps_arena_spare_committed">mps_arena_spare_committed</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_arena_spare_committed">mps_arena_spare_committed</a></code></p>
<h4>Summary</h4>
<p>Returns the number of bytes of spare committed memory.</p>
<h4>Associated Protocols</h4>
<p>Memory</p>
<h4>Type</h4>
<p><code>size_t mps_arena_spare_committed(mps_arena_t);</code></p>
<h4>Arguments</h4>
<p><code><a href="#mps_arena_t">mps_arena_t</a></code> <code><a href="#mps_arena">mps_arena</a></code></p>
<p>The arena to which the query applies.</p>
<h4>Returned Values</h4>
<p>Returns the number of bytes of spare committed memory.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>"Spare committed" memory is the term for describing memory which the arena is committed fromthe OS but which is free (so not in use by any pool and not otherwise in use for obscure internalreasons). It is used by the arena to (attempt to) avoid calling the OS to repeatedly uncommit andcommit areas of VM (because calling the OS to commit and uncommit memory is typically expensive)."Spare committed" memory can be used for grant client requests; if this is done when the MPS wouldotherwise have had to call the OS to commit more memory then the MPS has avoid some OS calls.</p>
<p>"spare committed" memory is counted as part of committed memory. The amount of committedmemory can be retrieved with <code><a href="#mps_arena_committed">mps_arena_committed</a></code> (see <code><a href="#mps_arena_committed">mps_arena_committed</a></code>).</p>
<p>The amount of "spare committed" memory can be limited by using <code><a href="#mps_arena_spare_commit_limit_set">mps_arena_spare_commit_limit_set</a></code> (see <code><a href="#mps_arena_spare_commit_limit_set">mps_arena_spare_commit_limit_set</a></code> ), and the valueof that limit can be retrieved with <code><a href="#mps_arena_spare_commit_limit">mps_arena_spare_commit_limit</a></code> (see <code><a href="#mps_arena_spare_commit_limit">mps_arena_spare_commit_limit</a></code> ). This is analogous to the functions for limiting theamount of committed memory.</p>
<h4>Example</h4>
<p>[missing]</p>
<h4>Error Handling</h4>
<p>[missing]</p>
<h4>See Also</h4>
<p>
<code><a
href="#mps_arena_spare_commit_limit_set">mps_arena_spare_commit_limit_set</a></code>,
<code><a
href="#mps_arena_spare_commit_limit">mps_arena_spare_commit_limit</a></code></p>
<h4>Notes</h4>
<p>None.</p>
<h3>function <code><a id="mps_bool_t" name="mps_bool_t">mps_bool_t</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_bool_t">mps_bool_t</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_bool_t">mps_bool_t</a></code> is a transparent type, equivalent to <code>int</code>, that is used in the MPS C interfaceto indicate that a boolean value is intended.</p>
<h4>Associated Protocols</h4>
<p>Not applicable.</p>
<h4>Syntax</h4>
<p>Not applicable.</p>
<h4>Structure</h4>
<p>Not applicable.</p>
<h4>Type</h4>
<p><code>typedef int mps_bool_t;</code></p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>When used as an input parameter to the MPS, a value of 0 indicates "false" and any othervalue indicates "true". As an output parameter or function return from the MPS, 0 indicates "false",and 1 indicates "true". Note that an <code><a href="#mps_bool_t">mps_bool_t</a></code> value can be used in a conditional context, suchas in an "if" statement.</p>
<h4>Example</h4>
<pre>
if(mps_ld_isstale(&amp;ld, space, obj)) {
mps_ld_reset(&amp;ld, space);
mps_ld_add(&amp;ld, space, obj);
}
</pre>
<h4>See Also</h4>
<h4>Notes</h4>
<p>None.</p>
<h3>function <code><a id="mps_class_amc" name="mps_class_amc">mps_class_amc</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_class_amc">mps_class_amc</a></code></p>
<p></p>
<h4>Summary</h4>
<p><code><a href="#mps_class_amc">mps_class_amc</a></code> returns the pool class object for the Automatic Mostly Copying pool class.</p>
<h4>Associated Protocols</h4>
<p>Pool</p>
<h4>Syntax</h4>
<p><code>mps_class_t mps_class_amc(void)</code></p>
<h4>Arguments</h4>
<p>No arguments.</p>
<h4>Returned Values</h4>
<p>Returns a pool class object.</p>
<h4>Resources</h4>
<p>mpscamc.h</p>
<h4>Description</h4>
<p>This function returns an object of type <code><a href="#mps_class_t">mps_class_t</a></code> which represents the Automatic MostlyCopying pool class.</p>
<p>This pool class requires an extra argument when used in <code><a href="#mps_pool_create">mps_pool_create</a></code>:</p>
<pre> res = mps_pool_create(&amp;pool, arena, mps_class_amc(), format); </pre>
<p>The extra argument, format, should be of type <code><a href="#mps_fmt_t">mps_fmt_t</a></code> and specifies the format of theobjects allocated in the pool.</p>
<p>An AMC pool is both scannable and collectable. Objects may contain exact references to otherobjects that will preserve such other objects. Objects may be reclaimed if they are not reachablefrom a root. Objects may move during collection, unless reachable via a (direct) ambiguousreference. Objects in an AMC pool may be registered for finalization. Exact (that is, non-ambiguous)references into an object in an AMC pool must be to the start of the object.</p>
<p>The AMC pool class exploits assumptions about object lifetimes and inter-connectionvariously referred to as "the generational hypothesis". In particular, the following tendencies willbe efficiently exploited by such a pool:</p>
<p>- Most objects die young;</p>
<p>- Objects that don't die young will live a long time;</p>
<p>- Most references are backwards in time.</p>
<p><code><a href="#mps_ap_frame_push">mps_ap_frame_push</a></code> and <code><a href="#mps_ap_frame_pop">mps_ap_frame_pop</a></code> may be used on an allocation point in an AMC pool.They do not declare the affected objects to be definitely dead (compare with the SNC pool class),but have an undefined effect on the collection strategy.</p>
<p>If an allocation point is created in an AMC pool, the call to <code><a href="#mps_ap_create">mps_ap_create</a></code> will take noadditional parameters.</p>
<p></p>
<h4>Example</h4>
<h4>See Also</h4>
<p>
<code><a href="#mps_ap_frame_pop">mps_ap_frame_pop</a></code>,
<code><a href="#mps_ap_frame_push">mps_ap_frame_push</a></code>,
<code><a href="#mps_ap_create">mps_ap_create</a></code></p>
<h3>function <code><a id="mps_class_mvff" name="mps_class_mvff">mps_class_mvff</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_class_mvff">mps_class_mvff</a></code></p>
<p></p>
<h4>Summary</h4>
<p>Used as a parameter to <code><a href="#mps_pool_create">mps_pool_create</a></code> to create an MVFF pool.</p>
<h4>Associated Protocols</h4>
<p>Pool, Allocation Points.</p>
<h4>Type</h4>
<p><code>mps_class_t mps_class_mvff(void)</code></p>
<h4>Arguments</h4>
<p>None.</p>
<h4>Returned Values</h4>
<p>The function returns a class object that can be passed to <code><a href="#mps_pool_create">mps_pool_create</a></code>.</p>
<h4>Resources</h4>
<p>mpscmvff.h</p>
<h4>Description</h4>
<p>MVFF pools implement a first-fit policy. The pool requires six
parameters to pool creation:</p>
<ul>
<li><p><code><a href="#mps_size_t">mps_size_t</a></code> extendBy -- The size of segment to allocate by default;</p></li>
<li><p><code><a href="#mps_size_t">mps_size_t</a></code> avgSize -- The average size of objects to be allocated;</p></li>
<li><p><code><a href="#mps_align_t">mps_align_t</a></code> alignment -- The alignment of addresses for allocation (and freeing) in thepool;</p></li>
<li><p><code><a href="#mps_bool_t">mps_bool_t</a></code> slotHigh</p></li>
<li><p><code><a href="#mps_bool_t">mps_bool_t</a></code> arenaHigh</p></li>
<li><p><code><a href="#mps_bool_t">mps_bool_t</a></code> firstFit</p></li>
</ul>
<p>
The alignment is the alignment of ranges that can be allocated and freed. If an unalignedsize is passed to <code><a href="#mps_alloc">mps_alloc</a></code> or <code><a href="#mps_free">mps_free</a></code>, it will be rounded up to the pool's alignment. The minimumalignment supported by pools of this class is
<code>
sizeof(void *)</code>.
</p>
<p>The three boolean parameters may be set to (0, 0, 1) or (1, 1, 1). No other settings of these parameters is currently recommended.</p>
<p>Buffered allocation (<code><a href="#mps_reserve">mps_reserve</a></code> and <code><a href="#mps_commit">mps_commit</a></code>) is also supported, but in that case, thepolicy is rather different: buffers are filled worst-fit, and allocation is always upwards from thebase. The arenaHigh parameter regulates whether new segments are acquired at high or low addresses;the slotHigh and firstFit parameters do not affect buffered allocation. Buffered and unbufferedallocation can be used at the same time, but in that case, the first allocation point must becreated before any call to <code><a href="#mps_alloc">mps_alloc</a></code>.</p>
<p>Cached allocation ( <code><a href="#MPS_SAC_ALLOC">MPS_SAC_ALLOC</a></code> and <code><a href="#MPS_SAC_FREE">MPS_SAC_FREE</a></code> ) is also supported, but in that case,the policy is a little different: allocation from the cache follows its own policy (typicallyfirst-fit), and only when the cache needs to acquire more blocks from the underlying MVFF pool doesit use the usual algorithm to choose blocks for the cache.</p>
<h4>Example</h4>
<pre>
if(mps_pool_create(&amp;pool, arena, mps_class_mvff(), 8 * 1024, 135, 4, 0, 0, 1)
!= MPS_RES_OK) {
printf("Error creating pool!");
exit(2);
}
</pre>
<h4>See Also</h4>
<p>
<code><a href="#mps_pool_create">mps_pool_create</a></code>,
<code><a href="#mps_reserve">mps_reserve</a></code>,
<code><a href="#mps_commit">mps_commit</a></code>.</p>
<h4>Notes</h4>
<p>It is usually not advisable to use buffered and unbuffered allocationat the same time,because the worst-fit policy of buffer filling will grab all the large blocks, leading to severefragmentation. Use two separate pools instead.</p>
<p>Note that using buffered allocation prevents (for obscure technical reasons) the pool fromallocating across segment boundaries. This can cause added external fragmentation if objects areallocated that are a significant fraction of the segment size. (This quirk will disappear in afuture version.)</p>
<h3>function <code><a id="mps_class_snc" name="mps_class_snc">mps_class_snc</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_class_snc">mps_class_snc</a></code></p>
<p></p>
<h4>Summary</h4>
<p>Returns the pool class object (of type <code><a href="#mps_class_t">mps_class_t</a></code>) for the Stack No Check pool class.</p>
<h4>Associated Protocols</h4>
<p>Pool.</p>
<h4>Syntax</h4>
<p><code>mps_class_t mps_class_snc(void)</code></p>
<h4>Arguments</h4>
<p>No arguments.</p>
<h4>Returned Values</h4>
<p>Returns a pool class object.</p>
<h4>Resources</h4>
<p>mpscsnc.h</p>
<h4>Description</h4>
<p>This function returns an object of type <code><a href="#mps_class_t">mps_class_t</a></code> which represents the Stack No Check poolclass.</p>
<p>This pool class requires an extra argument when used in <code><a href="#mps_pool_create">mps_pool_create</a></code>:</p>
<pre> res = mps_pool_create(&amp;pool, arena, mps_class_snc(), format); </pre>
<p>The extra argument, format, should be of type <code><a href="#mps_fmt_t">mps_fmt_t</a></code> and specifies the format of theobjects allocated in the pool (in a similar way to <code><a href="#mps_class_amc">mps_class_amc</a></code>). The format should provide atleast the methods: scan, skip, pad.</p>
<p>An SNC pool is scannable, in that objects may contain references to objects in other poolsthat will keep those objects alive (depending on rank). In this sense, an SNC pool is a de-factoroot.</p>
<p>Exact references may point to (the start of) objects in an SNC pool, but will have no effecton whether those objects are either scanned or kept alive.</p>
<p>If <code><a href="#mps_ap_frame_pop">mps_ap_frame_pop</a></code> is used on an allocation point in an SNC pool (after a correspondingcall to <code><a href="#mps_ap_frame_push">mps_ap_frame_push</a></code>), then the objects affected by the pop are effectively declared dead, andmay be reclaimed by the collector. Extant references to such objects from reachable or de factoalive objects are safe, but such other objects should be dead; that is, such references must neverbe used.</p>
<p>If an allocation point is created in an SNC pool, then the call to <code><a href="#mps_ap_create">mps_ap_create</a></code> will takeas an additional parameter the rank (of type <code><a href="#mps_rank_t">mps_rank_t</a></code>) of references in the objects to be createdin that allocation point. Currently, only rank exact (<code><a href="#mps_rank_exact">mps_rank_exact</a></code>) is supported.</p>
<p>Objects in an SNC pool may not be registered for finalization.</p>
<p>Objects in an SNC pool will not move.</p>
<p></p>
<h4>Example</h4>
<h4>Nya</h4>
<h4>Error Handling</h4>
<p>Cannot fail.</p>
<p></p>
<h4>See Also</h4>
<p>
<code><a href="#mps_class_amc">mps_class_amc</a></code>,
<code><a href="#mps_ap_frame_pop">mps_ap_frame_pop</a></code>,
<code><a href="#mps_ap_frame_push">mps_ap_frame_push</a></code>,
<code><a href="#mps_ap_create">mps_ap_create</a></code></p>
<h3><code><a id="mps_class_mvt" name="mps_class_mvt">mps_class_mvt</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_class_mvt">mps_class_mvt</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_class_mvt">mps_class_mvt</a></code> is a function that returns the MVT pool class object.</p>
<h4>Associated Protocols</h4>
<p>Allocation point.</p>
<h4>Syntax</h4>
<p><code>mps_class_t mps_class_mvt(void);</code></p>
<h4>Type</h4>
<p>C function</p>
<h4>Arguments</h4>
<p>None.</p>
<h4>Returned Values</h4>
<p>The MVT pool class object.</p>
<h4>Resources</h4>
<p>mpscmv2.h</p>
<h4>Description</h4>
<p>The function <code><a
href="#mps_class_mvt">mps_class_mvt</a></code> returns the MVT pool
class object, which can be used to create an MVT pool instance by
passing the class object as the <code><a
href="#mps_class_t">mps_class_t</a></code> (third) argument to
<code><a href="#mps_pool_create">mps_pool_create</a></code>.</p>
<p>The MVT pool class manually manages variable-sized, unformatted objects. The MVT pool usesan allocation policy termed "temporal fit". Temporal fit attempts to place consecutive allocationsnext to each other. It relies on delaying reuse as long as possible to permit freed blocks tocoalesce, thus maximizing the number of consecutive allocations that can be co-located. Temporal fitpermits a very fast allocator and a deallocator competitive in speed with all other known policies.</p>
<p>
Temporal fit is intended to take advantage of knowledge of object lifetimes, either
<cite>
apriori
</cite>
knowledge or knowledge acquired by profiling. The best performance of the MVT poolwill be achieved by allocating objects with similar expected deathtimes together.
</p>
<p>A simple policy can be implemented to take advantage of MVT: Object size is typicallywell-correlated with object life-expectancy, and birthtime plus lifetime gives deathtime, soallocating objects of similar size sequentially from the same pool instance should result in objectsallocated close to each other dying at about the same time.</p>
<p>An application that has several classes of objects of widely differing life expectancy willbest be served by creating a different MVT pool instance for each life-expectancy class. A moresophisticated policy can use either the programmer's knowledge of the expected lifetime of an objector any characteristic of objects that correlates with lifetime to choose an appropriate poolinstance to allocate in.</p>
<p>Allocating objects with unknown or very different deathtimes together will pessimize thespace performance of MVT.</p>
<h4>Example</h4>
<pre>
if(mps_pool_create(&amp;pool, arena, mps_class_mvt(), 8, 32, 256, 70, 20)
!= MPS_RES_OK) {
printf("Error creating pool!");
exit(2);
}
</pre>
<h4>Error Handling</h4>
<p><code><a href="#mps_class_mvt">mps_class_mvt</a></code> cannot result in an error.</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_pool_create">mps_pool_create</a></code></p>
<h4>Notes</h4>
<p>
<strong>
Creation
</strong>
</p>
<p>The MVT pool class has five creation parameters:</p>
<pre>
mps_res_t mps_pool_create(mps_pool_t * pool, mps_arena_t arena,
mps_class_t mvt_class, size_t minimum_size,
size_t mean_size, size_t maximum_size,
mps_count_t reserve_depth mps_count_t fragmentation_limit);
</pre>
<p>Sizes</p>
<p><code>minimum_size</code>, <code>mean_size</code>, and <code>maximum_size</code> are the minimum, mean, and maximum (typical) sizein bytes of objects expected to be allocated in the pool. Objects smaller than minimum size may beallocated, but the pool is not guaranteed to manage them space-efficiently. Objects larger thanmaximum_size may be allocated, but the pool is not guaranteed to manage them space-efficiently.Furthermore, partial freeing is not supported for objects larger than maximum size; doing so willresult in the storage of the object never being reused. Mean_size need not be an accurate mean,although the pool will manage mean_size objects more efficiently.</p>
<p>Reserve Depth</p>
<p>reserve_depth is the expected hysteresis of the object population. When pool objects arefreed, the pool will retain sufficient storage to allocate reserve_depth objects of mean_size fornear term allocations (rather than immediately making that storage available to other pools).</p>
<p>If a pool has a stable object population, one which only grows over the lifetime of thepool, or one which grows steadily and then shrinks steadily, use a reserve_depth of 0.</p>
<p>It is always safe to use a reserve depth of 0, but if the object population typicallyfluctuates in a range (e.g., the client program may repeatedly create and destroy a subset ofobjects in a loop), it is more efficient for the pool to retain enough storage to satisfy thatfluctuation. For example, if a pool has an object population that typically fluctuates between 8,000and 10,000, use a reserve_depth of 2,000.</p>
<p>The reserve will not normally be available to other pools for allocation, even when it isnot used by the pool. If this is undesirable, a reserve depth of 0 may be used for a pool whoseobject population does vary, at a slight cost in efficiency. The reserve does not guarantee anyparticular amount of allocation.</p>
<p>Fragmentation Limit</p>
<p>fragmentation_limit is a percentage in (0, 100] that can be used to set an upper limit onthe space overhead of MVT in case object deathtimes and allocations do not correlate well.</p>
<p>If the free space managed by the pool as a ratio of all the space managed by the poolexceeds the specified percentage, the pool will fall back to a first fit allocation policy,exploiting space more efficiently at a cost in time efficiency.</p>
<p>A fragmentation_limit of 0 would cause the pool to operate as a first-fit pool, at asignificant cost in time-efficiency, therefore is not permitted.</p>
<p>A fragmentation_limit of 100 will cause the pool to use temporal fit (unless resources areexhausted). If the objects allocated in the pool have similar lifetime expectancies, this mode willhave the best time- and space-efficiency. If the objects have widely varying lifetime expectancies,this mode will be time-efficient, but may be space-inefficient. An intermediate setting can be usedto limit the space-inefficiency of temporal fit due to varying object life expectancies.</p>
<p>
<strong>
Allocation
</strong>
</p>
<p>The MVT pool class only supports allocation through allocation points. See <code><a href="#mps_ap_create">mps_ap_create</a></code>.</p>
<p>
<strong>
Deallocation
</strong>
</p>
<p>The MVT pool class supports explicit freeing. See <code><a href="#mps_pool_free">mps_pool_free</a></code>.</p>
<h4>Internal Notes</h4>
<p>Need a life-expectancy parameter! How else will different instances choose their Loci?</p>
<p>Need an alignment parameter. Perhaps this is embedded in a format parameter (when all poolshave at least a null format).</p>
<p>It is conceivable that a client would want to mix manual and automatic pools with the manualpool being able to be a root for the automatic. To do so, MVT would need to support formattedobjects and scanning. This may be added someday.</p>
<p>Eventually the MM product will include profiling tools that will help determine objectcharacteristics that correlate with object lifetime and suggest how to configure the appropriatenumber of MVT pool instances and what characteritics to dispatch on when choosing which instance toallocate from.</p>
<p>[From mail.ptw.1998-08-19.02-33(0) ]</p>
<p>Remember Wilson's statement that the goal of a memory manager is to exploit the regularitiesin allocation patterns? My intent in the interface parameters is to accept measurable regularitiesin object populations, then the implementation can exploit them.</p>
<p>Perhaps the pool should accept some description of the mean and
deviation of the objectsizes, object population, and object
lifetimes. Is that what you are getting at? [Reserve_depth is in some sense a deviation.]</p>
<h3>Type <code><a id="mps_class_t" name="mps_class_t">mps_class_t</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_class_t">mps_class_t</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_class_t">mps_class_t</a></code> is the type of pool classes.</p>
<h4>Associated Protocols</h4>
<p>Pool.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p><code><a href="#mps_class_t">mps_class_t</a></code> is the abstract type of pool classes. It is opaque. A pool class may beobtained by calling the class function for the appropriate class, such as <code><a href="#mps_class_amc">mps_class_amc</a></code> for theAMC class. A pool class is used when creating a pool with <code><a href="#mps_pool_create">mps_pool_create</a></code> or <code><a href="#mps_pool_create_v">mps_pool_create_v</a></code>.</p>
<h4>Example</h4>
<h4>See Also</h4>
<p>
<code><a href="#mps_pool_create">mps_pool_create</a></code>,
<code><a href="#mps_pool_create_v">mps_pool_create_v</a></code></p>
<h4>Notes</h4>
<p><code><a href="#mps_class_s">mps_class_s</a></code> is an incomplete structure type used only to define <code><a href="#mps_class_t">mps_class_t</a></code>.</p>
<h3>function <code><a id="mps_finalize" name="mps_finalize">mps_finalize</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_finalize">mps_finalize</a></code></p>
<h4>Summary</h4>
<p>Registers an object for finalization.</p>
<h4>Associated Protocols</h4>
<p>Finalization, message.</p>
<h4>Syntax</h4>
<p><code>mps_res_t mps_finalize(mps_arena_t arena, mps_addr_t *object_ref)</code></p>
<h4>Arguments</h4>
<p>
<code>arena</code>
-- the arena in which the object lives
</p>
<p>
<code>object_ref</code>
-- a pointer to a pointer to the object to be finalized
</p>
<h4>Returned Values</h4>
<p>A result code.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>This function registers the specified object for finalization. This object must be an objectallocated from a pool in the specified arena.</p>
<p>An object becomes finalizable if it is registered for finalization, and the collectorobserves that it would otherwise be reclaimable. Note that the subsequent creation of strongreferences to the object (from, say, weak references) may cause finalization to occur when an objectis not otherwise reclaimable.</p>
<p>When an object is finalizable, it may be finalized up to N times, where N is the number oftimes it has been registered for finalization. When an object is finalized, it is also deregisteredfor finalization (so that it cannot be finalized again from the same registration).</p>
<p>Finalization is performed by passing a finalization message to the client, containing anexact reference to the object. See the message protocol, <code><a href="#mps_message_type_finalization">mps_message_type_finalization</a></code>, and <code><a href="#mps_message_finalization_ref">mps_message_finalization_ref</a></code> for details.</p>
<p>If an object is registered for finalization multiple times, then there may be multiplefinalization messages on the queue at the same time. It may also be necessary to discard previousfinalization messages for an object before all such messages are posted on the message queue.Clients performing multiple registrations must cope with both behaviors.</p>
<p>Note that there is no guarantee that finalization will be prompt, although the collectordoes attempt to do this.</p>
<p>Note that there will be no attempt to finalize objects in the context of <code><a href="#mps_arena_destroy">mps_arena_destroy</a></code> or <code><a href="#mps_pool_destroy">mps_pool_destroy</a></code>. <code><a href="#mps_pool_destroy">mps_pool_destroy</a></code>should therefore not be invoked on pools containing objects registered for finalization.</p>
<p>Not all pools support finalization of objects in those pools. For more information, see thePool Class Catalog.</p>
<h4>Example</h4>
<p>[missing]</p>
<h4>Error Handling</h4>
<p>[missing]</p>
<h4>See Also</h4>
<p>
<code>mps_message_*</code>,
<code><a href="#mps_arena_destroy">mps_arena_destroy</a></code>,
<code><a href="#mps_pool_destroy">mps_pool_destroy</a></code></p>
<h4>Notes</h4>
<p>This function receives a pointer to a reference. This is to avoid placing the restriction onthe client that the C call stack be a root.</p>
<h3>type <code><a id="mps_fmt_A_s" name="mps_fmt_A_s">mps_fmt_A_s</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_fmt_A_s">mps_fmt_A_s</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_fmt_A_s">mps_fmt_A_s</a></code> is a structure used to create object formats of variant A.</p>
<h4>Associated Protocols</h4>
<p>Format.</p>
<h4>Type</h4>
<pre>
typedef struct mps_fmt_A_s {
mps_align_t align;
mps_fmt_scan_t scan;
mps_fmt_skip_t skip;
mps_fmt_copy_t copy;
mps_fmt_fwd_t fwd;
mps_fmt_isfwd_t isfwd;
mps_fmt_pad_t pad;
} mps_fmt_A_s;
</pre>
<h4>Resources</h4>
<p>
<code class="filename">
mps.h
</code>
</p>
<h4>Description</h4>
<p>Objects of this type are intended to be used in the creation of object formats. Objectformats describe the layout of client objects.</p>
<p><code><a href="#mps_fmt_A_s">mps_fmt_A_s</a></code> is a structure that represents the particular collection of methodsand values that describes an object format of variant A.</p>
<p>Broadly speaking, the object formats of this variant are suitable for use in copying ormoving memory managers.</p>
<p><code><a href="#mps_fmt_A_s">mps_fmt_A_s</a></code> has the
following methods: <code> scan</code>, <code> skip</code>, <code>copy</code>, <code> fwd</code>, <code> isfwd</code>, <code> pad</code>, and the following value:<code>align</code>.</p>
<p><code>align</code> is an integer value defines the alignment of objects allocated with thisformat. It should be large enough to satisfy the alignment requirements of any field in the objects,and it cannot be larger than the arena alignment. For details of the methods, consult the reference pages for the type of each method.</p>
<h4>Example</h4>
<pre>
mps_fmt_t create_format(mps_arena_t arena)
{
mps_fmt my_format;
mps_res_t res;
mps_fmt_A_s my_format_A = { my_alignment, &amp;my_scan, &amp;my_skip, &amp;my_copy, &amp;my_fwd,
&amp;my_isfwd, &amp;my_pad };
res = mps_fmt_create_A(&amp;my_format, arena, &amp;my_format_A);
assert(res != MPS_RES_OK);
return my_format;
}
</pre>
<h4>See Also</h4>
<p>
<code><a href="#mps_fmt_create_A">mps_fmt_create_A</a></code>,
<code><a href="#mps_fmt_scan_t">mps_fmt_scan_t</a></code>,
<code><a href="#mps_fmt_skip_t">mps_fmt_skip_t</a></code>
<code><a href="#mps_fmt_copy_t">mps_fmt_copy_t</a></code>,
<code><a href="#mps_fmt_fwd_t">mps_fmt_fwd_t</a></code>,
<code><a href="#mps_isfwd_t">mps_isfwd_t</a></code>,
<code><a href="#mps_pad_t">mps_pad_t</a></code>,
<code><a href="#mps_align_t">mps_align_t</a></code>,
<code><a href="#mps_fmt_B_s">mps_fmt_B_s</a></code></p>
<h3>type <code><a id="mps_fmt_A_t" name="mps_fmt_A_t">mps_fmt_A_t</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_fmt_A_t">mps_fmt_A_t</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_fmt_A_t">mps_fmt_A_t</a></code> is the type pointer to <code><a href="#mps_fmt_A_s">mps_fmt_A_s</a></code>.</p>
<h4>Associated Protocols</h4>
<p>Format.</p>
<h4>Type</h4>
<pre>
typedef struct mps_fmt_A_s {
mps_align_t align;
mps_fmt_scan_t scan;
mps_fmt_skip_t skip;
mps_fmt_copy_t copy;
mps_fmt_fwd_t fwd;
mps_fmt_isfwd_t isfwd;
mps_fmt_pad_t pad;
} mps_fmt_A_s;
typedef struct mps_fmt_A_s *mps_fmt_A_t;
</pre>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p><code><a href="#mps_fmt_A_t">mps_fmt_A_t</a></code> is the type pointer to <code><a href="#mps_fmt_A_s">mps_fmt_A_s</a></code>. A value of this type represents a collection of methods and values that can be used to create a format object of type <code><a href="#mps_fmt_t">mps_fmt_t</a></code>.This type represents a particular collection of methods and values; other collections arerepresented by other types.</p>
<p>Objects of type <code><a href="#mps_fmt_A_t">mps_fmt_A_t</a></code> are intended to be used in the creation of object formats.Object formats describe the layout of client objects. The function <code><a href="#mps_fmt_create_A">mps_fmt_create_A</a></code> takes an <code><a href="#mps_fmt_A_t">mps_fmt_A_t</a></code> as one of its arguments and creates an object of type <code><a href="#mps_fmt_t">mps_fmt_t</a></code> (an object format).</p>
<p>See the documentation of <code><a href="#mps_fmt_A_s">mps_fmt_A_s</a></code> for further details.</p>
<h4>Example</h4>
<h4>See Also</h4>
<p>
<code><a href="#mps_fmt_A_s">mps_fmt_A_s</a></code>,
<code><a href="#mps_fmt_t">mps_fmt_t</a></code>,
<code><a href="#mps_fmt_create_A">mps_fmt_create_A</a></code></p>
<h3>type <code><a id="mps_fmt_B_s" name="mps_fmt_B_s">mps_fmt_B_s</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_fmt_B_s">mps_fmt_B_s</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_fmt_B_s">mps_fmt_B_s</a></code> is a transparent structure used to create object formats of variantB.</p>
<h4>Associated Protocols</h4>
<p>Format.</p>
<h4>Type</h4>
<pre>
typedef struct mps_fmt_B_s {
mps_align_t align;
mps_fmt_scan_t scan;
mps_fmt_skip_t skip;
mps_fmt_copy_t copy;
mps_fmt_fwd_t fwd;
mps_fmt_isfwd_t isfwd;
mps_fmt_pad_t pad;
mps_fmt_class_t mps_class;
} mps_fmt_B_s;
</pre>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>Objects of this type are intended to be used in the creation of object formats. Objectformats describe the layout of client objects. <code><a href="#mps_fmt_B_s">mps_fmt_B_s</a></code> is a structure thatrepresents the particular collection of methods and values that describes an object format ofvariant B.</p>
<p><code><a href="#mps_fmt_B_s">mps_fmt_B_s</a></code> is the same as <code><a href="#mps_fmt_A_s">mps_fmt_A_s</a></code> except for the addition ofthe <code><a href="#mps_class">mps_class</a></code> method. Broadly speaking, the object formats of variety B are suitable for use incopying or moving memory managers (just like variety A); the addition of the class method allowsmore information to be passed to various support tools (such as graphical browsers).</p>
<p><code><a href="#mps_fmt_B_s">mps_fmt_B_s</a></code> has the following methods: scan, skip, copy, fwd, isfwd, pad, <code><a href="#mps_class">mps_class</a></code>, and the following value: align.</p>
<p>align is an integer value defines the alignment of objects allocated with this format. Itshould be large enough to satisfy the alignment requirements of any field in the objects, and itcannot be larger than the arena alignment. For details of the methods, consult the reference pagesfor the type of each method.</p>
<h4>Example</h4>
<pre>
mps_fmt_t create_format(mps_arena_t arena)
{
mps_fmt_B_s my_format_B = { my_alignment, &amp;my_scan, &amp;my_skip, &amp;my_copy,
&amp;my_fwd, &amp;my_isfwd, &amp;my_pad, &amp;my_class };
mps_fmt my_format;
mps_res_t res;
res = mps_fmt_create_B(&amp;my_format, arena, &amp;my_format_B);
assert(res != MPS_RES_OK);
return my_format;
}
</pre>
<h4>See Also</h4>
<p>
<code><a href="#mps_fmt_create_B">mps_fmt_create_B</a></code>,
<code><a href="#mps_fmt_scan_t">mps_fmt_scan_t</a></code>,
<code><a href="#mps_fmt_skip_t">mps_fmt_skip_t</a></code>,
<code><a href="#mps_fmt_copy_t">mps_fmt_copy_t</a></code>,
<code><a href="#mps_fmt_fwd_t">mps_fmt_fwd_t</a></code>,
<code><a href="#mps_isfwd_t">mps_isfwd_t</a></code>,
<code><a href="#mps_pad_t">mps_pad_t</a></code>,
<code><a href="#mps_align_t">mps_align_t</a></code>,
<code><a href="#mps_class_t">mps_class_t</a></code>,
<code><a href="#mps_fmt_A_s">mps_fmt_A_s</a></code></p>
<h4>Notes</h4>
<p>The <code><a href="#mps_class">mps_class</a></code> field used to be called "class", but that was problematic forC++, so we changed it.</p>
<h3>Type <code><a id="mps_fmt_B_t" name="mps_fmt_B_t">mps_fmt_B_t</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_fmt_B_t">mps_fmt_B_t</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_fmt_B_t">mps_fmt_B_t</a></code> is a type passed to <code><a href="#mps_fmt_create_B">mps_fmt_create_B</a></code>. It represents the collection of methodsand values used to create a <code><a href="#mps_fmt_t">mps_fmt_t</a></code>. You are expected to declare and create structures of thistype if you require an object of type <code><a href="#mps_fmt_B_t">mps_fmt_B_t</a></code>.</p>
<h4>Associated Protocols</h4>
<p>Format</p>
<h4>Structure</h4>
<pre>
typedef struct mps_fmt_B_s {
mps_align_t align;
mps_fmt_scan_t scan;
mps_fmt_skip_t skip;
mps_fmt_copy_t copy;
mps_fmt_fwd_t fwd;
mps_fmt_isfwd_t isfwd;
mps_fmt_pad_t pad;
mps_fmt_class_t class;
} mps_fmt_B_s;
</pre>
<h4>Type</h4>
<p><code>typedef struct mps_fmt_B_s *mps_fmt_B_t;</code></p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p><code><a href="#mps_fmt_B_t">mps_fmt_B_t</a></code> is the equivalent to <code><a href="#mps_fmt_A_t">mps_fmt_A_t</a></code> that should be passed to<code><a href="#mps_fmt_create_B">mps_fmt_create_B</a></code>. It is suitable for format variety A collectors that need to use tools that useclass information.</p>
<p>See the documentation for the symbol <code><a href="#mps_fmt_B_s">mps_fmt_B_s</a></code> for further details.</p>
<h4>Example</h4>
<h4>See Also</h4>
<p>
<code><a href="#mps_fmt_B_s">mps_fmt_B_s</a></code>,
<code><a href="#mps_fmt_t">mps_fmt_t</a></code>,
<code><a href="#mps_fmt_create_B">mps_fmt_create_B</a></code>,
<code><a href="#mps_fmt_A_t">mps_fmt_A_t</a></code></p>
<h4>Notes</h4>
<p>None.</p>
<h3>type <code><a id="mps_fmt_auto_header_s" name="mps_fmt_auto_header_s">mps_fmt_auto_header_s</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_fmt_auto_header_s">mps_fmt_auto_header_s</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_fmt_auto_header_s">mps_fmt_auto_header_s</a></code> is a structure used to create objectformats of variant auto_header.</p>
<h4>Associated Protocols</h4>
<p>Format.</p>
<h4>Type</h4>
<blockquote>
<pre>
typedef struct mps_fmt_auto_header_s {
mps_align_t align;
mps_fmt_scan_t scan;
mps_fmt_skip_t skip;
mps_fmt_fwd_t fwd;
mps_fmt_isfwd_t isfwd;
mps_fmt_pad_t pad;
size_t mps_headerSize;
} mps_fmt_auto_header_s;
</pre>
</blockquote>
<h4>Resources</h4>
<p>
<code class="filename">
mps.h
</code>
</p>
<h4>Description</h4>
<p>Objects of this type are intended to be used in the creation of object formats. Objectformats describe the layout of client objects. <code><a href="#mps_fmt_auto_header_s">mps_fmt_auto_header_s</a></code> isa structure that represents the particular collection of methods and values that describes an objectformat of variant auto_header.</p>
<p>Broadly speaking, the object formats of this variant are suitable
for use in automaticmemory management for objects with headers (hence
the name). More precisely, this variant is intended for formats where the client's pointers point some distance into the memory blockcontaining the object. This typically happens when the objects have a common header used for memorymanagement or class system purposes, but this situation also arises when the low bits of a pointerare used for a tag. The MPS does not care what the reason is, only about the offset of the pointerin relation to the memory block.</p>
<p><code><a href="#mps_fmt_auto_header_s">mps_fmt_auto_header_s</a></code>has the following methods: <code class="source"> scan</code>, <code class="source"> skip</code>, <code class="source"> fwd</code>, <code class="source"> isfwd</code>, <code class="source"> pad</code>, and the following values: <code class="source"> align </code> and <code><a href="#mps_headerSize">mps_headerSize</a></code>.</p>
<p>
<code class="source">
align
</code>
is an integer value defines the alignment of objectsallocated with this format. It should be large enough to satisfy the alignment requirements of anyfield in the objects, and it cannot be larger than the arena alignment.
</p>
<p><code><a href="#mps_headerSize">mps_headerSize</a></code> is the size of the header, i.e., the offset of aclient pointer from the base the memory block. For details of the methods, consult the referencepages for the type of each method.</p>
<h4>Example</h4>
<pre>
mps_fmt_t create_format(mps_arena_t arena)
{
mps_fmt format;
mps_res_t res;
mps_fmt_auto_header_s format_desc = { my_alignment, &amp;my_scan, &amp;my_skip, &amp;my_fwd,
&amp;my_isfwd, &amp;my_pad, HEADER_SIZE };
res = mps_fmt_create_auto_header(&amp;format, arena, &amp;format_desc);
assert(res != MPS_RES_OK);
return format;
}
</pre>
<h4>See Also</h4>
<p>
<code><a
href="#mps_fmt_create_auto_header">mps_fmt_create_auto_header</a></code>,
<code><a href="#mps_fmt_scan_t">mps_fmt_scan_t</a></code>,
<code><a href="#mps_fmt_skip_t">mps_fmt_skip_t</a></code>,
<code><a href="#mps_fmt_fwd_t">mps_fmt_fwd_t</a></code>,
<code><a href="#mps_isfwd_t">mps_isfwd_t</a></code>,
<code><a href="#mps_pad_t">mps_pad_t</a></code>,
<code><a href="#mps_align_t">mps_align_t</a></code>,
<code><a href="#mps_fmt_A_s">mps_fmt_A_s</a></code></p>
<h4>Notes</h4>
<p>For technical reasons, client objects must be longer than the header, i.e., objectsconsisting of only a header are not supported. However, if the header size is larger than or equalto alignment, the pad method must still be able to create padding objects down to alignment size.</p>
<p>At the moment, this format only works with pool classes AMC and AMCZ.</p>
<h3>type <code><a id="mps_fmt_class_t" name="mps_fmt_class_t">mps_fmt_class_t</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_fmt_class_t">mps_fmt_class_t</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_fmt_class_t">mps_fmt_class_t</a></code> is a function pointer type for the class method of a format.</p>
<h4>Associated Protocols</h4>
<p>Format. Telemetry.</p>
<h4>Type</h4>
<p><code>typedef mps_addr_t (*mps_fmt_class_t)(mps_addr_t addr);</code></p>
<h4>Arguments</h4>
<p>addr the address of the object whose class is of interest</p>
<h4>Returned Values</h4>
<p>Returns an address that the client associates with the class or type of the object.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p><code><a href="#mps_fmt_class_t">mps_fmt_class_t</a></code> is t he type of a format's class method. A class methodreturns an address that is related to the class of the object, for passing on to various supporttools (such as graphical browsers).</p>
<p>A class method is provided by the client as part of a format (see Format Protocol).</p>
<p>The exact meaning of the return value is up to the client, but it would typically bear somerelation to class or type in the client program. The client may have objects that represent classesor types. These may be associated with strings via <code><a href="#mps_telemetry_intern">mps_telemetry_intern</a></code> and <code><a href="#mps_telemetry_label">mps_telemetry_label</a></code>.</p>
<h4>Example</h4>
<pre>
mps_addr_t my_class_method(mps_addr_t object) {
my_object_generic_t generic_object = object;
return (mps_addr_t)(generic_object.class);
}
</pre>
<h4>Error Handling</h4>
<p>A class method is not allowed to fail, but may return NULL.</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_fmt_t">mps_fmt_t</a></code>,
<code><a href="#mps_fmt_create_B">mps_fmt_create_B</a></code></p>
<h4>Notes</h4>
<p>It is recommended that NULL be returned for padding objects and forwarded objects.</p>
<h3>type <code><a id="mps_fmt_copy_t" name="mps_fmt_copy_t">mps_fmt_copy_t</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_fmt_copy_t">mps_fmt_copy_t</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_fmt_copy_t">mps_fmt_copy_t</a></code> is a function pointer type for the copy method of a format.</p>
<h4>Associated Protocols</h4>
<p>Format.</p>
<h4>Type</h4>
<p><code>typedef void (*mps_fmt_copy_t)(mps_addr_t old, mps_addr_t new);</code></p>
<h4>Arguments</h4>
<p>old -- the address of the object</p>
<p>new -- the address to which the object should be copied</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p><code><a href="#mps_fmt_copy_t">mps_fmt_copy_t</a></code> is a function pointer type for the copy method of a format. A copy methodcopies an object to a new location. It may be called by the MPS as part of copying garbagecollection, for example.</p>
<p>A copy method is required in some formats (in particular formats A and B (see <code><a href="#mps_fmt_A_t">mps_fmt_A_t</a></code> and <code><a href="#mps_fmt_B_t">mps_fmt_B_t</a></code>)). A copy method takes the address of an object and another address, and copiesthe object to the new address. The new and the old locations are guaranteed not to overlap.</p>
<h4>Example</h4>
<pre>
void my_copy_method(mps_addr_t old, mps_addr_t new)
{
size_t length = (char*)my_skip_method(old) - (char *)old;
memcpy(new, old, length);
}
</pre>
<h4>Error Handling</h4>
<p>A copy method is not allowed to fail.</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_fmt_t">mps_fmt_t</a></code>,
<code><a href="#mps_fmt_create_A">mps_fmt_create_A</a></code>,
<code><a href="#mps_fmt_A_t">mps_fmt_A_t</a></code>,
<code><a href="#mps_fmt_B_t">mps_fmt_B_t</a></code>,
<code><a href="#mps_fmt_create_B">mps_fmt_create_B</a></code></p>
<h4>Notes</h4>
<p>Most pools will just ignore Copy methods, and do the copy themselves.</p>
<h3>function <code><a id="mps_fmt_create_A" name="mps_fmt_create_A">mps_fmt_create_A</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_fmt_create_A">mps_fmt_create_A</a></code></p>
<h4>Summary</h4>
<p>Function for create a format of variety A.</p>
<h4>Associated Protocols</h4>
<p>Format.</p>
<p></p>
<h4>Syntax</h4>
<p><code>mps_res_t mps_fmt_create_A(mps_fmt_t *fmt_o, mps_arena_t arena, mps_fmt_A_s *fmt_A);</code></p>
<h4>Arguments</h4>
<p>
<code>fmt_o</code>
- the address of a variable to hold the new format
</p>
<p>
<code>arena</code>
- the arena in which to create the format
</p>
<p>
<code>fmt_A</code>
- format description of variety A
</p>
<h4>Returned Values</h4>
<p>Result status. If the return value is <code><a href="#MPS_RES_OK">MPS_RES_OK</a></code>, the new format is in <code>*fmt_o </code>.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>This function creates a format from a user format specification of variety A.</p>
<h4>Example</h4>
<pre>
mps_fmt_t create_format(mps_arena_t arena)
{
mps_fmt_A_s my_format_A = { my_alignment, &amp;my_scan, &amp;my_skip, &amp;my_copy,&amp;my_fwd,
&amp;my_isfwd, &amp;my_pad };
mps_fmt my_format;
mps_res_t res;
res = mps_fmt_create_A(&amp;my_format, arena, &amp;my_format_A);
if(res != MPS_RES_OK) {
fprintf(stderr, "Couldn't create format.\n");
exit(1);
}
return my_format;
}
</pre>
<h4>Error Handling</h4>
<p>The MPS may exhaust some resource in the course of <code><a href="#mps_fmt_create_A">mps_fmt_create_A</a></code> and willreturn an appropriate error code in such circumstances.</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_fmt_A_s">mps_fmt_A_s</a></code>,
<code><a href="#mps_fmt_t">mps_fmt_t</a></code>,
<code><a href="#mps_fmt_create_B">mps_fmt_create_B</a></code></p>
<h3>function <code><a id="mps_fmt_create_B" name="mps_fmt_create_B">mps_fmt_create_B</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_fmt_create_B">mps_fmt_create_B</a></code></p>
<h4>Summary</h4>
<p>Function for create a format of variety B.</p>
<h4>Associated Protocols</h4>
<p>Format.</p>
<p></p>
<h4>Syntax</h4>
<p><code>mps_res_t mps_fmt_create_B(mps_fmt_t *fmt_o, mps_arena_t arena, mps_fmt_B_s *fmt_B);</code></p>
<h4>Arguments</h4>
<p><code>arena</code> - the arena in which to create the format</p>
<p><code>fmt_B</code> - format description of variety B</p>
<h4>Returned Values</h4>
<p>Result status. If the return value is <code><a href="#MPS_RES_OK">MPS_RES_OK</a></code>, the new format is in<code>*fmt_o </code>.</p>
<p></p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>This function creates a format from a user format specification of variety B. It is verysimilar to <code><a href="#mps_fmt_create_A">mps_fmt_create_A</a></code>.</p>
<h4>Example</h4>
<pre>
mps_fmt_t create_format(mps_arena_t arena)
{
mps_fmt_B_s my_format_B = { my_alignment, &amp;my_scan, &amp;my_skip, &amp;my_copy,
&amp;my_fwd, &amp;my_isfwd, &amp;my_pad, &amp;my_class };
mps_fmt my_format;
mps_res_t res;
res = mps_fmt_create_B(&amp;my_format, arena, &amp;my_format_B);
assert(res != MPS_RES_OK);
return my_format;
}
</pre>
<h4>Error Handling</h4>
<p>The MPS may exhaust some resource in the course of <code><a href="#mps_fmt_create_B">mps_fmt_create_B</a></code> and willreturn an appropriate error code in such circumstances.</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_fmt_B_s">mps_fmt_B_s</a></code>,
<code><a href="#mps_fmt_t">mps_fmt_t</a></code>,
<code><a href="#mps_fmt_create_A">mps_fmt_create_A</a></code></p>
<h3>function <code><a id="mps_fmt_create_auto_header" name="mps_fmt_create_auto_header">mps_fmt_create_auto_header</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_fmt_create_auto_header">mps_fmt_create_auto_header</a></code></p>
<h4>Summary</h4>
<p>Function for create a format of variety auto_header.</p>
<h4>Associated Protocols</h4>
<p>Format.</p>
<h4>Syntax</h4>
<p><code>mps_res_t mps_fmt_create_auto_header(mps_fmt_t *fmt_o, mps_arena_t arena, mps_fmt_auto_header_s *fmt_st);</code></p>
<h4>Arguments</h4>
<p>
<code>fmt_o</code>
- the address of a variable to hold the new format
</p>
<p>
<code>arena</code>
- the arena in which to create the format
</p>
<p>
<code>fmt_st</code>
- format description of variety auto_header
</p>
<h4>Returned Values</h4>
<p>Result status. If the return value is <code><a href="#MPS_RES_OK">MPS_RES_OK</a></code>, the new format is in <code>*fmt_o </code>.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>This function creates a format from a user format specification of variety auto_header.</p>
<h4>Example</h4>
<pre>
mps_fmt_t create_format(mps_arena_t arena)
{
mps_fmt_auto_header_s format_desc = { my_alignment, &amp;my_scan, &amp;my_skip, &amp;my_fwd,
&amp;my_isfwd, &amp;my_pad, HEADER_SIZE };
mps_fmt format;
mps_res_t res;
res = mps_fmt_create_auto_header(&amp;format, arena, &amp;format_desc);
assert(res != MPS_RES_OK);
return format;
}
</pre>
<h4>Error Handling</h4>
<p>The MPS may exhaust some resource in the course of <code><a href="#mps_fmt_create_auto_header">mps_fmt_create_auto_header</a></code>and will return an appropriate error code in such circumstances.</p>
<h4>See Also</h4>
<p>
<code><a
href="#mps_fmt_auto_header_s">mps_fmt_auto_header_s</a></code>,
<code><a href="#mps_fmt_t">mps_fmt_t</a></code>,
<code><a href="#mps_fmt_create_A">mps_fmt_create_A</a></code></p>
<h3>type <code><a id="mps_fmt_fwd_t" name="mps_fmt_fwd_t">mps_fmt_fwd_t</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_fmt_fwd_t">mps_fmt_fwd_t</a></code></p>
<h4>Summary</h4>
<p>The type of a format's forward method.</p>
<h4>Associated Protocols</h4>
<p>Format.</p>
<h4>Type</h4>
<p><code>typedef void (*mps_fmt_fwd_t)(mps_addr_t old, mps_addr_t new);</code></p>
<h4>Arguments</h4>
<p>old</p>
<p>the address of an object</p>
<p>new</p>
<p>the address where the object has been moved</p>
<h4>Returned Values</h4>
<p>None.</p>
<h4>Description</h4>
<p><code><a href="#mps_fmt_fwd_t">mps_fmt_fwd_t</a></code> is the type of a format's forward method. A forward method isused to store relocation information in a heap. It may be called by the MPS as part of copyinggarbage collection.</p>
<p>A forward method is provided by the client as part of a format (see Format Protocol ). TheMPS calls a forward method when it has relocated an object. The forward method when called mustreplace the object at 'old' with a forwarding marker that points to the address 'new'. Theforwarding marker must meet the following requirements:</p>
<ul>
<li><p>it must be possible for the MPS to call other format methods with the address of aforwarding marker as the argument.</p></li>
<li><p>he forwarding marker must not be bigger than the original object.</p></li>
<li><p>t must be possible to distinguish the forwarding marker from ordinary objects using theisfwd method (see <code><a href="#mps_fmt_isfwd_t">mps_fmt_isfwd_t</a></code> ), and the isfwd method must return the address'new'.</p></li>
</ul>
<h4>Example</h4>
<pre>
/* define the function */
void example_fwd(mps_addr_t old, mps_addr_t new)
{
/* ... */
}
/* also define example_scan, example_skip, etc */
/* store pointer to function in the format variant struct */
struct mps_fmt_B_s example_fmt_B = {
4, /* align */
example_scan,
example_skip,
example_copy,
example_fwd,
example_isfwd,
example_pad,
example_class
};
/* The (address of the) example_fmt_B object can now be passed to */
/* mps_fmt_create_B to create a format. */
</pre>
<h4>See Also</h4>
<p>
<code><a href="#mps_fmt_A_s">mps_fmt_A_s</a></code>,
<code><a href="#mps_fmt_B_s">mps_fmt_B_s</a></code>,
<code><a
href="#mps_fmt_auto_header_s">mps_fmt_auto_header_s</a></code>,
<code><a href="#mps_fmt_isfwd_t">mps_fmt_isfwd_t</a></code></p>
<h4>Notes</h4>
<p>This method is never invoked by the GC on an object in a non-moving pool.</p>
<h3>type <code><a id="mps_fmt_isfwd_t" name="mps_fmt_isfwd_t">mps_fmt_isfwd_t</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_fmt_isfwd_t">mps_fmt_isfwd_t</a></code></p>
<h4>Summary</h4>
<p>The type of a format's isfwd ("is forwarded") method.</p>
<h4>Associated Protocols</h4>
<p>Format.</p>
<h4>Type</h4>
<p><code>typedef mps_addr_t (*mps_fmt_isfwd_t)(mps_addr_t addr);</code></p>
<h4>Arguments</h4>
<p>addr</p>
<p>the address of a candidate object</p>
<h4>Returned Values</h4>
<p>
Either a null pointer to indicate the object at
<code>addr</code>
has not been relocated, orthe new location of the object if there is a forwarding marker at
<code>addr</code>
indicating thatthe object has been relocated.
</p>
<h4>Description</h4>
<p>The type of a format's isfwd ("is forwarded") method. An isfwd method is used to testwhether an object has been relocated using the format's forward method.</p>
<p>An isfwd method is provided by the client as part of a format (see protocol.mps.format(0) ).The MPS calls the isfwd method to determine whether an object in the heap has been relocated or not.Objects in the heap are relocated using the format's forward method (see <code><a href="#mps_fmt_fwd_t">mps_fmt_fwd_t</a></code>). When the isfwd method is called the parameter addr will be the address of either an object or aforwarding marker created with the forward method. If it is an object (so it has not been relocated)the method should return a null pointer; otherwise it is a forward marker indicating the address ofthe relocated object, the address of the relocated object should be returned (this should be thesame as the 'new' parameter that was passed to the forward method that created the forwardingmarker).</p>
<h4>Example</h4>
<p>&lt;example of how to use the symbol&gt;</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_fmt_A_s">mps_fmt_A_s</a></code>,
<code><a href="#mps_fmt_B_s">mps_fmt_B_s</a></code>,
<code><a
href="#mps_fmt_auto_header_s">mps_fmt_auto_header_s</a></code>,
<code><a href="#mps_fmt_fwd_t">mps_fmt_fwd_t</a></code></p>
<h4>Notes</h4>
<p>This method is never invoked by the GC on an object in a non-moving pool.</p>
<h3>type <code><a id="mps_fmt_pad_t" name="mps_fmt_pad_t">mps_fmt_pad_t</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_fmt_pad_t">mps_fmt_pad_t</a></code></p>
<h4>Summary</h4>
<p>The type of a format's pad method.</p>
<h4>Associated Protocols</h4>
<p>Format.</p>
<h4>Type</h4>
<p><code>typedef void (*mps_fmt_pad_t)(mps_addr_t addr, size_t size);</code></p>
<h4>Arguments</h4>
<p>addr</p>
<p>The address at which to create a padding object.</p>
<p>size</p>
<p>The size (in bytes) of the padding object to be created.</p>
<h4>Returned Values</h4>
<p>None.</p>
<h4>Description</h4>
<p>The type of a format's pad method. A pad method is used to create padding objects.</p>
<p>A pad method is provided by the client as part of a format (see Format Protocol ). The MPScalls a pad method when it wants to create a padding object. Typically the MPS creates paddingobjects to fill in otherwise unused gaps in memory; they allow the MPS to pack objects in fixed-sizeunits (such as OS pages). The pad method should create a padding object of the specified size at thespecified address. The size can be any aligned (to the format alignment) size. A padding objectshould be acceptable to other methods in the format (scan, skip, isfwd, etc.).</p>
<h4>Example</h4>
<p>&lt;example of how to use the symbol&gt;</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_fmt_A_s">mps_fmt_A_s</a></code>,
<code><a href="#mps_fmt_B_s">mps_fmt_B_s</a></code></p>
<h3>type <code><a id="mps_fmt_scan_t" name="mps_fmt_scan_t">mps_fmt_scan_t</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_fmt_scan_t">mps_fmt_scan_t</a></code></p>
<h4>Summary</h4>
<p>Type of the scan method of a format.</p>
<h4>Associated Protocols</h4>
<p>Format, Scanning.</p>
<h4>Syntax</h4>
<p><code>typedef mps_res_t (*mps_fmt_scan_t)(mps_ss_t scan_state, mps_addr_t base, mps_addr_t limit)</code></p>
<h4>Arguments</h4>
<p>
<code>scan_state</code>
a scan state
</p>
<p>
<code>base</code>
a client pointer to the first object in the block to be scanned
</p>
<p>
<code>limit</code>
a client pointer to the object just beyond the end of the block
</p>
<h4>Returned Values</h4>
<p>A result code.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>This is the type of scanning functions provided by the client in some format variants and <code><a href="#mps_root_create_fmt">mps_root_create_fmt</a></code>. When the MPS needs to scan objects in an area of memory that thisscanning function has been registered for, it will be called with a scan state and the limits of theblock of objects to scan. It must then indicate references within the objects by using<code><a href="#mps_fix">mps_fix</a></code> or one of the alternatives.</p>
<p>The <code>base</code> and <code>limit</code> arguments are client pointers, as usual. Notethat there might not be any object at the location indicated by <code>limit</code>.</p>
<h4>Example</h4>
<pre>
/* Scanner for a simple Scheme-like language with just two interesting types */
mps_res_t scan_objs(mps_ss_t ss, mps_addr_t base, mps_addr_t limit)
{
mps_res_t res;
mps_addr_t obj;
MPS_SCAN_BEGIN(ss)
for(obj = base; obj &lt; limit;) { /* obj maps over the objects to scan */
switch(((Object*)obj)-&gt;type) {
case ArrayType:
{
size_t i;
Array *array = (Array *)obj;
for(i = 0; i &lt; array-&gt;length; ++i) { /* fix each element */
res = MPS_FIX12(ss, &amp;array-&gt;contents[i]);
if(res != MPS_RES_OK) return res;
}
obj = AddrAdd(obj, ArraySize(array)); /* move to next object */
break;
}
case StackFrameType:
{
StackFrame *frame = (StackFrame *)obj;
for(i = frame-&gt;size; i &gt; 0; --i) { /* fix each local var */
res = MPS_FIX12(ss, &amp;frame-&gt;locals[i]);
if(res != MPS_RES_OK) return res;
}
res = MPS_FIX12(ss, &amp;frame-&gt;next);
if(res != MPS_RES_OK) return res;
obj = AddrAdd(obj, StackFrameSize(frame));
break;
}
default: /* other types don't contain references */
obj = AddrAdd(obj, DefaultSize(obj));
break;
}
}
MPS_SCAN_END(ss);
return res;
}
</pre>
<h4>Error Handling</h4>
<p>If a fixing operation 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, itis better if it returns as soon as
possible. If the scanning is completed successfully, the
function should return <code><a
href="#MPS_RES_OK">MPS_RES_OK</a></code>.</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_fmt_A_s">mps_fmt_A_s</a></code>,
<code><a href="#mps_fmt_B_s">mps_fmt_B_s</a></code>,
<code><a
href="#mps_fmt_auto_header_s">mps_fmt_auto_header_s</a></code>,
<code><a href="#mps_root_create_fmt">mps_root_create_fmt</a></code>,
<code><a href="#mps_fix">mps_fix</a></code>,
<code><a href="#MPS_FIX12">MPS_FIX12</a></code>,
<code><a href="#MPS_FIX1">MPS_FIX1</a></code>,
<code><a href="#MPS_FIX2">MPS_FIX2</a></code>,
<code><a href="#MPS_FIX_CALL">MPS_FIX_CALL</a></code>,
<code><a href="#MPS_SCAN_BEGIN">MPS_SCAN_BEGIN</a></code>,
<code><a href="#MPS_SCAN_END">MPS_SCAN_END</a></code></p>
<h3>type <code><a id="mps_fmt_skip_t" name="mps_fmt_skip_t">mps_fmt_skip_t</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_fmt_skip_t">mps_fmt_skip_t</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_fmt_skip_t">mps_fmt_skip_t</a></code> is a function pointer type for the skip method of a format.</p>
<h4>Associated Protocols</h4>
<p>Format.</p>
<h4>Type</h4>
<p><code>typedef mps_addr_t (*mps_fmt_skip_t)(mps_addr_t obj);</code></p>
<h4>Arguments</h4>
<p>
<code>obj</code>
the client pointer to the object to be skipped
</p>
<h4>Returned Values</h4>
<p>The skip method should return the address of the next object.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p><code><a href="#mps_fmt_skip_t">mps_fmt_skip_t</a></code> is a function pointer type for the skip method of a format.</p>
<p>These methods are provided by the client as part of a format and invoked by the MPS (seeFormat Protocol). The skip method takes the client pointer to the object. The method should returnthe client pointer to the next object, whether there is one or not. With no headers, this is theaddress just past the end of this object; with headers, it's the address just past where the headerof next object would be. It is always the case that the difference between the argument and thereturn value is the size of the block containing the object.</p>
<h4>Example</h4>
<pre>
mps_addr_t my_skip_method(mps_addr_t object)
{
char *p = (char *)object;
my_object_t my_object = (my_object_t)object;
return((mps_addr_t)(p + my_object-&gt;length));
}
</pre>
<h4>Error Handling</h4>
<p>A skip method is not allowed to fail.</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_fmt_A_s">mps_fmt_A_s</a></code>,
<code><a href="#mps_fmt_B_s">mps_fmt_B_s</a></code>,
<code><a
href="#mps_fmt_auto_header_s">mps_fmt_auto_header_s</a></code></p>
<h3>type <code><a id="mps_fmt_t" name="mps_fmt_t">mps_fmt_t</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_fmt_t">mps_fmt_t</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_fmt_t">mps_fmt_t</a></code> is the type of object formats.</p>
<h4>Associated Protocols</h4>
<p>Format.</p>
<h4>Type</h4>
<p><code>typedef struct mps_fmt_s *mps_fmt_t;</code></p>
<p><code><a href="#mps_fmt_s">mps_fmt_s</a></code> is an incomplete structure type used only to declare the opaque type <code><a href="#mps_fmt_t">mps_fmt_t</a></code>.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p><code><a href="#mps_fmt_t">mps_fmt_t</a></code> is the opaque type of object formats. An object format is a way for the MPS andclient programs to communicate regarding the layout of client objects. For more information, seeFormat Protocol.</p>
<h4>Example</h4>
<pre>
#include "mps.h"
#include "mpscamc.h"
#include &lt;stdlib.h&gt;
struct mps_fmt_A_s fmt_A_s = {
(mps_align_t)4,
scan, skip, copy, move, isMoved, pad
};
void go(mps_space_t space)
{
mps_fmt_t format;
mps_res_t res;
mps_pool_t pool;
res = mps_fmt_create_A(&amp;format, space, &amp;mps_fmt_A_s);
if(res != MPS_RES_OK)
abort();
res = mps_pool_create(&amp;pool, space, mps_class_amc(), format);
if(res != MPS_RES_OK)
abort();
/* do some stuff here */
mps_pool_destroy(pool);
mps_format_destroy(format);
}
</pre>
<h4>See Also</h4>
<p>
<code><a href="#mps_fmt_create_A">mps_fmt_create_A</a></code>,
<code><a href="#mps_fmt_create_B">mps_fmt_create_B</a></code>,
<code><a href="#mps_fmt_destroy">mps_fmt_destroy</a></code>,
<code><a href="#mps_fmt_A_t">mps_fmt_A_t</a></code></p>
<h3>type <code><a id="mps_formatted_objects_stepper_t" name="mps_formatted_objects_stepper_t">mps_formatted_objects_stepper_t</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_formatted_objects_stepper_t">mps_formatted_objects_stepper_t</a></code></p>
<h4>Summary</h4>
<p>Type of the client supplied heap walker component.</p>
<h4>Associated Protocols</h4>
<p>None.</p>
<h4>Type</h4>
<p><code>typedef void (*mps_formatted_objects_stepper_t)(mps_addr_t, mps_fmt_t, mps_pool_t, void *,size_t )</code></p>
<h4>Arguments</h4>
<p>The function pointed to by an object of type <code><a href="#mps_formatted_objects_stepper_t">mps_formatted_objects_stepper_t</a></code> takes thefollowing argument list:</p>
<p><code>(mps_addr_t object, mps_fmt_t format, mps_pool_t pool, void *p, size_t s)</code></p>
<p><code>object</code> is a pointer to the (client) object.</p>
<p><code>format</code> is the MPS format of the client object.</p>
<p><code>pool</code> in the MPS pool in which the client object resides.</p>
<p><code>p</code> and <code>s</code> are two closure values which are copies of the corresponding values which the clientpassed into <code><a href="#mps_arena_formatted_objects_walk">mps_arena_formatted_objects_walk</a></code>.</p>
<h4>Returned Values</h4>
<p>The function pointed to by an object of type <code><a href="#mps_formatted_objects_stepper_t">mps_formatted_objects_stepper_t</a></code> returns noarguments.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>A pointer to a function is passed into the function <code><a href="#mps_arena_formatted_objects_walk">mps_arena_formatted_objects_walk</a></code>; the pointer has this type. The heap walker arranges to apply this function to all objects on the heap.</p>
<h4>Example</h4>
<p>&lt;example of how to use the symbol&gt;</p>
<h4>Error Handling</h4>
<p>The function pointed to by an object of type <code><a href="#mps_formatted_objects_stepper_t">mps_formatted_objects_stepper_t</a></code> have no way toreturn an error code to the caller.</p>
<h4>See Also</h4>
<p>
<code><a
href="#mps_arena_formatted_objects_arena_walk">mps_arena_formatted_objects_arena_walk</a></code></p>
<h4>Notes</h4>
<h3>function <code><a id="mps_free" name="mps_free">mps_free</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_free">mps_free</a></code></p>
<h4>Summary</h4>
<p>Frees a block of memory to a pool.</p>
<h4>Associated Protocols</h4>
<p>Allocation</p>
<h4>Syntax</h4>
<p><code>void mps_free(mps_pool_t pool, mps_addr_t p, size_t size);</code></p>
<h4>Arguments</h4>
<p><code>pool</code> the pool of the object to be freed</p>
<p><code>p</code> a pointer to the object to the freed</p>
<p><code>size</code> the size of the object to the freed in bytes</p>
<h4>Returned Values</h4>
<p>None.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>Frees an object of memory, returning the memory block to the pool it was allocated from.The pool might then decide to make it available to other pools, but the way this happens depends onthe pool class and the current situation.</p>
<h4>Example</h4>
<h4>See Also</h4>
<p>
<code><a href="#mps_alloc">mps_alloc</a></code></p>
<h4>Notes</h4>
<p><code><a href="#mps_free">mps_free</a></code> takes a size argument, because it is most efficient to do so. In practicalprograms, the type of an object is usually known at the point in the code that calls thedeallocation function, and hence the size is trivially available. In such cases. storing the size onthe MPS side would cost time and memory, and make it hard to get good virtual memory behaviour (asit is, the deallocation code doesn't have to touch the dead object at all).</p>
<p>Undoubtedly, one day, we'll get around to writing a pool that stores the size of eachobject.</p>
<h3>function <code><a id="mps_lib_memcmp" name="mps_lib_memcmp">mps_lib_memcmp</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_lib_memcmp">mps_lib_memcmp</a></code></p>
<h4>Summary</h4>
<p>A plinth function similar to C's "memcmp".</p>
<h4>Associated Protocols</h4>
<p>Plinth</p>
<h4>Syntax</h4>
<p><code>int mps_lib_memcmp(const void *s1, const void *s2, size_t n);</code></p>
<h4>Arguments</h4>
<p>s1, s2 pointers to memory blocks to be compared</p>
<p>n length of the blocks, in bytes</p>
<h4>Returned Values</h4>
<p>An integer that is greater than, equal to, or less than zero, accordingly as the blockpointed to by "s1" is greater than, equal to, or less than the block pointer to by "s2".</p>
<h4>Resources</h4>
<p>mpslib.h</p>
<h4>Description</h4>
<p>This function is intended to have the same semantics as the "memcmp" function of the ANSI Cstandard (section 7.11.4.1).</p>
<p>Like other plinth features, it is used by the MPS and provided by the client (possibly usingthe ANSI plinth, mpsliban.c).</p>
<h4>Example</h4>
<p>None, clients don't use it.</p>
<h4>Error Handling</h4>
<p>None.</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_lib_memset">mps_lib_memset</a></code>,
<code><a href="#mps_lib_memcpy">mps_lib_memcpy</a></code>,
mpsliban.c</p>
<h4>Notes</h4>
<p>None.</p>
<h3>function <code><a id="mps_lib_memcpy" name="mps_lib_memcpy">mps_lib_memcpy</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_lib_memcpy">mps_lib_memcpy</a></code></p>
<h4>Summary</h4>
<p>A plinth function similar to C's "memcpy".</p>
<h4>Associated Protocols</h4>
<p>Plinth</p>
<h4>Syntax</h4>
<p><code>void *mps_lib_memcpy(void *dest, const void *source, size_t n);</code></p>
<h4>Arguments</h4>
<p>dest destination of copy</p>
<p>source source of copy</p>
<p>n length of the blocks, in bytes</p>
<h4>Returned Values</h4>
<p>Returns the value of the dest argument.</p>
<h4>Resources</h4>
<p>mpslib.h</p>
<h4>Description</h4>
<p>This function is intended to have the same semantics as the "memcpy" function of the ANSI Cstandard (section 7.11.2.1).</p>
<p>Like other plinth features, it is used by the MPS and provided by the client (possibly usingthe ANSI plinth, mpsliban.c).</p>
<h4>Example</h4>
<p>None, clients don't use it.</p>
<h4>Error Handling</h4>
<p>None.</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_lib_memset">mps_lib_memset</a></code>,
<code><a href="#mps_lib_memcmp">mps_lib_memcmp</a></code>,
mpsliban.c</p>
<h4>Notes</h4>
<p>None.</p>
<h3>function <code><a id="mps_lib_memset" name="mps_lib_memset">mps_lib_memset</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_lib_memset">mps_lib_memset</a></code></p>
<h4>Summary</h4>
<p>A plinth function similar to C's "memset".</p>
<h4>Associated Protocols</h4>
<p>Plinth</p>
<h4>Syntax</h4>
<p><code>void *mps_lib_memset(void *s, int c, size_t n);</code></p>
<h4>Arguments</h4>
<p>s destination of copy</p>
<p>c byte (when converted to an unsigned char) to copy</p>
<p>n length of the block, in bytes</p>
<h4>Returned Values</h4>
<p>Returns the value of s.</p>
<h4>Resources</h4>
<p>mpslib.h</p>
<h4>Description</h4>
<p>This function is intended to have the same semantics as the "memset" function of the ANSI Cstandard (section 7.11.6.1).</p>
<p>Like other plinth features, it is used by the MPS and provided by the client (possibly usingthe ANSI plinth, mpsliban.c).</p>
<h4>Example</h4>
<p>None, clients don't use it.</p>
<h4>Error Handling</h4>
<p>None.</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_lib_memcpy">mps_lib_memcpy</a></code>,
<code><a href="#mps_lib_memcmp">mps_lib_memcmp</a></code>,
mpsliban.c</p>
<h4>Notes</h4>
<p>None.</p>
<h3><code><a id="mps_lib_telemetry_control" name="mps_lib_telemetry_control">mps_lib_telemetry_control</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_lib_telemetry_control">mps_lib_telemetry_control</a></code></p>
<h4>Summary</h4>
<p>Plinth function to supply a default value for telemetry filters from environment.</p>
<h4>Associated Protocols</h4>
<p>Telemetry</p>
<h4>Type</h4>
<p><code>unsigned long mps_lib_telemetry_control();</code></p>
<h4>Arguments</h4>
<p>None.</p>
<h4>Initial/Default Values</h4>
<p>In the absence of environmental data, a default of zero is recommended.</p>
<h4>Returned Values</h4>
<p>The default value of the telemetry filter, as derived from the environment. It isrecommended that the environment be consulted for a symbol analagous to <code><a href="#MPS_TELEMETRY_CONTROL">MPS_TELEMETRY_CONTROL</a></code>, subject to local restrictions.</p>
<h4>Resources</h4>
<p>Depends on access to the environment.</p>
<h4>Description</h4>
<p>See <code><a href="#mps_telemetry_control">mps_telemetry_control</a></code> for more information on the significant of the values.</p>
<p></p>
<h4>Example</h4>
<p>See the supplied ANSI plinth for an example implementation.</p>
<h4>See Also</h4>
<p>
<code><a
href="#mps_telemetry_control">mps_telemetry_control</a></code></p>
<h3>function <code><a id="mps_message_discard" name="mps_message_discard">mps_message_discard</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_message_discard">mps_message_discard</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_message_discard">mps_message_discard</a></code> is used to indicate that there is no further use for thespecified message.</p>
<h4>Associated Protocols</h4>
<p>Message.</p>
<h4>Syntax</h4>
<p><code>void mps_message_discard(mps_arena_t arena, mps_message_t message)</code></p>
<h4>Arguments</h4>
<p>
<code>arena</code>
-- the arena
</p>
<p>
<code>message</code>
-- the message
</p>
<h4>Returned Values</h4>
<p>None.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p><code><a href="#mps_message_discard">mps_message_discard</a></code>
is used to indicate that the client has no further use for the specified message in the specified arena. After this, the message may not be passed as argumentto any message functions.</p>
<p>This procedure is called by the client program as a courtesy, to avoid the use of unboundedresources by the message queue itself and any other MPS-managed objects referred to by the message.</p>
<h4>Example</h4>
<p>[missing]</p>
<h4>Error Handling</h4>
<p>Can't fail.</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_message_get">mps_message_get</a></code></p>
<h4>Notes</h4>
<p>A finalized object will not be reclaimed by the collector until the finalization message hasbeen discarded, because the message contains a reference to the object.</p>
<h3>function <code><a id="mps_message_finalization_ref" name="mps_message_finalization_ref">mps_message_finalization_ref</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_message_finalization_ref">mps_message_finalization_ref</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_message_finalization_ref">mps_message_finalization_ref</a></code> returns the "finalization reference" property of thespecified message in the specified arena.</p>
<h4>Associated Protocols</h4>
<p>Message, finalization.</p>
<h4>Syntax</h4>
<p><code>void mps_message_finalization_ref(mps_addr_t *object_ref, mps_arena_t arena, mps_message_tmessage) </code></p>
<h4>Arguments</h4>
<p>object_ref -- a reference to a reference to the object to which the message belongs</p>
<p>arena -- the arena that the message is in</p>
<p>message -- a message of a message type that supports this method</p>
<h4>Returned Values</h4>
<p>None.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>This method returns the "finalization reference" property of the specified message in thespecified arena. The message must be of a message type that supports this method. Currently, theonly such type is that of finalization messages, as returned by <code><a href="#mps_message_type_finalization">mps_message_type_finalization</a></code>.</p>
<p>Note that the reference returned is subject to the normal constraints such as movingcollection, if appropriate. For this reason, it is returned indirectly via "object_ref" to enablethe client to place it directly into scanned memory, without imposing the restriction that the Cstack be a root.</p>
<p>Note that the invocation of this method does not affect the liveness of the specifiedmessage and hence the liveness of the object referred to by "object_ref. Use <code><a href="#mps_message_discard">mps_message_discard</a></code> to discard messages.</p>
<h4>Example</h4>
<h4>Error Handling</h4>
<h4>See Also</h4>
<p>
<code>mps_message_*</code>,
<code><a href="#mps_finalize">mps_finalize</a></code></p>
<h3>function <code><a id="mps_message_gc_condemned_size" name="mps_message_gc_condemned_size">mps_message_gc_condemned_size</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_message_gc_condemned_size">mps_message_gc_condemned_size</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_message_gc_condemned_size">mps_message_gc_condemned_size</a></code> returns the "condemned size" property of the specified message in the specified arena.</p>
<h4>Associated Protocols</h4>
<p>Message, GC.</p>
<h4>Syntax</h4>
<p><code>size_t mps_message_gc_condemned_size(mps_arena_t arena, mps_message_tmessage)</code></p>
<h4>Arguments</h4>
<p><code class="source"> arena</code>-- the arena</p>
<p>
<code class="source">
message</code>-- a message of a message type that supports this method
</p>
<h4>Returned Values</h4>
<p>An approximate size for the set of objects condemned in the collection that generated themessage.</p>
<h4>Resources</h4>
<p>
<code class="filename">
mps.h
</code>
</p>
<h4>Description</h4>
<p>Currently, the only type of message that supports this property is <code><a href="#mps_message_type_gc">mps_message_type_gc</a></code>, such messages are generated whenever a garbage collectioncompletes. This method returns an approximation to the size of the set of objects that werecondemned in that collection.</p>
<h4>Example</h4>
<h4>Error Handling</h4>
<h4>See Also</h4>
<p>
<code>mps_message_*</code></p>
<h3>function <code><a id="mps_message_gc_live_size" name="mps_message_gc_live_size">mps_message_gc_live_size</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_message_gc_live_size">mps_message_gc_live_size</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_message_gc_live_size">mps_message_gc_live_size</a></code> returns the "live size" property of thespecified message in the specified arena.</p>
<h4>Associated Protocols</h4>
<p>Message, GC.</p>
<h4>Syntax</h4>
<p><code class="source"> size_t mps_message_gc_live_size(mps_arena_t arena, mps_message_t message) </code></p>
<h4>Arguments</h4>
<p><code class="source"> arena </code> -- the arena;</p>
<p><code class="source"> message </code> -- a message of a message type that supports thismethod.</p>
<h4>Returned Values</h4>
<p>The total size of the condemned objects that survived the collection that generated themessage.</p>
<h4>Resources</h4>
<p>
<code class="filename">
mps.h
</code>
</p>
<h4>Description</h4>
<p>Currently, the only type of message that supports this property is <code><a href="#mps_message_type_gc">mps_message_type_gc</a></code>, such messages are generated whenever a garbage collectioncompletes. This method returns the size of the set of objects that were condemned in thatcollection, but survived.</p>
<h4>Example</h4>
<h4>Error Handling</h4>
<h4>See Also</h4>
<p>
<code>mps_message_*</code></p>
<h3>function <code><a id="mps_message_gc_not_condemned_size" name="mps_message_gc_not_condemned_size">mps_message_gc_not_condemned_size</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_message_gc_not_condemned_size">mps_message_gc_not_condemned_size</a></code></p>
<h4>Summary</h4>
<p><code class="source"> mps_message_gc_not_condemned_size </code> returns the "not condemnedsize" property of the specified message in the specified arena.</p>
<h4>Associated Protocols</h4>
<p>Message, GC.</p>
<h4>Syntax</h4>
<p><code class="source"> size_t mps_message_gc_not_condemned_size(mps_arena_t arena,mps_message_t message) </code></p>
<h4>Arguments</h4>
<p>
<code class="source">
arena
</code>
-- the arena
</p>
<p>
<code class="source">
message
</code>
-- a message of a message type that supports this method
</p>
<h4>Returned Values</h4>
<p>An approximate size for the set of objects that were in collected pools, but were notcondemned in the collection that generated the message.</p>
<h4>Resources</h4>
<p><code class="filename"> mps.h </code></p>
<h4>Description</h4>
<p>Currently, the only type of message that supports this property is <code><a href="#mps_message_type_gc">mps_message_type_gc</a></code>; such messages are generated whenever a garbage collectioncompletes. This method returns an approximation to the size of the set of objects that were incollected pools (so potentially subject to garbage collection), but were not condemned in thatcollection.</p>
<h4>Example</h4>
<h4>Error Handling</h4>
<h4>See Also</h4>
<p>
<code>mps_message_*</code></p>
<h3>function <code><a id="mps_message_get" name="mps_message_get">mps_message_get</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_message_get">mps_message_get</a></code></p>
<h4>Summary</h4>
<p>Gets a message of the specified type from a message queue.</p>
<h4>Associated Protocols</h4>
<p>Message.</p>
<h4>Syntax</h4>
<p><code>mps_bool_t mps_message_get(mps_message_t *message_return, mps_arena_t arena, mps_message_type_tmessage_type)</code></p>
<h4>Arguments</h4>
<p>
<code>message_return</code>
-- the handle to the message that was removed from the queue
</p>
<p>
<code>arena</code>
-- the arena
</p>
<p>
<code>message_type</code>
-- the type of message
</p>
<h4>Returned Values</h4>
<p>Returns true if a message has been removed from the queue, false if not.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>
If there is a message of the specified type on the message queue of the specified arena,then this function removes one such message from the queue, returns a handle to it via the<code>message_return
</code>
argument, and returns true. Otherwise it returns false.
</p>
<h4>Example</h4>
<h4>See Also</h4>
<p>
<code>mps_message_*</code></p>
<h3><code><a id="mps_message_poll" name="mps_message_poll">mps_message_poll</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_message_poll">mps_message_poll</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_message_poll">mps_message_poll</a></code> determines whether there are currently any messages on amessage queue.</p>
<h4>Associated Protocols</h4>
<p>Message.</p>
<h4>Syntax</h4>
<p><code>mps_bool_t mps_message_poll(mps_arena_t arena)</code></p>
<h4>Arguments</h4>
<p>
<code>arena</code>
-- the arena whose message queue you are interested in
</p>
<h4>Returned Values</h4>
<p>A flag to indicate whether there are any messages on the queue.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p><code><a href="#mps_message_poll">mps_message_poll</a></code> is used to determine whether there are currently any messageson the message queue of the specified arena.</p>
<h4>Example</h4>
<p>[missing]</p>
<h4>Error Handling</h4>
<p>Can't fail.</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_message_get">mps_message_get</a></code></p>
<h4>Notes</h4>
<p>If you expect a particular type of message, it is usually more practical to just call <code><a href="#mps_message_get">mps_message_get</a></code>.</p>
<h3>function <code><a id="mps_message_queue_type" name="mps_message_queue_type">mps_message_queue_type</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_message_queue_type">mps_message_queue_type</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_message_queue_type">mps_message_queue_type</a></code> returns the type of the first message on a message queue.</p>
<h4>Associated Protocols</h4>
<p>Message.</p>
<h4>Syntax</h4>
<p><code>mps_bool_t mps_message_queue_type(mps_message_type_t *message_type_return, mps_arena_t arena)</code></p>
<h4>Arguments</h4>
<p>message_type_return -- the type of the first message on the queue of the specified arena</p>
<p>arena -- the arena</p>
<h4>Returned Values</h4>
<p>"True" if there are any messages on the queue of the specified arena, "false" if not.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>If there are any messages on the queue of the specified arena, then this function returns"true", and also returns the type of the first message via "message_type_return". Otherwise itreturns "false".</p>
<h4>Example</h4>
<h4>See Also</h4>
<p>
<code>mps_message_*</code></p>
<h3>type <code><a id="mps_message_t" name="mps_message_t">mps_message_t</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_message_t">mps_message_t</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_message_t">mps_message_t</a></code> is used as a handle on an individual message.</p>
<h4>Associated Protocols</h4>
<p>Message.</p>
<h4>Type</h4>
<p><code>typedef struct mps_message_s *mps_message_t</code></p>
<p><code><a href="#mps_message_s">mps_message_s</a></code> is an incomplete structure type used only to declare the opaque type <code><a href="#mps_message_t">mps_message_t</a></code>.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>The opaque type <code><a href="#mps_message_t">mps_message_t</a></code> is used as a handle on an individual message. Messages aremanually managed. They are created at the instigation of the MPS (but see <code><a href="#mps_message_type_enable">mps_message_type_enable</a></code>), and are deleted by the client.</p>
<p>An <code><a href="#mps_message_t">mps_message_t</a></code> is a reference into MPS managed memory, and can safely be stored as suchin scannable memory.</p>
<h4>Example</h4>
<h4>Error Handling</h4>
<p>Not applicable.</p>
<h4>See Also</h4>
<p>
<code>mps_message_*</code></p>
<h3>function <code><a id="mps_message_type" name="mps_message_type">mps_message_type</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_message_type">mps_message_type</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_message_type">mps_message_type</a></code> returns the type of a message.</p>
<h4>Associated Protocols</h4>
<p>Message.</p>
<h4>Syntax</h4>
<p><code>mps_message_type_t mps_message_type(mps_arena_t arena, mps_message_t message)</code></p>
<h4>Arguments</h4>
<p>arena -- the arena containing the message</p>
<p>message -- a valid message; that is, one previously returned by <code><a href="#mps_message_get">mps_message_get</a></code>, and notdiscarded via <code><a href="#mps_message_discard">mps_message_discard</a></code></p>
<h4>Returned Values</h4>
<p>The type of the specified message.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p><code><a href="#mps_message_type">mps_message_type</a></code> returns the type of a message.</p>
<h4>Example</h4>
<h4>Error Handling</h4>
<h4>See Also</h4>
<p>
<code>mps_message_*</code></p>
<h3>function <code><a id="mps_message_type_disable" name="mps_message_type_disable">mps_message_type_disable</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_message_type_disable">mps_message_type_disable</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_message_type_disable">mps_message_type_disable</a></code> restores the arena to the default state whereby messages of thespecified type are not generated.</p>
<p>This reverses the effect of an earlier call to "m ps_message_type_enable".</p>
<h4>Associated Protocols</h4>
<p>Message.</p>
<h4>Syntax</h4>
<p><code>void mps_message_type_disable(mps_arena_t arena, mps_message_type_t message_type)</code></p>
<h4>Arguments</h4>
<p>arena -- the arena</p>
<p>message_type -- the message type to be disabled</p>
<h4>Returned Values</h4>
<p>None.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>This procedure may be used by the client to specify that messages of the specified typeshould not created for the specified arena.</p>
<p>Messages are not generated by default, but the client may enable the generation of messageswith <code><a href="#mps_message_type_enable">mps_message_type_enable</a></code>.</p>
<p>Any existing messages of the specified type are flushed from the message queue.</p>
<h4>Example</h4>
<p>[none]</p>
<h4>Error Handling</h4>
<p>Never fails.</p>
<h4>See Also</h4>
<p>
<code>mps_message_*</code></p>
<h4>Notes</h4>
<p>It is permitted to call this function when the message type is already disabled. Such a callwill have no effect.</p>
<h3>function <code><a id="mps_message_type_enable" name="mps_message_type_enable">mps_message_type_enable</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_message_type_enable">mps_message_type_enable</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_message_type_enable">mps_message_type_enable</a></code> allows messages of the specified type to be created for thespecified arena. Without such enabling, the MPS will, by default, not generate any messages of thattype.</p>
<h4>Associated Protocols</h4>
<p>Message.</p>
<h4>Syntax</h4>
<p><code>void mps_message_type_enable(mps_arena_t arena, mps_message_type_t message_type)</code></p>
<h4>Arguments</h4>
<p>arena -- the arena</p>
<p>message_type -- the message type to be enabled</p>
<h4>Returned Values</h4>
<p>None.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>This procedure may be used by the client to specify that messages of the specified type maybe created for the specified arena. Without such enabling, the MPS will by default not generate anymessages of that type.</p>
<p>Note that the enabling of messages of a particular type implies that the client applicationwill handle and discard message of that type, or the message queue may consume unbounded resources.</p>
<p>The client may disable message generation again by means of an equivalent call to <code><a href="#mps_message_type_disable">mps_message_type_disable</a></code>.</p>
<h4>Example</h4>
<p>[none]</p>
<h4>Error Handling</h4>
<p>Never fails.</p>
<h4>See Also</h4>
<p>
<code>mps_message_*</code></p>
<p>"Message Protocol"</p>
<h4>Notes</h4>
<p>It is permitted to call this function when the message type is already enabled. Such a callwill have no effect.</p>
<p></p>
<h3>function <code><a id="mps_message_type_finalization" name="mps_message_type_finalization">mps_message_type_finalization</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_message_type_finalization">mps_message_type_finalization</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_message_type_finalization">mps_message_type_finalization</a></code> returns the type of finalization messages.</p>
<h4>Associated Protocols</h4>
<p>Message, Finalization.</p>
<h4>Syntax</h4>
<p><code>mps_message_type_t mps_message_type_finalization(void) </code></p>
<h4>Arguments</h4>
<p>None.</p>
<h4>Returned Values</h4>
<p>The type of finalization messages.</p>
<h4>Resources</h4>
<p>Not applicable.</p>
<h4>Description</h4>
<p><code><a href="#mps_message_type_finalization">mps_message_type_finalization</a></code> returns the type of finalization messages. Finalizationmessages are used by the MPS see signal to the client that an object has become finalizable. Inaddition to the usual methods applicable to messages, finalization messages support the <code><a href="#mps_message_finalization_ref">mps_message_finalization_ref</a></code> method which returns a reference to the registered object.</p>
<h4>Example</h4>
<pre>
{
mps_message_type_t type;
if( mps_message_queue_type(&amp;type, arena) ) {
if(type == mps_message_type_finalization()) {
process_finalization_message_from_queue();
} else {
unknown_message_type();
}
}
}
</pre>
<h4>See Also</h4>
<p>
<code>mps_message_*</code>,
<code><a href="#mps_finalize">mps_finalize</a></code></p>
<h3>function <code><a id="mps_message_type_gc" name="mps_message_type_gc">mps_message_type_gc</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_message_type_gc">mps_message_type_gc</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_message_type_gc">mps_message_type_gc</a></code> returns the type of garbage collectionstatistic messages.</p>
<h4>Associated Protocols</h4>
<p>Message.</p>
<h4>Syntax</h4>
<p><code class="source"> mps_message_type_t mps_message_type_gc(void) </code></p>
<h4>Arguments</h4>
<p>None.</p>
<h4>Returned Values</h4>
<p>The type of garbage collection statistic messages.</p>
<h4>Resources</h4>
<p>
<code class="filename">
mps.h
</code>
</p>
<h4>Description</h4>
<p><code><a href="#mps_message_type_gc">mps_message_type_gc</a></code> returns the type of garbage collectionstatistic messages. Garbage collection statistic messages are used by the MPS to give the clientinformation about garbage collections that have occurred. Such information may be useful inanalysing the client's memory usage over time.</p>
<p>The access methods specific to a message of this type are:</p>
<ul>
<li><p><code class="source"> mps_message_gc_live_size </code> -- gives the total size of thecondemned objects that survived the collection that generated the message</p></li>
<li><p><code class="source"> mps_message_gc_condemned_size </code>
-- gives an approximate size for the set of objects condemned in the collection that generated the message.</p></li>
<li><p><code class="source"> mps_message_gc_not_condemned_size </code> -- gives an approximate sizefor the set of objects that were in collected pools, but were not condemned in the collection thatgenerated the message.</p></li>
</ul>
<h4>Example</h4>
<pre>
{
mps_message_t message;
if(mps_message_get(&amp;message, arena, mps_message_type_gc())) {
size_t live, condemned, not_condemned;
live = mps_message_gc_live_size(arena, message);
condemned = mps_message_gc_condemned_size(arena, message);
not_condemned = mps_message_gc_not_condemned_size(arena,message);
mps_message_discard(arena, message);
process_collection_stats(live, condemned, not_condemned);
}
}
</pre>
<h4>Error Handling</h4>
<p>Cannot fail.</p>
<h4>See Also</h4>
<p>
<code>mps_message_*</code>.</p>
<h3>type <code><a id="mps_message_type_t" name="mps_message_type_t">mps_message_type_t</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_message_type_t">mps_message_type_t</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_message_type_t">mps_message_type_t</a></code> is the type of message types.</p>
<h4>Associated Protocols</h4>
<p>Message.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p><code><a href="#mps_message_type_t">mps_message_type_t</a></code> is the type whose values are the various message types. It is opaque.</p>
<h4>Example</h4>
<h4>See Also</h4>
<p>
<code>mps_message_*</code></p>
<h3>function <code><a id="mps_pool_check_fenceposts" name="mps_pool_check_fenceposts">mps_pool_check_fenceposts</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_pool_check_fenceposts">mps_pool_check_fenceposts</a></code></p>
<h4>Summary</h4>
<p>Check all the fenceposts in the pool.</p>
<h4>Associated Protocols</h4>
<p>Debug</p>
<h4>Syntax</h4>
<p><code>void mps_pool_check_fenceposts(mps_pool_t pool)</code></p>
<h4>Arguments</h4>
<p>pool the pool whose fenceposts are to be checked</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>This function is a debugging feature to check all the fenceposts in the pool. If a corruptedfencepost is found, an assert will fire. It is only useful to call this on a debug pool that hadfenceposting turned, it does nothing on other pools.</p>
<h4>Example</h4>
<p><code>mps_pool_check_fenceposts(gene_pool);</code></p>
<h4>Error Handling</h4>
<p>If a corrupted fencepost is found, an assert will fire. You will
probably want to look at the problem with a debugger.</p>
<h4>See Also</h4>
<p>
<code>mps_class_*_debug</code></p>
<h3>structure <code><a id="mps_pool_debug_option_s" name="mps_pool_debug_option_s">mps_pool_debug_option_s</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_pool_debug_option_s">mps_pool_debug_option_s</a></code></p>
<h4>Summary</h4>
<p>This structure is used to pass debug options to <code><a href="#mps_pool_create">mps_pool_create</a></code> for debug classes.</p>
<h4>Associated Protocols</h4>
<p>Debug.</p>
<h4>Type</h4>
<pre>
typedef struct mps_pool_debug_option_s {
void *fence_template;
size_t fence_size;
} mps_pool_debug_option_s;
</pre>
<h4>Members</h4>
<p>
<code>fence_template</code>
the template for fencepost contents
</p>
<p>
<code>fence_size</code>
the size of the template in bytes
</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>Structures of this type are used to pass debug options to <code><a href="#mps_pool_create">mps_pool_create</a></code> when creatinginstances of debug classes.</p>
<p>Fenceposting is enabled by specifying a non-zero <code>fence_size</code>; the size mustbe a multiple of the [pool/format] alignment. The content of fenceposts is given as a template thatis simply copied onto each fencepost (although sometimes the MPS will create fenceposts smaller thanthe given size, for example, to pad out some bit that was left unused because of alignmentrequirements).</p>
<h4>Example</h4>
<pre>
static mps_pool_debug_option_s debugOptions = { (void *)"postpost", 8 };
if(mps_pool_create(&amp;pool, arena, mps_class_ams_debug(),
&amp;debugOptions, 8192, 135, 8)
!= MPS_RES_OK) {
printf("Error creating pool!"); exit(2);
}
</pre>
<h4>See Also</h4>
<p>
<code><a
href="#mps_pool_check_fenceposts">mps_pool_check_fenceposts</a></code></p>
<h4>Notes</h4>
<p>Fencepost templates allow the client to specify complicated patterns that mimic illegal datavalues, that would cause an assert to fire if read by mistake, and that would never be written byany operation that writes at the wrong address by mistake.</p>
<p>Another trick is to make the pattern contain an instruction sequence that would cause theprogram to error or stop if executed by mistake.</p>
<h3>function <code><a id="mps_rank_ambig" name="mps_rank_ambig">mps_rank_ambig</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_rank_ambig">mps_rank_ambig</a></code></p>
<h4>Summary</h4>
<p>Function returning the value representing "rank ambig".</p>
<h4>Associated Protocols</h4>
<p>Allocation, Root, Scanning.</p>
<h4>Syntax</h4>
<p><code>mps_rank_ambig()</code></p>
<h4>Type</h4>
<p><code>mps_rank_t mps_rank_ambig(void)</code></p>
<h4>Arguments</h4>
<p>None.</p>
<h4>Returned Values</h4>
<p>Returns a value of type <code><a href="#mps_rank_t">mps_rank_t</a></code> representing "rank ambig".</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>Used to get a value for "rank ambig", which is used to denote that certain references (in aroot, for example) are ambiguous references.</p>
<h4>Example</h4>
<h4>See Also</h4>
<p>
<code><a href="#mps_rank_t">mps_rank_t</a></code>,
<code><a href="#mps_rank_exact">mps_rank_exact</a></code></p>
<h3>function <code><a id="mps_rank_exact" name="mps_rank_exact">mps_rank_exact</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_rank_exact">mps_rank_exact</a></code></p>
<h4>Summary</h4>
<p>Used to declare references which the client wishes to be exact references.</p>
<h4>Associated Protocols</h4>
<p>Allocation, Root, Scanning.</p>
<h4>Type</h4>
<p><code>mps_rank_t mps_rank_exact(void);</code></p>
<h4>Arguments</h4>
<p>No arguments.</p>
<h4>Returned Values</h4>
<p>Returns a rank (see <code><a href="#mps_rank_t">mps_rank_t</a></code>) which can be used to declare references to be exactreferences.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>Used to declare references which the client wishes to be exact, non-weak references.</p>
<h4>Example</h4>
<p>[missing]</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_rank_t">mps_rank_t</a></code>,
<code><a href="#mps_rank_ambig">mps_rank_ambig</a></code>,
<code><a href="#mps_rank_weak">mps_rank_weak</a></code></p>
<h3>type <code><a id="mps_rank_t" name="mps_rank_t">mps_rank_t</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_rank_t">mps_rank_t</a></code></p>
<h4>Summary</h4>
<p>A type whose values are "reference ranks".</p>
<h4>Associated Protocols</h4>
<p>Allocation, Root.</p>
<h4>Type</h4>
<p><code>typedef unsigned int mps_rank_t;</code></p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p><code><a href="#mps_rank_t">mps_rank_t</a></code> is a concrete type. It is an alias (via the C typedef mechanism) for "unsignedint" provided for convenience and clarity. An object of type <code><a href="#mps_rank_t">mps_rank_t</a></code> can store a valuerepresenting one reference rank. Reference ranks are used to conveniently express specific semanticsof particular references. See "MPS Scanning Protocol" for descriptions of these semantics, and <code>mps_rank_*</code> for the actual ranks used to declare these semantics.</p>
<h4>Example</h4>
<p>(Probably won't be used explicitly, most likely to be seen in the prototype declaration forother MPS functions. For example, <code><a href="#mps_root_create">mps_root_create</a></code>.)</p>
<h4>See Also</h4>
<p>
<code>mps_rank_*</code></p>
<h3>function <code><a id="mps_rank_weak" name="mps_rank_weak">mps_rank_weak</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_rank_weak">mps_rank_weak</a></code></p>
<h4>Summary</h4>
<p>Function to return a value used to represent "rank weak".</p>
<h4>Associated Protocols</h4>
<p>Allocation, Scanning.</p>
<h4>Type</h4>
<p><code>extern mps_rank_t mps_rank_weak(void);</code></p>
<h4>Arguments</h4>
<p>None.</p>
<h4>Returned Values</h4>
<p>Returns a value of type <code><a href="#mps_rank_t">mps_rank_t</a></code> that represent "rank weak".</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p><code><a href="#mps_rank_weak">mps_rank_weak</a></code> returns a value used to represent "rank weak".</p>
<p>"Rank weak" is often used to denote that certain references (in a root or in objectsallocated in a pool) are weak references.</p>
<h4>Example</h4>
<p>&lt;example of how to use the symbol&gt;</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_rank_t">mps_rank_t</a></code>,
<code><a href="#mps_rank_exact">mps_rank_exact</a></code></p>
<h3>type <code><a id="mps_reg_scan_t" name="mps_reg_scan_t">mps_reg_scan_t</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_reg_scan_t">mps_reg_scan_t</a></code></p>
<h4>Summary</h4>
<p>Type of root scanning functions for <code><a href="#mps_root_create_reg">mps_root_create_reg</a></code>.</p>
<h4>Associated Protocols</h4>
<p>Root.</p>
<h4>Syntax</h4>
<p><code>typedef mps_res_t (*mps_reg_scan_t)( mps_ss_t scan_state, mps_thr_t thread, void *p, size_t s)</code></p>
<h4>Arguments</h4>
<p>scan_state a scan state</p>
<p>thread the thread</p>
<p>p a value passed through from root registration</p>
<p>s a value passed through from root registration</p>
<h4>Returned Values</h4>
<p>A result code.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>This is the type of root scanning functions the client provides to <code><a href="#mps_root_create_reg">mps_root_create_reg</a></code>.These functions will be called, whenever the root needs to be scanned, and passed the "p" and "s"values specified in the call to <code><a href="#mps_root_create_reg">mps_root_create_reg</a></code>.</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_root_create_reg">mps_root_create_reg</a></code>,
<code><a
href="#mps_stack_scan_ambig">mps_stack_scan_ambig</a></code></p>
<h4>Notes</h4>
<p>Users are not expected to write any scanning functions of this type. The one functionsupplied with the MPS, <code><a href="#mps_stack_scan_ambig">mps_stack_scan_ambig</a></code>, should be enough for most purposes.</p>
<h3>type <code><a id="mps_res_t" name="mps_res_t">mps_res_t</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_res_t">mps_res_t</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_res_t">mps_res_t</a></code> is the type of result codes returned by operations that may fail.</p>
<h4>Type</h4>
<p><code>typedef int mps_res_t;</code></p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>A result code indicates the success or failure of an operation, along with the reason forfailure. Like UNIX error codes, the meaning of the code depends on the call that returned it. Referto the documentation of the function for the exact meaning. This documentation describes the broadcategories with mnemonic names for various sorts of problems.</p>
<p><code><a id="MPS_RES_OK" name="MPS_RES_OK">MPS_RES_OK</a></code>: The operation succeeded. Out and in/out parameters will only be updated if OK isreturned, otherwise they will be left untouched. <code><a href="#MPS_RES_OK">MPS_RES_OK</a></code> is zero.</p>
<p><code><a id="MPS_RES_FAIL" name="MPS_RES_FAIL">MPS_RES_FAIL</a></code>: Something went wrong that does not fall into any of the other categories. Theexact meaning depends on the call. See the documentation of the function.</p>
<p><code><a id="MPS_RES_RESOURCE" name="MPS_RES_RESOURCE">MPS_RES_RESOURCE</a></code>: A needed resource could not be obtained. Which resource, depends on thecall. Compare with <code><a href="#MPS_RES_MEMORY">MPS_RES_MEMORY</a></code>, which is a special case of this.</p>
<p><code><a id="MPS_RES_MEMORY" name="MPS_RES_MEMORY">MPS_RES_MEMORY</a></code>: Needed memory (committed memory, not address space) could not be obtained.</p>
<p><code><a id="MPS_RES_LIMIT" name="MPS_RES_LIMIT">MPS_RES_LIMIT</a></code>: An internal limitation was reached. For example, the maximum number ofsomething was reached.</p>
<p><code><a id="MPS_RES_UNIMPL" name="MPS_RES_UNIMPL">MPS_RES_UNIMPL</a></code>: The operation, or some vital part of it, is unimplemented. This might bereturned by functions that are no longer supported, or by operations that are included for futureexpansion, but not yet supported.</p>
<p><code><a id="MPS_RES_IO" name="MPS_RES_IO">MPS_RES_IO</a></code>: An I/O error occurred. Exactly what depends on the function.</p>
<p><code><a id="MPS_RES_COMMIT_LIMIT" name="MPS_RES_COMMIT_LIMIT">MPS_RES_COMMIT_LIMIT</a></code>: The arena's commit limit would have been exceeded as a result of(explicit or implicit) allocation. See protocol.arena.commit.</p>
<p><code><a id="MPS_RES_PARAM" name="MPS_RES_PARAM">MPS_RES_PARAM</a></code>: A parameter of the operation was invalid.</p>
<h4>A</h4>
<p>ny function that might fail will return a result code. Any other results of the function arebe passed back in "return" parameters. See MPS Interface Conventions for more information.</p>
<h4>Example</h4>
<pre>
mps_addr_t p;
mps_res_t res;
res = mps_alloc(&amp;p, pool, sizeof(struct spong));
if(res != MPS_RES_OK) {
handle_memory_error(res);
abort();
}
</pre>
<p>For more examples, s ee doc.mps.ref-man.if-conv.</p>
<h4>See Also</h4>
<p>
<code>MPS_RES_*</code></p>
<h3>function <code><a id="mps_root_create" name="mps_root_create">mps_root_create</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_root_create">mps_root_create</a></code></p>
<h4>Summary</h4>
<p>The function <code><a href="#mps_root_create">mps_root_create</a></code> declares a root that consists of all the references indicatedby a scanning function.</p>
<h4>Associated Protocols</h4>
<p>Root.</p>
<h4>Syntax</h4>
<p><code>mps_res_t mps_root_create(mps_root_t *root_o, mps_arena_t arena, mps_rank_t rank, mps_rm_trm, mps_root_scan_t scan, void *p, size_t s)</code></p>
<h4>Arguments</h4>
<p>root_o a pointer to a variable to store the new root structure</p>
<p>arena the arena</p>
<p>rank the rank of references in the root</p>
<p>rm the root mode</p>
<p>scan the scanning function</p>
<p>p a value to be passed to the scanning function</p>
<p>s a value to be passed to the scanning function</p>
<h4>Returned Values</h4>
<p>If the return value is <code><a href="#MPS_RES_OK">MPS_RES_OK</a></code>, a new root structure in "*root_o".</p>
<h4>Resources</h4>
<p>mps.h.</p>
<h4>Description</h4>
<p>The client provides a scanning function, that will be called with a scan state and "p" and"s", whenever the root needs to be scanned. See <code><a href="#mps_root_scan_t">mps_root_scan_t</a></code> for details.</p>
<p>If the rank of the root is not <code><a href="#MPS_RANK_AMBIG">MPS_RANK_AMBIG</a></code>, the contents of the root have to be validwhenever a GC happens, i.e., they have to be references to actual objects or "NULL". If you're usingasynchronous GC, this could be right after the root is registered, so the root has to be valid whenit is registered. It's OK for a root to have entries which point to memory not managed by the MPS --they will simply be ignored.</p>
<h4>Example</h4>
<pre>
static mps_root_t mmRoot;
int main(void)
{
mps_res_t res;
/* ... */
res = mps_root_create(&amp;mmRoot, arena, MPS_RANK_EXACT, (mps_rm_t)0,
&amp;rootScanner, NULL, 0);
/* see doc of mps_root_scan_t for definition of rootScanner */
if(res != MPS_RES_OK)
exit(1);
/* ... */
}
</pre>
<h4>Error Handling</h4>
<p><code><a href="#mps_root_create">mps_root_create</a></code> returns <code><a href="#MPS_RES_MEMORY">MPS_RES_MEMORY</a></code> when it fails to allocate memory for the internalroot structure; you need to deallocate or reclaim something to make enough space, or expand thearena.</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_root_scan_t">mps_root_scan_t</a></code>,
<code><a href="#mps_rm_t">mps_rm_t</a></code>,
<code><a href="#mps_rank_t">mps_rank_t</a></code>,
<code><a href="#mps_root_t">mps_root_t</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_RM_CONST">MPS_RM_CONST</a></code></p>
<h4>Notes</h4>
<p>"p" and "s" are just arbitrary data that scanning function can use. This is needed because Clacks local functions.</p>
<h3>function <code><a id="mps_root_create_fmt" name="mps_root_create_fmt">mps_root_create_fmt</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_root_create_fmt">mps_root_create_fmt</a></code></p>
<h4>Summary</h4>
<p>The function <code><a href="#mps_root_create_fmt">mps_root_create_fmt</a></code> declares a root that consists of a block of objects, andprovides a scanning function for them.</p>
<h4>Associated Protocols</h4>
<p>Root.</p>
<h4>Syntax</h4>
<p><code>mps_res_t mps_root_create_fmt(mps_root_t *root_o, mps_arena_t arena, mps_rank_t rank, mps_rm_t rm, mps_fmt_scan_t scan, mps_addr_t base, mps_addr_t limit) </code></p>
<h4>Arguments</h4>
<p>root_o a pointer to a variable to store the new root structure</p>
<p>arena the arena</p>
<p>rank the rank of references in the root</p>
<p>rm the root mode</p>
<p>scan the scanning function</p>
<p>base the address of the start of the root</p>
<p>limit the address just beyond the end of the root</p>
<h4>Returned Values</h4>
<p>If the return value is <code><a href="#MPS_RES_OK">MPS_RES_OK</a></code>, the new root in "*root_o".</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>The client provides a scanning function, that will be called with a scan state and an areaof memory, whenever the root needs to be scanned. See <code><a href="#mps_fmt_scan_t">mps_fmt_scan_t</a></code> for details.</p>
<p>If the rank of the root is not <code><a href="#MPS_RANK_AMBIG">MPS_RANK_AMBIG</a></code>, the contents of the root have to be validwhenever a GC happens, i.e., they have to be references to actual objects or "NULL". If you're usingasynchronous GC, this could be right after the root is registered, so the root has to be valid whenit is registered. It's OK for a root to have entries which point to memory not managed by the MPS --they will simply be ignored.</p>
<h4>Example</h4>
<pre>
static mps_root_t mmRoot;
SegmentDescriptor DataSegment;
int main(void)
{
mps_res_t res;
/* ... */
res = mps_root_create_fmt(&amp;mmRoot, arena, MPS_RANK_EXACT, (mps_rm_t)0,
&amp;scan_objs,
(mps_addr_t)DataSegment.base,
(mps_addr_t) (DataSegment.base + SegmentLength) );
/* see doc of mps_fmt_scan_t for definition of scan_objs */
if(res != MPS_RES_OK)
exit( EXIT_FAILURE );
/* ... */
}
</pre>
<h4>Error Handling</h4>
<p><code><a href="#mps_root_create_fmt">mps_root_create_fmt</a></code> returns <code><a href="#MPS_RES_MEMORY">MPS_RES_MEMORY</a></code> when it fails to allocate memory for theinternal root structure; you need to deallocate or reclaim something to make enough space, or expandthe arena.</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_fmt_scan_t">mps_fmt_scan_t</a></code>,
<code><a href="#mps_rm_t">mps_rm_t</a></code>,
<code><a href="#mps_rank_t">mps_rank_t</a></code>,
<code><a href="#mps_root_t">mps_root_t</a></code>,
<code><a href="#mps_root_create">mps_root_create</a></code>,
<code><a
href="#mps_root_create_table">mps_root_create_table</a></code>,
<code><a href="#MPS_RM_PROT">MPS_RM_PROT</a></code>,
<code><a href="#MPS_RM_CONST">MPS_RM_CONST</a></code></p>
<h4>Notes</h4>
<p>This is like <code><a href="#mps_root_create_table">mps_root_create_table</a></code>, except you get to supply your own scanning function.This is like <code><a href="#mps_root_create">mps_root_create</a></code>, except the scanning function has a slightly different argument list(and the MPS knows where the root is).</p>
<h3>function <code><a id="mps_root_create_reg" name="mps_root_create_reg">mps_root_create_reg</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_root_create_reg">mps_root_create_reg</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_root_create_reg">mps_root_create_reg</a></code> registers a thread as a root.</p>
<h4>Associated Protocols</h4>
<p>Root.</p>
<h4>Syntax</h4>
<p><code>mps_res_t mps_root_create_reg(mps_root_t * root_o, mps_arena_t arena, mps_rank_t rank, mps_rm_t rm, mps_thr_t thread, mps_reg_scan_t scan, void *p, size_t s) </code></p>
<h4>Arguments</h4>
<p>root_o a pointer to a variable to store the new root structure</p>
<p>arena the arena</p>
<p>rank the rank of references in the root</p>
<p>rm the root mode</p>
<p>thread the thread to the registered as a root</p>
<p>scan the scanning function</p>
<p>p a value to be passed to the scanning function</p>
<p>s a value to be passed to the scanning function</p>
<h4>Returned Values</h4>
<p>If the return value is <code><a href="#MPS_RES_OK">MPS_RES_OK</a></code>, a new root structure in "*root_o".</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p><code><a href="#mps_root_create_reg">mps_root_create_reg</a></code>
declares the state of a thread as a root. The client provides a
scanning function that will be called and passed "p" and "s", whenever
the root needs to be scanned. See <code><a
href="#mps_reg_scan_t">mps_reg_scan_t</a></code> for details.</p>
<p>If the rank of the root is not <code><a href="#MPS_RANK_AMBIG">MPS_RANK_AMBIG</a></code>, the contents of the root have to be validwhenever a GC happens, i.e., they have to be references to actual objects or "NULL". If you're usingasynchronous GC, this could be right after the root is registered, so the root has to be valid whenit is registered. It's OK for a root to have entries which point to memory not managed by the MPS --they will simply be ignored.</p>
<h4>Example</h4>
<pre>
typedef struct {
mps_root_t mmRoot;
mps_thr_t thread;
/* ... */
} ThreadLocals;
void InitThread(ThreadLocals *thr)
{
/* This is a hack to find the bottom of the stack. */
void *stackBottom=&stackBottom;
mps_thread_reg(&amp;thr-&gt;thread, arena);
mps_root_create_reg(&amp;thr-&gt;mmRoot, arena, MPS_RANK_AMBIG, (mps_rm_t) 0,
thr-&gt;thread, mps_stack_scan_ambig, stackBottom, 0);
/* ... */
}
</pre>
<h4>Error Handling</h4>
<p><code><a href="#mps_root_create_reg">mps_root_create_reg</a></code> returns <code><a href="#MPS_RES_MEMORY">MPS_RES_MEMORY</a></code> when it fails to allocate memory for theinternal root structure; you need to deallocate or reclaim something to make enough space, or expandthe arena.</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_stack_scan_ambig">mps_stack_scan_ambig</a></code>,
<code><a href="#mps_reg_scan_t">mps_reg_scan_t</a></code></p>
<h4>Notes</h4>
<p>Only one suitable scanning function is supplied with the MPS, namely <code><a href="#mps_stack_scan_ambig">mps_stack_scan_ambig</a></code>.</p>
<h3>function <code><a id="mps_root_create_table" name="mps_root_create_table">mps_root_create_table</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_root_create_table">mps_root_create_table</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_root_create_table">mps_root_create_table</a></code> create s a root that is a vector of references.</p>
<h4>Associated Protocols</h4>
<p>Root.</p>
<h4>Syntax</h4>
<p><code>mps_res_t mps_root_create_table(mps_root_t *root_o, mps_arena_t arena, mps_rank_t rank, mps_rm_t rm, mps_addr_t *base, size_t size) </code></p>
<h4>Arguments</h4>
<p>root_o a pointer to a variable for storing the new root structure in</p>
<p>arena the arena</p>
<p>rank the rank of the references in this root</p>
<p>rm the root mode</p>
<p>base a pointer to the vector of references that is being registered</p>
<p>size the number of references in the vector being registered</p>
<h4>Returned Values</h4>
<p>If the return value is <code><a href="#MPS_RES_OK">MPS_RES_OK</a></code>, the new root in "*root_o".</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>This function declares a root that is a vector of references.</p>
<p>If the rank of the root is not <code><a href="#MPS_RANK_AMBIG">MPS_RANK_AMBIG</a></code>, the contents of the root have to be validwhenever a GC happens, i.e., they have to be references to actual objects or "NULL". If you're usingasynchronous GC, this could be right after the root is registered, so the root has to be valid whenit is registered. It's OK for a root to have entries which point to memory not managed by the MPS --they will simply be ignored.</p>
<h4>Example</h4>
<pre>
static mps_root_t mmRoot;
Object *Objects[rootCOUNT];
int main(void)
{
mps_res_t res;
/* ... */
res = mps_root_create_table(&amp;mmRoot, arena, MPS_RANK_EXACT, (mps_rm_t)0,
(mps_addr_t) &amp;Objects, rootCOUNT );
if(res != MPS_RES_OK)
exit(1);
/* ... */
}
</pre>
<h4>Error Handling</h4>
<p><code><a href="#mps_root_create_table">mps_root_create_table</a></code> returns <code><a href="#MPS_RES_MEMORY">MPS_RES_MEMORY</a></code> when it fails to allocate memory for theinternal root structure; you need to deallocate or reclaim something to make enough space, or expandthe arena.</p>
<h4>See Also</h4>
<p>
<code><a
href="#mps_root_create_table_masked">mps_root_create_table_masked</a></code>,
<code><a href="#MPS_RM_PROT">MPS_RM_PROT</a></code>,
<code><a href="#MPS_RM_CONST">MPS_RM_CONST</a></code></p>
<h3>function <code><a id="mps_root_create_table_masked" name="mps_root_create_table_masked">mps_root_create_table_masked</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_root_create_table_masked">mps_root_create_table_masked</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_root_create_table_masked">mps_root_create_table_masked</a></code> creates a root that is a vector of tagged values.</p>
<h4>Associated Protocols</h4>
<p>Root.</p>
<h4>Syntax</h4>
<p><code>mps_res_t mps_root_create_table_masked(mps_root_t *root_o, mps_arena_t arena, mps_rank_t rank, mps_rm_t rm, mps_addr_t *base, size_t size, mps_word_t mask); </code></p>
<h4>Arguments</h4>
<p>root_o a pointer to a variable for storing the new root structure in</p>
<p>arena the arena</p>
<p>rank the rank of the references in this root</p>
<p>rm the root mode</p>
<p>base a pointer to the vector of references that is being registered</p>
<p>
size the number of references in the vector being registered
<br />
mask any element that has any of the bits in mask set is ignored
</p>
<h4>Returned Values</h4>
<p>If the return value is <code><a href="#MPS_RES_OK">MPS_RES_OK</a></code>, the new root in "*root_o".</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p><code><a href="#mps_root_create_table_masked">mps_root_create_table_masked</a></code> creates a root that is a table of tagged values. The maskparameter indicates which bits of a pointer are tag bits. References are assumed to have a tag ofzero, values with other tags are ignored.</p>
<p>If the rank of the root is not <code><a href="#MPS_RANK_AMBIG">MPS_RANK_AMBIG</a></code>, the contents of the root have to be validwhenever a GC happens, i.e., they have to be references to actual objects or "NULL". If you're usingasynchronous GC, this could be right after the root is registered, so the root has to be valid whenit is registered. It's OK for a root to have entries which point to memory not managed by the MPS --they will simply be ignored.</p>
<h4>Example</h4>
<pre>
#define tagMASK 0x0003
static mps_root_t mmRoot;
Object *Objects[rootCOUNT];
int main(void)
{
mps_res_t res;
/* ... */
res = mps_root_create_table_masked(&amp;mmRoot, arena, MPS_RANK_EXACT, (mps_rm_t)0,
(mps_addr_t)&amp;Objects, rootCOUNT,
(mps_word_t)tagMASK);
if(res != MPS_RES_OK)
exit(1);
/* ... */
}
</pre>
<h4>Error Handling</h4>
<p><code><a href="#mps_root_create_table_masked">mps_root_create_table_masked</a></code> returns <code><a href="#MPS_RES_MEMORY">MPS_RES_MEMORY</a></code> when it fails to allocate memoryfor the internal root structure; you need to deallocate or reclaim something to make enough space,or expand the arena.</p>
<h4>See Also</h4>
<p>
<code><a
href="#mps_root_create_table">mps_root_create_table</a></code>,
<code><a href="#MPS_RM_PROT">MPS_RM_PROT</a></code>,
<code><a href="#MPS_RM_CONST">MPS_RM_CONST</a></code></p>
<h3>type <code><a id="mps_root_scan_t" name="mps_root_scan_t">mps_root_scan_t</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_root_scan_t">mps_root_scan_t</a></code></p>
<h4>Summary</h4>
<p>Type of root scanning functions for <code><a href="#mps_root_create">mps_root_create</a></code>.</p>
<h4>Associated Protocols</h4>
<p>Root.</p>
<h4>Syntax</h4>
<p><code>typedef mps_res_t (*mps_root_scan_t)(mps_ss_t scan_state, void * p, size_t s)</code></p>
<h4>Arguments</h4>
<p><code>scan_state</code> a scan state</p>
<p><code>p</code> an argument passed through from <code><a href="#mps_root_create">mps_root_create</a></code></p>
<p><code>s</code> an argument passed through from <code><a href="#mps_root_create">mps_root_create</a></code></p>
<h4>Returned Values</h4>
<p>A result code.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>This is the type of root scanning functions the client provides to<code><a href="#mps_root_create">mps_root_create</a></code>. The MPS will call these functions whenever the root needs to bescanned, with a scan state (of type <code><a href="#mps_ss_t">mps_ss_t</a></code> ), and the <code>p</code> and<code>s </code> values specified in the call to <code><a href="#mps_root_create">mps_root_create</a></code>. Apart from theargument list, the scanning function works like the format scan methods: it needs to indicate allreferences using <code><a href="#mps_fix">mps_fix</a></code> or <code>MPS_FIX*</code>.</p>
<h4>Example</h4>
<pre>
static StackFrame *stackBottom;
/* root scanner for an imaginary interpreter for a stack-oriented language */
static mps_res_t rootScanner(mps_ss_t ss, void * p, size_t s)
{
StackFrame *frame;
size_t i;
mps_res_t res;
UNUSED(p);
UNUSED(s);
for(frame = stackBottom; frame != NULL; frame = frame-&gt;next)
for(i = frame-&gt;size; i &gt; 0; --i) {
res = mps_fix(ss, &amp;frame-&gt;locals[i]);
if(res != MPS_RES_OK) return res;
}
return res;
}
</pre>
<h4>Error Handling</h4>
<p>If a fixing operation 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, itis better if it returns as soon as
possible. If the scanning is completed successfully, the
function should return <code><a
href="#MPS_RES_OK">MPS_RES_OK</a></code>.</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_root_create">mps_root_create</a></code>,
<code><a href="#mps_ss_t">mps_ss_t</a></code>,
<code><a href="#mps_fix">mps_fix</a></code>,
<code><a href="#MPS_SCAN_BEGIN">MPS_SCAN_BEGIN</a></code>,
<code><a href="#MPS_SCAN_END">MPS_SCAN_END</a></code>,
<code><a href="#MPS_FIX12">MPS_FIX12</a></code>,
<code><a href="#MPS_FIX1">MPS_FIX1</a></code>,
<code><a href="#MPS_FIX2">MPS_FIX2</a></code>,
<code><a href="#MPS_FIX_CALL">MPS_FIX_CALL</a></code>,
<code><a href="#mps_fmt_scan_t">mps_fmt_scan_t</a></code></p>
<h3>type <code><a id="mps_roots_stepper_t" name="mps_roots_stepper_t">mps_roots_stepper_t</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_roots_stepper_t">mps_roots_stepper_t</a></code></p>
<h4>Summary</h4>
<p>Type of the client-supplied root walker component.</p>
<h4>Associated Protocols</h4>
<p>None.</p>
<h4>Type</h4>
<p>
<code>typedef void (*mps_roots_stepper_t)( mps_addr_t *, mps_root_t, void *, size_t )</code>
</p>
<h4>Arguments</h4>
<p>The function pointed to by an object of type <code><a href="#mps_roots_stepper_t">mps_roots_stepper_t</a></code> takes the followingargument list:</p>
<p><code>(mps_addr_t *ref, mps_root_t root, void *p, size_t s)</code></p>
<p>ref is the address of a root which references an object in the arena. It's a pointer to aroot which points to "something" in the client heap. That "something" will be an object if the rootis an exact root. But it might be an interior pointer to an object if the root is an ambiguous root.</p>
<p>root is the MPS root object which contains ref.</p>
<p>p and s are two closure values which are copies of the corresponding values which the clientpassed into <code><a href="#mps_arena_roots_walk">mps_arena_roots_walk</a></code>.</p>
<h4>Returned Values</h4>
<p>he function pointed to by an object of type <code><a href="#mps_roots_stepper_t">mps_roots_stepper_t</a></code> returns no values.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>A pointer to a function is passed into the function <code><a href="#mps_arena_roots_walk">mps_arena_roots_walk</a></code>; the pointer hasthis type. The root walker arranges to apply this function to all objects which are directlyreferenced from the roots.</p>
<h4>Example</h4>
<p>&lt;example of how to use the symbol&gt;</p>
<h4>Error Handling</h4>
<h4>T</h4>
<p>he function pointed to by an object of type <code><a href="#mps_roots_stepper_t">mps_roots_stepper_t</a></code> has no way of signalling anerror to the caller.</p>
<h4>See Also</h4>
<p>
<code><a
href="#mps_arena_roots_arena_walk">mps_arena_roots_arena_walk</a></code></p>
<h4>Notes</h4>
<h3>type <code><a id="mps_sac_class_s" name="mps_sac_class_s">mps_sac_class_s</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_sac_class_s">mps_sac_class_s</a></code></p>
<h4>Summary</h4>
<p>A structure describing a size class to be passed as an argument to <code><a href="#mps_sac_create">mps_sac_create</a></code>.</p>
<h4>Associated Protocols</h4>
<p>Allocation cache</p>
<h4>Type</h4>
<pre>
typedef struct mps_sac_class_s {
size_t mps_block_size;
size_t mps_cached_count;
unsigned mps_frequency;
} mps_sac_class_s;
</pre>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p><code><a href="#mps_sac_class_s">mps_sac_class_s</a></code> is the element t ype of the array passed to<code><a href="#mps_sac_create">mps_sac_create</a></code> to describ e the size classes. Each element of this array describes oneclass by specifying <code>block_size</code>, the maximum size (in bytes) in this class;<code>cached_count </code> , the number of objects of this class to cache ; and<code>frequency </code> , a number that describes the frequency of requests (allocation anddeallocation combined ) in this class relative to all the other classes. The classes should be givenin the order of ascending size.</p>
<p><code>block_size</code> s have to be aligned to the pool alignment. All sizes must bedifferent, and the smallest size must be large enough to hold a <code>void *</code>.</p>
<p>
<code>cached_count</code>
is advice to the MPS on how many blocks to cache, not an absolutelimit. The cache policy tries to accommodate fluctuations in the population and minimize the cost ofresponding to client requests; the purpose of this parameter is to limit how much memory the clientis willing to set aside for this purpose. However, a
<code>cached_count</code>
of zero prevents anycaching of blocks falling into that class.
</p>
<p>The MPS automatically provides an "overlarge" class for arbitrarily large objects above thelargest class described. Allocations falling into the overlarge class are not cached.</p>
<h4>Example</h4>
<pre>
mps_sac_t sac;
mps_sac_class_s classes[3] = { {8, 38, 1}, {136, 19, 3}, {512, 4, 1} };
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>See Also</h4>
<p>
<code><a href="#mps_sac_create">mps_sac_create</a></code></p>
<h4>Notes</h4>
<p>Any blocks whose size falls between two classes are allocated from the larger class.</p>
<h3>function <code><a id="mps_sac_create" name="mps_sac_create">mps_sac_create</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_sac_create">mps_sac_create</a></code></p>
<h4>Summary</h4>
<p>This function creates a segregated allocation cache.</p>
<h4>Associated Protocols</h4>
<p>Allocation cache</p>
<h4>Type</h4>
<p><code>mps_res_t mps_sac_create(mps_sac_t *sac_o, mps_pool_t pool, size_t classes_count,mps_sac_class_s *classes);</code></p>
<h4>Arguments</h4>
<p>sac_o a pointer to a variable to hold the cache created</p>
<p>pool the pool the cache is attached to</p>
<p>classes_count the number of the size classes</p>
<p>classes pointer to the first element of an array describing the size classes</p>
<h4>Returned Values</h4>
<p>If the return value is <code><a href="#MPS_RES_OK">MPS_RES_OK</a></code>, a new cache in <code>*sac_o</code>.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>This function creates an allocation cache whose free-list is segregated into the given sizeclasses. 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 <code><a href="#mps_alloc">mps_alloc</a></code> and <code><a href="#mps_free">mps_free</a></code>.</p>
<p>The size classes are described by an array of element type <code><a href="#mps_sac_class_s">mps_sac_class_s</a></code>(q.v.). This array is used to initialize the cache, and is not needed after<code><a href="#mps_sac_create">mps_sac_create</a></code> returns. There might be a limit on how many classes can be described,but it will be no less than <code><a href="#MPS_SAC_CLASS_LIMIT">MPS_SAC_CLASS_LIMIT</a></code>. You must specify at least one class.The MPS automatically provides an "overlarge" class for arbitrarily large objects above the largestclass described. Allocations falling into the overlarge class are not cached.</p>
<h4>Example</h4>
<pre>
mps_sac_t sac;
mps_sac_class_s classes[3] = { {8, 38, 1}, {136, 19, 3}, {512, 4, 1} };
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>Error Handling</h4>
<p><code><a href="#mps_sac_create">mps_sac_create</a></code> returns <code><a href="#MPS_RES_MEMORY">MPS_RES_MEMORY</a></code> or<code><a href="#MPS_RES_COMMIT_LIMIT">MPS_RES_COMMIT_LIMIT</a></code> when it fails to allocate memory for the internal cache structure;see the documentation for those return codes for recovery options. It returns<code><a href="#MPS_RES_LIMIT">MPS_RES_LIMIT</a></code> if you ask for too many size classes; combine some small adjacentclasses. It returns <code><a href="#MPS_RES_PARAM">MPS_RES_PARAM</a></code> if the pool doesn't support segregated allocationcaches.</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_sac_class_s">mps_sac_class_s</a></code>,
<code><a href="#MPS_SAC_CLASS_LIMIT">MPS_SAC_CLASS_LIMIT</a></code>,
<code><a href="#mps_sac_destroy">mps_sac_destroy</a></code>,
<code><a href="#MPS_RES_MEMORY">MPS_RES_MEMORY</a></code>,
<code><a href="#MPS_RES_COMMIT_LIMIT">MPS_RES_COMMIT_LIMIT</a></code>,
<code><a href="#MPS_RES_LIMIT">MPS_RES_LIMIT</a></code>,
<code><a href="#MPS_RES_PARAM">MPS_RES_PARAM</a></code>,
<code><a href="#mps_sac_t">mps_sac_t</a></code></p>
<h4>Notes</h4>
<p>Too many classes will slow down allocation; too few classes waste more space in internalfragmentation. It is assumed that overlarge allocations are rare; otherwise, you would add anotherclass for them, or even create separate allocation caches or pools for them.</p>
<p>Some pools will work more efficiently with caches than others. In the future, the MPS mightoffer pools specially optimized for particular types of cache.</p>
<p>Segregated allocation caches work poorly with debug pool classes at the moment: the checkingonly happens when blocks are moved between the cache and the pool. This will be fixed, but the speedof allocation with a debug class will always be similar to <code><a href="#mps_alloc">mps_alloc</a></code>, rather than cached speed.</p>
<h3>function <code><a id="mps_sac_destroy" name="mps_sac_destroy">mps_sac_destroy</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_sac_destroy">mps_sac_destroy</a></code></p>
<h4>Summary</h4>
<p>This function destroys a segregated allocation cache.</p>
<h4>Associated Protocols</h4>
<p>Allocation cache</p>
<h4>Type</h4>
<p><code>void mps_sac_destroy(mps_sac_t);</code></p>
<h4>Arguments</h4>
<p>sac the segregated allocation cache</p>
<h4>Returned Values</h4>
<p>None.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>This function destroys a segregated allocation cache. All memory held in it is returned tothe associated pool.</p>
<h4>Example</h4>
<pre>
res = mps_sac_create(&amp;sac, pool, 3, classes);
if (res != MPS_RES_OK) {
printf("Failed to create the allocation cache!");
exit(1);
}
/* Use sac. */
mps_sac_destroy(sac);
mps_pool_destroy(pool);
</pre>
<h4>See Also</h4>
<p>
<code><a href="#mps_sac_create">mps_sac_create</a></code>,
<code><a href="#mps_sac_t">mps_sac_t</a></code></p>
<h4>Notes</h4>
<p>Destroying the cache might well cause the pool to return some memory to the arena, butthat's up to the pool's usual policy.</p>
<p>Destroying the cache has no effect on objects allocated through it.</p>
<h3>function <code><a id="mps_sac_flush" name="mps_sac_flush">mps_sac_flush</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_sac_flush">mps_sac_flush</a></code></p>
<h4>Summary</h4>
<p>This function flushes the segregated allocation cache given.</p>
<h4>Associated Protocols</h4>
<p>Allocation cache</p>
<h4>Type</h4>
<p><code>void mps_sac_flush(mps_sac_t sac);</code></p>
<h4>Arguments</h4>
<p>sac the segregated allocation cache</p>
<h4>Returned Values</h4>
<p>None.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>This function flushes the segregated allocation cache given, returning all memory held in itto the associated pool.</p>
<p>The client is responsible for synchronising the access to the cache, but the MPS willproperly synchronize with any other threads that might be accessing the same pool.</p>
<h4>Example</h4>
<pre>
mps_sac_t sac_small, sac_large;
res = mps_sac_create(&amp;sac_small, pool, 3, small_classes);
if (res != MPS_RES_OK) {
printf("Failed to create the small allocation cache!");
exit(1);
}
res = mps_sac_create(&amp;sac_large, pool, 3, large_classes);
if (res != MPS_RES_OK) {
printf("Failed to create the large allocation cache!");
exit(1);
}
/* Use sac_small. */
mps_sac_flush(sac_small);
/* Use sac_large. */
mps_sac_flush(sac_large);
/* Use sac_small. */
</pre>
<h4>See Also</h4>
<p>
<code><a href="#mps_sac_t">mps_sac_t</a></code></p>
<h4>Notes</h4>
<p>This is something that you'd typically do when you know you won't be using the cache for awhile, but want to hold on to the cache itself. Destroying a cache has the effect of flushing it,naturally.</p>
<p>Flushing the cache might well cause the pool to return some memory to the arena, but that'supto the pool's usual policy.</p>
<p>Note that the MPS might also decide to take memory from the cache without the clientrequesting a flush.</p>
<h3>type <code><a id="mps_sac_t" name="mps_sac_t">mps_sac_t</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_sac_t">mps_sac_t</a></code></p>
<h4>Summary</h4>
<p>Type of segregated allocation caches.</p>
<h4>Associated Protocols</h4>
<p>Allocation cache</p>
<h4>Type</h4>
<p><code>typedef struct mps_sac_s *mps_sac_t;</code></p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>A value of this type represents an allocation cache with segregated freelists. It is anopaque type.</p>
<h4>Example</h4>
<pre>
mps_sac_t sac;
mps_sac_class_s classes[3] = { {8, 38, 1}, {136, 19, 3}, {512, 4, 1} };
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>See Also</h4>
<p>
<code><a href="#mps_sac_create">mps_sac_create</a></code>,
<code><a href="#mps_sac_destroy">mps_sac_destroy</a></code>,
<code><a href="#MPS_SAC_ALLOC">MPS_SAC_ALLOC</a></code>,
<code><a href="#mps_sac_alloc">mps_sac_alloc</a></code>,
<code><a href="#MPS_SAC_FREE">MPS_SAC_FREE</a></code>,
<code><a href="#mps_sac_free">mps_sac_free</a></code>,
<code><a href="#mps_sac_flush">mps_sac_flush</a></code></p>
<h4>Notes</h4>
<p>None.</p>
<h3>function <code><a id="mps_stack_scan_ambig" name="mps_stack_scan_ambig">mps_stack_scan_ambig</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_stack_scan_ambig">mps_stack_scan_ambig</a></code></p>
<h4>Summary</h4>
<p>A scanning function for ambiguous scanning of thread states.</p>
<h4>Associated Protocols</h4>
<p>Root.</p>
<h4>Syntax</h4>
<p><code>mps_res_t mps_stack_scan_ambig(mps_ss_t scan_state, mps_thr_t thread, void *stack_bottom, size_t ignore) </code></p>
<h4>Arguments</h4>
<p>scan_state a scan state</p>
<p>thread the thread</p>
<p>stack_bottom a pointer to the bottom of the stack</p>
<p>ignore ignored</p>
<h4>Returned Values</h4>
<p>A result code.</p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>This is a root scanning function of type <code><a href="#mps_reg_scan_t">mps_reg_scan_t</a></code>. It will scan allinteger registers and everything on the stack of the thread given, and can therefore only be usedwith roots of rank <code><a href="#MPS_RANK_AMBIG">MPS_RANK_AMBIG</a></code>. It will only scan things at the given stack bottompointer or higher on the stack (that is, more recently added). References are assumed to berepresented as machine words, and are required to be 4-byte-aligned; unaligned values are ignored.</p>
<p>Clients don't call this function, it is used as an argument of <code><a href="#mps_root_create_reg">mps_root_create_reg</a></code>.</p>
<h4>Example</h4>
<pre>
typedef struct {
mps_root_t mmRoot;
mps_thr_t thread;
/* ... */
} ThreadLocals;
void InitThread(ThreadLocals *thr)
{
/* This is a hack to find the bottom of the stack. */
void *stackBottom=&stackBottom;
mps_thread_reg(&amp;thr-&gt;thread, arena);
mps_root_create_reg(&amp;thr-&gt;mmRoot, arena, MPS_RANK_AMBIG, (mps_rm_t)0,
thr-&gt;thread, mps_stack_scan_ambig, stackBottom, 0)
/* ... */
}
</pre>
<h4>See Also</h4>
<p>
<code><a href="#mps_reg_scan_t">mps_reg_scan_t</a></code>,
<code><a
href="#mps_root_create_reg">mps_root_create_reg</a></code></p>
<h4>Notes</h4>
<p>The MPS provides this function because it's hard to write (it's OS- andarchitecture-dependent and possibly compiler-dependent).</p>
<h3>function <code><a id="mps_telemetry_control" name="mps_telemetry_control">mps_telemetry_control</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_telemetry_control">mps_telemetry_control</a></code></p>
<h4>Summary</h4>
<p>This function is used to read and change the filters on the telemetry stream.</p>
<h4>Associated Protocols</h4>
<p>Telemetry.</p>
<h4>Syntax</h4>
<p><code>mps_word_t mps_telemetry_control(mps_word_t reset_mask, mps_word_t flip_mask);</code></p>
<h4>Arguments</h4>
<p>reset_mask is a bit mask indicating the bits that should be reset, regardless of previousvalue.</p>
<p>flip_mask is a bit mask indicating the bits whose value should be flipped after theresetting.</p>
<h4>Returned Values</h4>
<p>The function returns the previous value of the telemetry filter control.</p>
<h4>Description</h4>
<p>This function is used to read and change the filters on the telemetry stream. It isgenerally for use by developers.</p>
<p>The parameters reset_mask and flip_mask allow specifying any binary operation on the filtercontrol. To use this function for typical operations, the parameters should be set as follows:</p>
<p>Operation reset_mask flip_mask</p>
<p>set(M) M M</p>
<p>reset(M) M 0</p>
<p>flip(M) 0 M</p>
<p>read() 0 0</p>
<p>The significance of the bits is liable to change, but the current values (number the leastsignificant bit as zero) are:</p>
<p>0 -- per space or arena</p>
<p>1 -- per pool</p>
<p>2 -- per trace or scan</p>
<p>3 -- per page (segment)</p>
<p>4 -- per reference or fix</p>
<p>5 -- per allocation or object</p>
<p>6 -- user events (e.g., <code><a href="#mps_telemetry_intern">mps_telemetry_intern</a></code>)</p>
<h4>Example</h4>
<h4>See Also</h4>
<p>
<code><a
href="#mps_lib_telemetry_control">mps_lib_telemetry_control</a></code></p>
<h3>function <code><a id="mps_telemetry_flush" name="mps_telemetry_flush">mps_telemetry_flush</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_telemetry_flush">mps_telemetry_flush</a></code></p>
<h4>Summary</h4>
<p>This function is used to flush the internal event buffers.</p>
<h4>Associated Protocols</h4>
<p>Telemetry.</p>
<h4>Syntax</h4>
<p><code>void mps_telemetry_flush(void);</code></p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>This function is used to flush the internal event buffers into the event stream. Thisfunction also calls <code><a href="#mps_lib_io_flush">mps_lib_io_flush</a></code> on the event stream itself. This ensures that even the latestevents are now properly recorded, should the application terminate (uncontrollably as a result of abug, for example) or some interactive tool require access to the event data. You could even trycalling this from a debugger after a problem.</p>
<h4>Example</h4>
<p><code>mps_telemetry_flush();</code></p>
<h4>See Also</h4>
<p>
<code><a href="#mps_lib_io_flush">mps_lib_io_flush</a></code></p>
<h3>function <code><a id="mps_telemetry_intern" name="mps_telemetry_intern">mps_telemetry_intern</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_telemetry_intern">mps_telemetry_intern</a></code></p>
<h4>Summary</h4>
<p>This function registers a string with the MPS, and receives a unique identifier in return.This identifier is suitable for use with <code><a href="#mps_telemetry_label">mps_telemetry_label</a></code>.</p>
<h4>Associated Protocols</h4>
<p>Telemetry</p>
<h4>Type</h4>
<p><code>mps_word_t mps_telemetry_intern(char *)</code></p>
<h4>Arguments</h4>
<p>The function receives a name as a nul-terminated string in the usual C way. The string'slength should not exceed 256 characters, including nul terminating character. In appropriatevarieties this restriction is checked and will cause the MPS to issue an ASSERT. So don't do it.</p>
<h4>Returned Values</h4>
<p>The function returns a unique idenifier that may be used to represent the string in future.</p>
<h4>Description</h4>
<p>The intention of this function is to provide an immediate
identifier that can be used toconcisely represent a string for the
purposes of <code><a
href="#mps_telemetry_label">mps_telemetry_label</a></code>. Note that
the appropriatesettings must be made to the telemetry filter (via
<code><a
href="#mps_telemetry_control">mps_telemetry_control</a></code>) before
this function is invoked; the associate event is of the user kind.</p>
<h4>Error Handling</h4>
<p>The string's length should not exceed 256 characters, including nul terminating character.This will cause the MPS to issue an ASSERT in appropriate varieties.</p>
<h4>See Also</h4>
<p>
<code><a
href="#mps_telemetry_label">mps_telemetry_label</a></code></p>
<p>
<code><a
href="#mps_telemetry_control">mps_telemetry_control</a></code></p>
<h3>function <code><a id="mps_telemetry_label" name="mps_telemetry_label">mps_telemetry_label</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_telemetry_label">mps_telemetry_label</a></code></p>
<h4>Summary</h4>
<p>This function associates an identifier returned from <code><a href="#mps_telemetry_intern">mps_telemetry_intern</a></code>, and hence astring, with an address, in the telemetry stream.</p>
<h4>Associated Protocols</h4>
<p>telemetry</p>
<h4>Type</h4>
<p><code>void mps_telemetry_label(mps_addr_t, mps_word_t);</code></p>
<h4>Arguments</h4>
<p>The function receives an address and an identifier. The identifier should be one returned by <code><a href="#mps_telemetry_intern">mps_telemetry_intern</a></code> in the same session.</p>
<h4>Description</h4>
<p>This function is intended to associate the address with an identifier in the telemetrystream. Note that the user kind must be set in the telemetry filter.</p>
<h4>Example</h4>
<p>Typical uses include:</p>
<p>- Label pools with a human-meaningful name;</p>
<p>- Label allocated objects with their type or class.</p>
<h4>See Also</h4>
<p>
<code><a href="#mps_telemetry_intern">mps_telemetry_intern</a></code>,
<code><a
href="#mps_telemetry_control">mps_telemetry_control</a></code>,
<code><a href="#mps_thr_t">mps_thr_t</a></code></p>
<h3>type <code><a id="mps_thr_t" name="mps_thr_t">mps_thr_t</a></code></h3>
<h4>Name</h4>
<p><code><a href="#mps_thr_t">mps_thr_t</a></code></p>
<h4>Summary</h4>
<p><code><a href="#mps_thr_t">mps_thr_t</a></code> is the type of thread records registered with the MPS.</p>
<h4>Associated Protocols</h4>
<p>Threads.</p>
<h4>Type</h4>
<p><code>typedef mps_thr_s *mps_thr_t;</code></p>
<h4>Resources</h4>
<p>mps.h</p>
<h4>Description</h4>
<p>An object of the opaque type <code><a href="#mps_thr_t">mps_thr_t</a></code> is a thread registration. In a multi-threadedenvironment where incremental garbage collection is used, threads must be registered with the MPS sothat the MPS can examine their state.</p>
<p>An object of type <code><a href="#mps_thr_t">mps_thr_t</a></code> is obtained using the thread registration function <code><a href="#mps_thread_reg">mps_thread_reg</a></code>.</p>
<h4>Example</h4>
<pre>
mps_thr_t this_thread;
mps_res_t res;
res = mps_thread_reg(&amp;this_thread, space);
if(res != MPS_RES_OK) return res;
</pre>
<h4>See Also</h4>
<p>
<code><a href="#mps_reg_t">mps_reg_t</a></code>,
<code><a href="#mps_thread_reg">mps_thread_reg</a></code>,
<code><a href="#mps_thread_dereg">mps_thread_dereg</a></code>,
<code><a href="#mps_reg_scan_t">mps_reg_scan_t</a></code>,
<code><a href="#mps_root_create_reg">mps_root_create_reg</a></code>,
<code><a
href="#mps_stack_scan_ambig">mps_stack_scan_ambig</a></code></p>
<h2> <a id="section-4" name="section-4">4. Undocumented Symbols</a> </h2>
<p>The following MPS symbols are used or defined in MPS header files,
and intended for client use, but are not yet documented in this
reference manual.</p>
<pre>
mps_arena_t
mps_pool_t
mps_chain_t
mps_root_t
mps_ap_t
mps_ld_t
mps_ss_t
mps_alloc_pattern_t
mps_frame_t
mps_word_t
mps_shift_t
mps_rm_t
MPS_RES_OK
MPS_RES_FAIL
MPS_RES_RESOURCE
MPS_RES_UNIMPL
MPS_RES_IO
MPS_RES_COMMIT_LIMIT
mps_ap_s
mps_sac_freelist_block_s
mps_sac_s
mps_ld_s
mps_ss_s
mps_fmt_fixed_s
MPS_BEGIN
MPS_END
mps_arena_step
mps_arena_destroy
mps_arena_reserved
mps_arena_has_addr
mps_arena_extend
mps_arena_retract
mps_fmt_create_fixed
mps_fmt_destroy
mps_pool_create
mps_pool_create_v
mps_pool_destroy
mps_gen_param_s
mps_chain_create
mps_chain_destroy
mps_alloc_v
mps_ap_create
mps_ap_create_v
mps_ap_destroy
mps_reserve
mps_commit
mps_ap_fill
mps_ap_fill_with_reservoir_permit
mps_ap_trip
MPS_SAC_ALLOC
MPS_SAC_FREE
mps_reservoir_limit_set
mps_reservoir_limit
mps_reservoir_available
mps_reserve_with_reservoir_permit
MPS_RESERVE_BLOCK
MPS_RESERVE_WITH_RESERVOIRf_PERMIT_BLOCK
mps_root_destroy
mps_tramp_t
mps_tramp
mps_thread_reg
mps_thread_dereg
mps_ld_reset
mps_ld_add
mps_ld_merge
mps_ld_isstale
mps_collections
mps_definalize
mps_pool_check_free_space
mps_lib_get_EOF
mps_lib_stream_s
mps_lib_get_stderr
mps_lib_get_stdout
mps_lib_fputc
mps_lib_fputs
mps_lib_assert_fail
mps_clock_t
mps_clock
mps_class_amcz
mps_class_ams
mps_class_ams_debug
mps_class_awl
mps_class_lo
mps_mv_free_size
mps_mv_size
mps_class_mv
mps_class_mv_debug
mps_mvt_free_size
mps_mvt_size
mps_mvff_free_size
mps_mvff_size
mps_class_mvff_debug
mps_SEH_filter
mps_SEH_handler
mps_io_t
mps_io_create
mps_io_destroy
mps_io_write
mps_io_flush
MPS_PF_STRING
MPS_PF_ALIGN
MPS_ARCH_60
MPS_ARCH_I3
MPS_ARCH_I4
MPS_ARCH_M2
MPS_ARCH_M4
MPS_ARCH_PP
MPS_ARCH_S8
MPS_ARCH_S9
MPS_BUILD_AC
MPS_BUILD_CC
MPS_BUILD_GC
MPS_BUILD_LC
MPS_BUILD_MV
MPS_BUILD_MW
MPS_BUILD_SC
MPS_OS_FR
MPS_OS_I5
MPS_OS_IA
MPS_OS_LI
MPS_OS_O1
MPS_OS_S7
MPS_OS_SO
MPS_OS_SU
MPS_OS_W3
MPS_OS_XC
MPS_PF_FRI4GC
MPS_PF_I5M2CC
MPS_PF_IAM4CC
MPS_PF_LII4GC
MPS_PF_LIPPGC
MPS_PF_O1ALCC
MPS_PF_O1ALGC
MPS_PF_S760AC
MPS_PF_S760MW
MPS_PF_S7PPAC
MPS_PF_S7PPMW
MPS_PF_SOS8GC
MPS_PF_SOS9SC
MPS_PF_SUS8GC
MPS_PF_SUS8LC
MPS_PF_W3ALMV
MPS_PF_W3I3MV
MPS_PF_W3PPMV
MPS_PF_XCPPGC
</pre>
<h2><a id="section-A" name="section-A">A. References</a></h2>
<h2><a id="section-B" name="section-B">B. Document History</a></h2>
<table>
<tr valign="top">
<td>2002-05-27</td>
<td><a href="mailto:rb@ravenbrook.com">RB</a></td>
<td> Created from individual MPS reference pages, originally written and mainted in Lotus Notes by members of the Memory Management Group of Global Graphics (formerly Harlequin). I found many errors caused by the various conversions that this text has been through. There are probably many more. </td>
</tr>
<tr valign="top">
<td>2002-06-17</td>
<td><a href="mailto:rb@ravenbrook.com">RB</a></td>
<td> Removed Global Graphics specific entries for confidential sources not included in open source release. </td>
</tr>
<tr valign="top">
<td>2002-06-18</td>
<td><a href="mailto:nb@ravenbrook.com">NB</a></td>
<td> Added contents table to section 3.</td>
</tr>
<tr valign="top">
<td>2002-06-20</td>
<td><a href="mailto:nb@ravenbrook.com">NB</a></td>
<td>Quite a bit of proof-reading, to insert missing spaces. Also reformatted for easier editing, including the "See Also" sections.</td>
</tr>
<tr valign="top">
<td>2002-06-21</td>
<td><a href="mailto:nb@ravenbrook.com">NB</a></td>
<td>Removed obsolete symbols.</td>
</tr>
</table>
<h2><a id="section-C" name="section-C">C. Copyright and License</a></h2>
<p>This document is copyright &copy; 1997-2002 <a href="http://www.ravenbrook.com/">Ravenbrook Limited</a>. All rights reserved. This is an open source license. Contact Ravenbrook for commercial licensing options.</p>
<p>Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:</p>
<ol>
<li> Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. </li>
<li> 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. </li>
<li> 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. </li>
</ol>
<p><strong> 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. </strong></p>
<hr />
<div align="center">
<p><code>$Id$</code></p>
<p>
<a href="/">Ravenbrook</a> /
<a href="/project/">Projects</a> /
<a href="/project/mps/">Memory Pool System</a> /
<a href="/project/mps/master/">Master Product Sources</a> /
<a href="/project/mps/master/manual/">Product Manuals</a>
</p>
</div>
</body>
</html>