mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-03-26 16:51:46 -07:00
Complete the conversion of the mps reference manual to restructured text, creating topic and pool pages as needed.
Copied from Perforce Change: 179839 ServerID: perforce.ravenbrook.com
This commit is contained in:
parent
1231d6982f
commit
108e18ad35
18 changed files with 550 additions and 15 deletions
|
|
@ -35,6 +35,10 @@ Glossary
|
|||
|
||||
??
|
||||
|
||||
ambiguous
|
||||
|
||||
??
|
||||
|
||||
arena
|
||||
|
||||
??
|
||||
|
|
@ -43,10 +47,22 @@ Glossary
|
|||
|
||||
??
|
||||
|
||||
assert
|
||||
|
||||
??
|
||||
|
||||
asynchronous
|
||||
|
||||
??
|
||||
|
||||
automatic
|
||||
|
||||
??
|
||||
|
||||
bitmask
|
||||
|
||||
??
|
||||
|
||||
black
|
||||
|
||||
??
|
||||
|
|
@ -83,6 +99,10 @@ Glossary
|
|||
|
||||
??
|
||||
|
||||
condemned
|
||||
|
||||
??
|
||||
|
||||
constant root
|
||||
|
||||
??
|
||||
|
|
@ -99,6 +119,10 @@ Glossary
|
|||
|
||||
??
|
||||
|
||||
debugging pool
|
||||
|
||||
??
|
||||
|
||||
dead
|
||||
|
||||
??
|
||||
|
|
@ -107,6 +131,14 @@ Glossary
|
|||
|
||||
??
|
||||
|
||||
exact
|
||||
|
||||
??
|
||||
|
||||
fencepost
|
||||
|
||||
??
|
||||
|
||||
finalization
|
||||
|
||||
??
|
||||
|
|
@ -115,6 +147,10 @@ Glossary
|
|||
|
||||
??
|
||||
|
||||
fix
|
||||
|
||||
??
|
||||
|
||||
format method
|
||||
|
||||
??
|
||||
|
|
@ -143,6 +179,10 @@ Glossary
|
|||
|
||||
??
|
||||
|
||||
free list
|
||||
|
||||
??
|
||||
|
||||
garbage collection
|
||||
|
||||
??
|
||||
|
|
@ -155,6 +195,14 @@ Glossary
|
|||
|
||||
??
|
||||
|
||||
incremental
|
||||
|
||||
??
|
||||
|
||||
in/out parameter
|
||||
|
||||
??
|
||||
|
||||
is-forwarded method
|
||||
|
||||
??
|
||||
|
|
@ -179,6 +227,14 @@ Glossary
|
|||
|
||||
??
|
||||
|
||||
message queue
|
||||
|
||||
??
|
||||
|
||||
message type
|
||||
|
||||
??
|
||||
|
||||
moving
|
||||
|
||||
??
|
||||
|
|
@ -199,6 +255,10 @@ Glossary
|
|||
|
||||
??
|
||||
|
||||
out parameter
|
||||
|
||||
??
|
||||
|
||||
padding method
|
||||
|
||||
??
|
||||
|
|
@ -314,10 +374,38 @@ Glossary
|
|||
|
||||
??
|
||||
|
||||
stepper function
|
||||
|
||||
??
|
||||
|
||||
table root
|
||||
|
||||
??
|
||||
|
||||
tag
|
||||
|
||||
??
|
||||
|
||||
tagged value
|
||||
|
||||
??
|
||||
|
||||
telemetry filter
|
||||
|
||||
??
|
||||
|
||||
telemetry label
|
||||
|
||||
??
|
||||
|
||||
telemetry stream
|
||||
|
||||
??
|
||||
|
||||
thread
|
||||
|
||||
??
|
||||
|
||||
trace
|
||||
|
||||
??
|
||||
|
|
@ -334,6 +422,10 @@ Glossary
|
|||
|
||||
??
|
||||
|
||||
weak
|
||||
|
||||
??
|
||||
|
||||
white
|
||||
|
||||
??
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ Pool reference
|
|||
|
||||
pool-amc
|
||||
pool-amcz
|
||||
pool-ams
|
||||
pool-lo
|
||||
pool-mvff
|
||||
pool-mvt
|
||||
pool-snc
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
.. _pool-amc:
|
||||
|
||||
=============================
|
||||
Automatic Mostly-Copying pool
|
||||
=============================
|
||||
===================================
|
||||
AMC (Automatic Mostly-Copying) pool
|
||||
===================================
|
||||
|
||||
|
||||
An AMC pool is both scannable and collectable. Objects may contain exact references to other objects that will preserve such other objects. Objects may be reclaimed if they are not reachable from a root. Objects may move during collection, unless reachable via a (direct) ambiguous reference. 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.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
.. _pool-amcz:
|
||||
|
||||
=========
|
||||
AMCZ pool
|
||||
=========
|
||||
=========================================
|
||||
AMCZ (Automatic Mostly-Copying Z???) pool
|
||||
=========================================
|
||||
|
|
|
|||
6
mps/manual/source/pool/pool-ams.rst
Normal file
6
mps/manual/source/pool/pool-ams.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
.. _pool-ams:
|
||||
|
||||
===================================
|
||||
AMS (Automatic Mark and Sweep) pool
|
||||
===================================
|
||||
|
||||
5
mps/manual/source/pool/pool-lo.rst
Normal file
5
mps/manual/source/pool/pool-lo.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
.. _pool-lo:
|
||||
|
||||
===================
|
||||
LO (Leaf Only) pool
|
||||
===================
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
.. _pool-mvff:
|
||||
|
||||
===================================
|
||||
Manual Variable-size First Fit pool
|
||||
===================================
|
||||
==========================================
|
||||
MVFF (Manual Variable-size First Fit) pool
|
||||
==========================================
|
||||
|
||||
|
||||
Buffered allocation (:c:func:`mps_reserve` and :c:func:`mps_commit`) is also supported, but in that case, the policy is rather different: buffers are filled worst-fit, and allocation is always upwards from the base. 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 unbuffered allocation can be used at the same time, but in that case, the first allocation point must be created before any call to :c:func:`mps_alloc`.
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
.. _pool-mvt:
|
||||
|
||||
======================================
|
||||
Manual Variable-size Temporal-fit pool
|
||||
======================================
|
||||
============================================
|
||||
MVT (Manual Variable-size Temporal-fit) pool
|
||||
============================================
|
||||
|
||||
The MVT pool class manually manages variable-sized, unformatted objects. The MVT pool uses an allocation policy termed "temporal fit". Temporal fit attempts to place consecutive allocations next to each other. It relies on delaying reuse as long as possible to permit freed blocks to coalesce, thus maximizing the number of consecutive allocations that can be co-located. Temporal fit permits a very fast allocator and a deallocator competitive in speed with all other known policies.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
.. _pool-snc:
|
||||
|
||||
===================
|
||||
Stack No Check pool
|
||||
===================
|
||||
=========================
|
||||
SNC (Stack No Check) pool
|
||||
=========================
|
||||
|
||||
|
||||
An SNC pool is scannable, in that objects may contain references to objects in other pools that will keep those objects alive (depending on rank). In this sense, an SNC pool is a de-facto root.
|
||||
|
|
|
|||
|
|
@ -108,3 +108,115 @@ What does this mean? (from mps_sac_alloc):
|
|||
|
||||
MPS_SAC_FREE_FAST(sac, p, FooSIZE);
|
||||
</pre>
|
||||
|
||||
|
||||
|
||||
<h4>Example</h4>
|
||||
|
||||
<pre>
|
||||
mps_sac_t sac;
|
||||
mps_sac_class_s classes[3] = { {8, 38, 1}, {136, 19, 3}, {512, 4, 1} };
|
||||
|
||||
res = mps_sac_create(&sac, pool, 3, classes);
|
||||
if (res != MPS_RES_OK) {
|
||||
printf("Failed to create the allocation cache!");
|
||||
exit(1);
|
||||
}
|
||||
</pre>
|
||||
|
||||
|
||||
|
||||
|
||||
<h4>Example</h4>
|
||||
|
||||
<pre>
|
||||
mps_sac_t sac;
|
||||
mps_sac_class_s classes[3] = { {8, 38, 1}, {136, 19, 3}, {512, 4, 1} };
|
||||
|
||||
res = mps_sac_create(&sac, pool, 3, classes);
|
||||
if (res != MPS_RES_OK) {
|
||||
printf("Failed to create the allocation cache!");
|
||||
exit(1);
|
||||
}
|
||||
</pre>
|
||||
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
Some pools will work more efficiently with segregated
|
||||
allocation caches than others. [WHICH?] In the future, the MPS might
|
||||
offer pools specially optimized for particular types of cache. [WHEN?]
|
||||
|
||||
|
||||
Segregated allocation caches work poorly with debugging pool
|
||||
classes: the debugging checks only happen when blocks are
|
||||
moved between the cache and the pool. This will be fixed [WHEN?], but
|
||||
the speed of allocation with a debug class will always be
|
||||
similar to :c:func:`mps_alloc`, rather than cached speed.
|
||||
|
||||
|
||||
|
||||
|
||||
<h4>Example</h4>
|
||||
|
||||
<pre>
|
||||
res = mps_sac_create(&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>Example</h4>
|
||||
|
||||
<pre>
|
||||
mps_sac_t sac_small, sac_large;
|
||||
|
||||
res = mps_sac_create(&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(&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>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(&sac, pool, 3, classes);
|
||||
if (res != MPS_RES_OK) {
|
||||
printf("Failed to create the allocation cache!");
|
||||
exit(1);
|
||||
}
|
||||
</pre>
|
||||
|
||||
|
|
|
|||
8
mps/manual/source/topic/collection.rst
Normal file
8
mps/manual/source/topic/collection.rst
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
.. _topic-collection:
|
||||
|
||||
==================
|
||||
Garbage collection
|
||||
==================
|
||||
|
||||
|
||||
|
||||
18
mps/manual/source/topic/debugging.rst
Normal file
18
mps/manual/source/topic/debugging.rst
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
.. _topic-debugging:
|
||||
|
||||
===============
|
||||
Debugging pools
|
||||
===============
|
||||
|
||||
|
||||
<h4>Example</h4>
|
||||
|
||||
<pre>
|
||||
static mps_pool_debug_option_s debugOptions = { (void *)"postpost", 8 };
|
||||
if(mps_pool_create(&pool, arena, mps_class_ams_debug(),
|
||||
&debugOptions, 8192, 135, 8)
|
||||
!= MPS_RES_OK) {
|
||||
printf("Error creating pool!"); exit(2);
|
||||
}
|
||||
</pre>
|
||||
|
||||
|
|
@ -34,3 +34,21 @@ Error handing
|
|||
|
||||
}
|
||||
</pre>
|
||||
|
||||
|
||||
|
||||
|
||||
<h4>Example</h4>
|
||||
|
||||
<pre>
|
||||
mps_addr_t p;
|
||||
mps_res_t res;
|
||||
|
||||
res = mps_alloc(&p, pool, sizeof(struct spong));
|
||||
if(res != MPS_RES_OK) {
|
||||
handle_memory_error(res);
|
||||
abort();
|
||||
}
|
||||
</pre>
|
||||
|
||||
For more examples, s ee doc.mps.ref-man.if-conv.
|
||||
|
|
|
|||
|
|
@ -19,3 +19,21 @@ Note that there is no guarantee that finalization will be prompt.
|
|||
Note that there will be no attempt to finalize objects in the context of :c:func:`mps_arena_destroy` or :c:func:`mps_pool_destroy`. :c:func:`mps_pool_destroy` should therefore not be invoked on pools containing objects registered for finalization.
|
||||
|
||||
Not all pool classes support finalization of objects. In general only pools that manage objects whose liveness is determined by garbage collection will support finalization of objects. For more information, see the Pool Class Catalog.
|
||||
|
||||
|
||||
|
||||
<h4>Example</h4>
|
||||
|
||||
<pre>
|
||||
{
|
||||
mps_message_type_t type;
|
||||
|
||||
if(mps_message_queue_type(&type, arena)) {
|
||||
if(type == mps_message_type_finalization()) {
|
||||
process_finalization_message_from_queue();
|
||||
} else {
|
||||
unknown_message_type();
|
||||
}
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ Topic reference
|
|||
|
||||
arena
|
||||
allocation
|
||||
collection
|
||||
error
|
||||
format
|
||||
scanning
|
||||
|
|
@ -20,3 +21,5 @@ Topic reference
|
|||
platform
|
||||
telemetry
|
||||
message
|
||||
debugging
|
||||
|
||||
|
|
|
|||
|
|
@ -18,3 +18,33 @@ Messages
|
|||
printf("Collection started at %ul.\n", (unsigned long)posted_at);
|
||||
}
|
||||
</pre>
|
||||
|
||||
|
||||
|
||||
<h4>Example</h4>
|
||||
|
||||
<pre>
|
||||
{
|
||||
mps_message_t message;
|
||||
if(mps_message_get(&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>
|
||||
|
||||
|
||||
|
||||
<pre>
|
||||
{
|
||||
mps_message_t message;
|
||||
if(mps_message_get(&message, arena, mps_message_type_gc_start())) {
|
||||
printf("Collection started; reason: %s\n",
|
||||
mps_message_gc_start_why(arena, message));
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
|
|
|
|||
|
|
@ -25,3 +25,220 @@ unprotect the relevant pages.</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>
|
||||
|
||||
|
||||
|
||||
<h4>Example</h4>
|
||||
|
||||
<pre>
|
||||
static mps_root_t mmRoot;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
mps_res_t res;
|
||||
|
||||
/* ... */
|
||||
|
||||
res = mps_root_create(&mmRoot, arena, MPS_RANK_EXACT, (mps_rm_t)0,
|
||||
&rootScanner, NULL, 0);
|
||||
/* see doc of mps_root_scan_t for definition of rootScanner */
|
||||
if(res != MPS_RES_OK)
|
||||
exit(1);
|
||||
|
||||
/* ... */
|
||||
}
|
||||
</pre>
|
||||
|
||||
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
Unless the rank of the root is not :c:macro:`MPS_RANK_AMBIG`,
|
||||
the contents of the root have to be valid whenever a
|
||||
:term:`garbage collection` happens. That is, all the
|
||||
references fixed by the root scanning function have to be
|
||||
references to actual objects or null pointers. If you're using
|
||||
:term:`asynchronous` garbage collection, this could be as soon
|
||||
as the root is registered, so the root has to be valid when it
|
||||
is registered. As with an ordinary :term:`scan method`, a root
|
||||
scanning function is allowed to fix references which point to
|
||||
memory not managed by the MPS. These references will be
|
||||
ignored.
|
||||
|
||||
|
||||
|
||||
|
||||
<h4>Example</h4>
|
||||
|
||||
<pre>
|
||||
static mps_root_t mmRoot;
|
||||
SegmentDescriptor DataSegment;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
mps_res_t res;
|
||||
|
||||
/* ... */
|
||||
|
||||
res = mps_root_create_fmt(&mmRoot, arena, MPS_RANK_EXACT, (mps_rm_t)0,
|
||||
&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>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(&thr->thread, arena);
|
||||
mps_root_create_reg(&thr->mmRoot, arena, MPS_RANK_AMBIG, (mps_rm_t) 0,
|
||||
thr->thread, mps_stack_scan_ambig, stackBottom, 0);
|
||||
|
||||
/* ... */
|
||||
|
||||
}
|
||||
</pre>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h4>Example</h4>
|
||||
|
||||
<pre>
|
||||
static mps_root_t mmRoot;
|
||||
Object *Objects[rootCOUNT];
|
||||
|
||||
int main(void)
|
||||
{
|
||||
mps_res_t res;
|
||||
|
||||
/* ... */
|
||||
|
||||
res = mps_root_create_table(&mmRoot, arena, MPS_RANK_EXACT, (mps_rm_t)0,
|
||||
(mps_addr_t) &Objects, rootCOUNT );
|
||||
|
||||
if(res != MPS_RES_OK)
|
||||
exit(1);
|
||||
|
||||
/* ... */
|
||||
}
|
||||
</pre>
|
||||
|
||||
|
||||
|
||||
|
||||
<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(&mmRoot, arena, MPS_RANK_EXACT, (mps_rm_t)0,
|
||||
(mps_addr_t)&Objects, rootCOUNT,
|
||||
(mps_word_t)tagMASK);
|
||||
if(res != MPS_RES_OK)
|
||||
exit(1);
|
||||
|
||||
/* ... */
|
||||
}
|
||||
</pre>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<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->next)
|
||||
for(i = frame->size; i > 0; --i) {
|
||||
res = mps_fix(ss, &frame->locals[i]);
|
||||
if(res != MPS_RES_OK) return res;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
</pre>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<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(&thr->thread, arena);
|
||||
mps_root_create_reg(&thr->mmRoot, arena, MPS_RANK_AMBIG, (mps_rm_t)0,
|
||||
thr->thread, mps_stack_scan_ambig, stackBottom, 0)
|
||||
|
||||
/* ... */
|
||||
}
|
||||
</pre>
|
||||
|
||||
|
||||
|
||||
<h4>Example</h4>
|
||||
|
||||
<pre>
|
||||
mps_thr_t this_thread;
|
||||
mps_res_t res;
|
||||
|
||||
res = mps_thread_reg(&this_thread, space);
|
||||
if(res != MPS_RES_OK) return res;
|
||||
</pre>
|
||||
|
|
|
|||
|
|
@ -3,3 +3,9 @@
|
|||
=========
|
||||
Telemetry
|
||||
=========
|
||||
|
||||
Typical uses of telemtry labels include:
|
||||
|
||||
- Label pools with a human-meaningful name;
|
||||
|
||||
- Label allocated objects with their type or class.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue