Complete more tasks from discussion with rb yesterday.

Copied from Perforce
 Change: 179931
 ServerID: perforce.ravenbrook.com
This commit is contained in:
Gareth Rees 2012-10-18 09:26:59 +01:00
parent 42876e24c7
commit b863290424
21 changed files with 436 additions and 404 deletions

View file

@ -190,7 +190,7 @@ Memory Management Glossary: A
allocate
.. aka:: *cons (2)*.
.. aka:: *cons*.
*Allocation* is the process of assigning resources. When
requested to by the program, an application :term:`memory

View file

@ -82,7 +82,7 @@ Memory Management Glossary: G
garbage collector
.. aka:: *collector (1)*.
.. aka:: *collector*.
A (garbage) collector is (an implementation of) a
:term:`garbage collection` algorithm.

View file

@ -14,7 +14,7 @@ Memory Management Glossary: M
main memory
.. aka:: *memory (3)*, *primary storage*.
.. aka:: *memory*, *primary storage*.
The *main memory* (or *primary storage*) of a computer is
:term:`memory (1)` that is wired directly to the processor,
@ -234,7 +234,7 @@ Memory Management Glossary: M
memory (1)
.. aka:: *storage*, *store (2)*.
.. aka:: *storage*, *store*.
*memory* or *storage* (or *store*) is where data and
instructions are stored. For example, :term:`caches (1)

View file

@ -268,7 +268,7 @@ Memory Management Glossary: P
physical memory (1)
.. aka:: *real memory (2)*.
.. aka:: *real memory*.
Physical memory is :term:`memory (1)` that is wired to
directly to the processor, addressable by :term:`physical

View file

@ -527,7 +527,9 @@ Memory Management Glossary: R
A value of type :c:type:`mps_rm_t` describing whether a
:term:`root` is :term:`constant <constant root>`,
:term:`protectable <protectable root>`, or both.
:term:`protectable <protectable root>`, or both. The root
mode tells the MPS whether it may place a :term:`barrier`
on the root.
root set
@ -535,5 +537,3 @@ Memory Management Glossary: R
the :term:`mutator` declares to the :term:`collector (2)`.
.. seealso:: :term:`garbage collection`.

View file

@ -121,7 +121,7 @@ Memory Management Glossary: T
terabyte
.. aka:: *TB (1)*.
.. aka:: *TB*.
A terabyte is 1024 :term:`gigabytes <gigabyte>`, or
1099511627776 :term:`bytes (1) <byte (1)>`.
@ -210,7 +210,7 @@ Memory Management Glossary: T
translation buffer
translation lookaside buffer
.. aka:: , *address translation cache*, *ATC*, *TB (2)*.
.. aka:: , *address translation cache*, *ATC*, *TB*.
The *translation lookaside buffer* or *address translation
cache* is small piece of associative :term:`memory (1)` within

View file

@ -69,7 +69,7 @@ Memory Management Glossary: U
unmapped
.. aka:: *free (4)*.
.. aka:: *free*.
A range of :term:`virtual addresses <virtual address>` is said
to be *unmapped* (*free* on Windows) if there is no

View file

@ -115,7 +115,7 @@ Memory Management Glossary: V
virtual memory
.. aka:: *VM (1)*.
.. aka:: *VM*.
In a *virtual memory* (*VM*) system, the program code deals
with :term:`virtual addresses <virtual address>`. Upon use,

View file

@ -761,8 +761,9 @@ that:
2. each reference keeps the target of the reference alive (unlike
:term:`weak references <weak reference (1)>`).
The fourth argument (here ``0``) is the :term:`root mode`: see
:ref:`topic-root`.
The fourth argument is the :term:`root mode`, which tells the MPS
whether it is allowed to place a :term:`barrier` on the root. The
root mode ``0`` means that it is not allowed.
The sixth and seventh arguments (here ``NULL`` and ``0``) are passed
to the root scanning function where they are received as the

View file

@ -1,12 +1,12 @@
TODO
TODO, QUERIES AND SUGGESTIONS
2. Create new types of objects for pools and topics.
2. Create new types of Sphinx objects for pools and topics.
3. Glossary entries need permalinks. See
3. Glossary entries need permalink markers. See
<https://bitbucket.org/birkenfeld/sphinx/issue/996/expose-glossary-entry-link-on-hover>
5. Fix the general index so that (1) aren't interpreted as
subentries.
subentries?
7. Re-do the diagrams in vector form and using the colour palette.
@ -19,49 +19,7 @@ TODO
11. Support MMREF-style anchors to the glossary (#garbage.collection
instead of #garbage-collection).
12. Superscripts in aka sections.
QUERIES AND SUGGESTIONS
6. The location dependency functions all take an arena as an
argument. What is the role of this argument?
ANSWER: if you have multiple arenas, you are going to have to have
an ld_t for each arena, and add each address you are interested in
for each arena. (If you happen to know which arena it's in, you
can just specify it for that arena.) So for isstale, it better be
the same arena as add.
7. What is the role of the third (addr) argument to mps_ld_isstale?
LDIsStale says "UNUSED(addr);" so maybe it is unused.
ANSWER: in theory it's the address you want to check, but in the
implementation it tells you for all addresses. The LD functions
have an intention that is not quite the same as the design
documentation. (But what, asks RB, is the point of ld_add?)
Perhaps in the case of isstale it's "a piece of information that
might be useful for debugging".
8. Is the material in the pool class comparison table at all accurate?
ANSWER: It will be better to have a flowchart approach rather than
a table of properties.
10. How does fixing interact with tagged references? Do I need to
remove the tag before fixing a reference? Do I need to restore the
tag afterwards? I thought that both would be necessary but the
critical path documentation has an example from OpenDylan with
tagged references that does neither:
<https://info.ravenbrook.com/project/mps/master/design/critical-path.txt>
ANSWER: we'll document that all references need to be
decrypted/de-tagged. There ought to be some slack in practice but
it needs thought. Make a job.
ACTION: made <https://info.ravenbrook.com/project/mps/issue/job003317/>
14. I need to document the values in mps_gen_param_s. I believe they
26. I need to document the values in mps_gen_param_s. I believe they
are the capacity (size of the generation in kilobytes) and the
mortality (the proportion of objects in this generation that are
expected to die in a collection). But what do they mean to the
@ -72,7 +30,7 @@ QUERIES AND SUGGESTIONS
document about this based on the Lisp Machine:
analysis.strategy.lisp-machine or something.
15. Wouldn't it make mps_amc_apply easier to document if there were a
27. Wouldn't it make mps_amc_apply easier to document if there were a
typedef for the stepper function type, something like this?
typedef void (*mps_amc_apply_stepper_t)(mps_addr_t object, void *p, size_t s)
@ -80,16 +38,10 @@ QUERIES AND SUGGESTIONS
ANSWER: Richard says I can make this change since it's
backwards-compatible.
19. What is a root mode and how do I explain it?
ANSWER: currently a root mode has no effect. It tells the MPS
whether it's OK for the MPS to put a barrier on the
root. Recommend pass zero. For future expansion.
20. You create a marker on the stack and pass it to
mps_root_create_reg to tell it where the bottom of the stack
is. Fine. But then you are supposed to call your program via
mps_tramp. If the MPS is trampoling your whole program, why does
32. You create a marker on the stack and pass it to
mps_root_create_reg to tell it where the bottom of the stack is.
Fine. But then you are supposed to call your program via
mps_tramp. If the MPS is trampolining your whole program, why does
the MPS need your help to work out where the stack is? It could
work it out for itself surely?
@ -101,31 +53,17 @@ QUERIES AND SUGGESTIONS
"mps_tramp needs to wrap any code that might handle references
into a pool class that requires it." [All the ones with A.]
21. Status. At what point will the work be "good enough" to merge back
33. Status. At what point will the work be "good enough" to merge back
to the master sources?
24. The discussion in the Scheme example about mps_reserve suggests
that mps_alloc doesn't require aligned sizes. Is that right? Needs
to be added to mps_alloc reference if so.
37. Some of the Scheme objects could be moved to a leaf-only pool
(e.g. AMCZ).
ANSWER: in fact there's no rule about this. Depends on the pool
class. "It doesn't unless the pool class says it does".
25. Some of the Scheme objects could be moved to a leaf-only pool.
26. Document about interface conventions and interface policies. What
38. Document about interface conventions and interface policies. What
do we guarantee about support for the external symbols?
27. We don't support scanning the stack/registers except via
mps_stack_scan_ambig? Document this?
ANSWER: this is the only one we support at the moment.
30. Move symbol references for the pool classes to the corresponding
pool document.
TODO DONE
DONE, ANSWERED
1. Create a new domain
<http://sphinx.pocoo.org/ext/appapi.html#sphinx.domains.Domain>
@ -136,10 +74,9 @@ TODO DONE
10. Pluralize "Topic" to "Topics" and so on.
12. Superscripts in aka sections.
ANSWERED QUERIES
1. Does the object format description (mps_fmt_A_s etc) have to be
13. Does the object format description (mps_fmt_A_s etc) have to be
static as in the Scheme example? Or is it OK to throw it away
after calling mps_fmt_create?
@ -152,7 +89,7 @@ ANSWERED QUERIES
so it is OK for the client program to put these structures on the
stack otherwise dispose of them.
2. What is the difference, if any, between mps_word_t and MPS_T_WORD?
14. What is the difference, if any, between mps_word_t and MPS_T_WORD?
ANSWER: MPS_T_WORD comes from mpstd.h which contains no C code
(only macro definitions). It used to be the case that mpstd.h was
@ -163,7 +100,7 @@ ANSWERED QUERIES
ACTION: made <https://info.ravenbrook.com/project/mps/issue/job003315/>
3. How can I explain why the Scheme example uses sizeof(mps_word_t)
15. How can I explain why the Scheme example uses sizeof(mps_word_t)
as its alignment? Why not MPS_PF_ALIGN (or are client programs not
supposed to look at mpstd.h)? Why not something of its own
manufacture, like sizeof(union {long, size_t, void*})?
@ -172,12 +109,12 @@ ANSWERED QUERIES
ACTION: made <https://info.ravenbrook.com/project/mps/issue/job003316/>
4. Why does the Scheme example have a copy method in its object
16. Why does the Scheme example have a copy method in its object
format when the reference manual says it's obsolete?
ANSWER: It wasn't obsolete when it was written. I removed it.
5. What is the difference between the "event stream" and the
17. What is the difference between the "event stream" and the
"telemetry stream"? Are these names for the same thing? Or is
there a distinction (for example, "event stream" refers to the
internal, unfiltered, stream of events and "telemetry stream"
@ -186,7 +123,31 @@ ANSWERED QUERIES
ANSWER: the event stream is the implementation of the telemetry
stream, so the user doc can refer to "telemetry stream".
9. This code seems a bit confused about what to do:
18. The location dependency functions all take an arena as an
argument. What is the role of this argument?
ANSWER: if you have multiple arenas, you are going to have to have
an ld_t for each arena, and add each address you are interested in
for each arena. (If you happen to know which arena it's in, you
can just specify it for that arena.) So for isstale, it better be
the same arena as add.
19. What is the role of the third (addr) argument to mps_ld_isstale?
LDIsStale says "UNUSED(addr);" so maybe it is unused.
ANSWER: in theory it's the address you want to check, but in the
implementation it tells you for all addresses. The LD functions
have an intention that is not quite the same as the design
documentation. (But what, asks RB, is the point of ld_add?)
Perhaps in the case of isstale it's "a piece of information that
might be useful for debugging".
20. Is the material in the pool class comparison table at all accurate?
ANSWER: It will be better to have a flowchart approach rather than
a table of properties.
21. This code seems a bit confused about what to do:
assert(0);
fprintf(stderr, "Unexpected object on the heap\n");
@ -198,7 +159,20 @@ ANSWERED QUERIES
ANSWER: the assertion and the return seem to be bogus, so I
removed them.
11. This code from mps_chat in the Scheme example is wrong:
22. How does fixing interact with tagged references? Do I need to
remove the tag before fixing a reference? Do I need to restore the
tag afterwards? I thought that both would be necessary but the
critical path documentation has an example from OpenDylan with
tagged references that does neither:
<https://info.ravenbrook.com/project/mps/master/design/critical-path.txt>
ANSWER: we'll document that all references need to be
decrypted/de-tagged. There ought to be some slack in practice but
it needs thought. Make a job.
ACTION: made <https://info.ravenbrook.com/project/mps/issue/job003317/>
23. This code from mps_chat in the Scheme example is wrong:
if (type == mps_message_type_gc_start()) {
printf("Collection %lu started.\n", (unsigned long)mps_collections(arena));
@ -221,24 +195,24 @@ ANSWERED QUERIES
ACTION: made <https://info.ravenbrook.com/project/mps/issue/job003318/>
12. It seems "tricky" to re-use fowarding objects as padding objects
24. It seems "tricky" to re-use fowarding objects as padding objects
by setting their forwarding pointer to NULL. Wouldn't it be
simpler to explain if we had TYPE_PAD for multiple-word padding
objects? Things are difficult enough to explain as it is!
ANSWER: It would be simpler, so I made this change.
13. The Scheme example says, "Adapting it to use the MPS took
25. The Scheme example says, "Adapting it to use the MPS took
approximately two hours". I doubt this would be the common case,
and it would be better to under-promise here and over-deliver.
ANSWER: take it out.
16. Wouldn't the Scheme example be better without TAB characters?
28. Wouldn't the Scheme example be better without TAB characters?
ANSWER: maybe, but it would lead to merge conflicts. So no change.
17. The example code looks better (easier to see the structure) if I
29. The example code looks better (easier to see the structure) if I
use an indentation of four spaces. There are also cases where the
original code is inconsistent (compare the indentation of the case
labels in "print" versus "obj_scan"). I've made these consistent
@ -248,20 +222,26 @@ ANSWERED QUERIES
ANSWER: no.
18. The Scheme example is inconsistent in its use of whitespace: for
30. The Scheme example is inconsistent in its use of whitespace: for
example sometimes there's a space after "if" and sometimes not.
ANSWER: maybe so, but it would lead to merge conflicts. So no
change.
22. The generic example of using mps_tramp need to pass argv and argc,
31. What is a root mode and how do I explain it?
ANSWER: currently a root mode has no effect. It tells the MPS
whether it's OK for the MPS to put a barrier on the
root. Recommend pass zero. For future expansion.
34. The generic example of using mps_tramp need to pass argv and argc,
and return an exit code, so maybe it would make sense to do that
in the Scheme example, even though Scheme doesn't use these
parameters.
ANSWER: no.
23. There's a lot of stuff to explain here, and I think some of it
35. There's a lot of stuff to explain here, and I think some of it
could be simplified:
a. The common trampoline case (passing argv and argc, and
@ -272,7 +252,19 @@ ANSWERED QUERIES
ANSWER: leave it as it is.
28. The fragmentation_limit argument to mps_class_mvt is an integer
36. The discussion in the Scheme example about mps_reserve suggests
that mps_alloc doesn't require aligned sizes. Is that right? Needs
to be added to mps_alloc reference if so.
ANSWER: in fact there's no rule about this. Depends on the pool
class. "It doesn't unless the pool class says it does".
39. We don't support scanning the stack/registers except via
mps_stack_scan_ambig? Document this?
ANSWER: this is the only one we support at the moment.
40. The fragmentation_limit argument to mps_class_mvt is an integer
representing a percentage between 1 and 100. For consistency with
mps_gen_param_s this should be a double between 0 (exclusive) and
1. Can we change this?
@ -281,8 +273,10 @@ ANSWERED QUERIES
ACTION: made <https://info.ravenbrook.com/project/mps/issue/job003319/>
29. Move symbol reference from mpsio.h, mpstd.h and mpslib.h to the
41. Move symbol reference from mpsio.h, mpstd.h and mpslib.h to the
plinth topic document.
ACTION: done.
42. Move symbol references for the pool classes to the corresponding
pool document.

View file

@ -42,19 +42,19 @@ First, answer these questions about your data:
And then look up your answers in this table to find the recommended
pool class to use:
========== ======= ==================== ===================================
Automatic? Moving? References? Use this pool class
========== ======= ==================== ===================================
yes yes none :ref:`pool-amcz`
yes yes exact :ref:`pool-amc`
yes yes weak :ref:`pool-awl`
yes no none :ref:`pool-lo`
yes no exact :ref:`pool-ams`
yes no weak nothing suitable
no *any* none :ref:`pool-mvt`
no *any* exact :ref:`pool-mvt` [1]_
no *any* weak nothing suitable
========== ======= ==================== ===================================
========== ======== ==================== ===================================
Automatic? Movable? References? Use this pool class
========== ======== ==================== ===================================
yes yes none :ref:`pool-amcz`
yes yes exact :ref:`pool-amc`
yes yes weak :ref:`pool-awl`
yes no none :ref:`pool-lo`
yes no exact :ref:`pool-ams`
yes no weak nothing suitable
no *any* none :ref:`pool-mvt`
no *any* exact :ref:`pool-mvt` [1]_
no *any* weak nothing suitable
========== ======== ==================== ===================================
.. note::

View file

@ -18,3 +18,68 @@ The AMC pool class exploits assumptions about object lifetimes and inter-connect
:c:func:`mps_ap_frame_push` and :c:func:`mps_ap_frame_pop` 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.
If an allocation point is created in an AMC pool, the call to :c:func:`mps_ap_create` will take no additional parameters.
=========================
Declared in ``mpscamc.h``
=========================
.. c:function:: void mps_amc_apply(mps_pool_t pool, void (*f)(mps_addr_t object, void *p, size_t s), void *p, size_t s)
Visit all :term:`formatted objects <formatted object>` in an
:ref:`pool-amc`.
``pool`` is the pool whose formatted objects you want to visit.
``f`` is a function that will be called for each formatted object in
the pool. It takes three arguments: ``object`` is the address of the
object; ``p`` and ``s`` are the corresponding arguments that were
passed to :c:func:`mps_amc_apply`.
``p`` and ``s`` are arguments that will be passed to ``f`` each time it
is called. This is intended to make it easy to pass, for example,
an array and its size as parameters.
You may only call this function when the :term:`arena` is in the
:term:`parked state`, for example, after calling
:c:func:`mps_arena_collect` or :c:func:`mps_arena_park`.
The function ``f`` will be called on both :term:`client <client
object>` and :term:`padding objects <padding object>`. It is the
job of ``f`` to distinguish, if necessary, between the two. It may
also be called on :term:`dead` objects that the collector has not
recycled or has been unable to recycle.
The function ``f`` may not allocate memory or access any
automatically-managed memory except within ``object``.
.. topics::
:ref:`topic-scanning`.
.. note::
There is no equivalent function for other pool classes, but
there is a more general function
:c:func:`mps_arena_formatted_objects_walk` that visits all
formatted objects in the arena.
.. c:function:: mps_class_t mps_class_amc(void)
Return the :term:`pool class` for an AMC (Automatic
Mostly-Copying) :term:`pool`.
When creating an AMC pool, :c:func:`mps_pool_create` takes two
extra arguments::
mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
mps_class_t mps_class_amc(),
mps_fmt_t fmt,
mps_chain_t chain)
``fmt`` specifies the :term:`object format` for the objects
allocated in the pool.
``chain`` specifies the :term:`generation chain` that the objects in
the pool will be collected into.

View file

@ -4,3 +4,11 @@
AMCZ (Automatic Mostly-Copying Zero-rank)
=========================================
=============================
Undocumented in ``mpscamc.h``
=============================
.. c:function:: mps_class_t mps_class_amcz(void)

View file

@ -4,3 +4,12 @@
AMS (Automatic Mark and Sweep)
==============================
=============================
Undocumented in ``mpscams.h``
=============================
.. c:function:: mps_class_t mps_class_ams(void)
.. c:function:: mps_class_t mps_class_ams_debug(void)

View file

@ -4,3 +4,11 @@
AWL (Automatic Weak Linked)
===========================
=============================
Undocumented in ``mpscawl.h``
=============================
.. c:function:: mps_class_t mps_class_awl(void)

View file

@ -3,3 +3,13 @@
==============
LO (Leaf Only)
==============
============================
Undocumented in ``mpsclo.h``
============================
.. c:function:: mps_class_t mps_class_lo(void)

View file

@ -4,3 +4,15 @@
MV (Manual Variable)
====================
============================
Undocumented in ``mpscmv.h``
============================
.. c:function:: size_t mps_mv_free_size(mps_pool_t pool)
.. c:function:: size_t mps_mv_size(mps_pool_t pool)
.. c:function:: mps_class_t mps_class_mv(void)
.. c:function:: mps_class_t mps_class_mv_debug(void)

View file

@ -23,3 +23,50 @@ It is usually not advisable to use buffered and unbuffered allocation at the sam
Note that using buffered allocation prevents (for obscure technical reasons) the pool from allocating across segment boundaries. This can cause added external fragmentation if objects are allocated that are a significant fraction of the segment size. (This quirk will disappear in a future version.)
==========================
Declared in ``mpscmvff.h``
==========================
.. c:function:: mps_class_t mps_class_mvff(void)
Return the :term:`pool class` for an MVFF (Manual Variable-size
First Fit) :term:`pool`.
When creating an MVFF pool, :c:func:`mps_pool_create` takes six
extra arguments::
mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
mps_class_t mps_class_mvff(),
mps_size_t extendBy,
mps_size_t avgSize,
mps_align_t alignment,
mps_bool_t slotHigh,
mps_bool_t arenaHigh,
mps_bool_t firstFit)
``extendBy`` is the :term:`size` of :term:`segment` to allocate by
default.
``avgSize`` is the average size of blocks to be allocated.
``alignment`` is the :term:`alignment` of addresses for allocation
(and freeing) in the pool. If an unaligned size is passed to
:c:func:`mps_alloc` or :c:func:`mps_free`, it will be rounded up
to the pool's alignment. The minimum alignment supported by pools
of this class is ``sizeof(void *)``.
``slotHigh``, ``arenaHigh``, and ``firstFit`` are undocumented and may
be set to (0, 0, 1) or (1, 1, 1). No other setting of these
parameters is currently recommended.
==============================
Undocumented in ``mpscmvff.h``
==============================
.. c:function:: size_t mps_mvff_free_size(mps_pool_t mpspool)
.. c:function:: size_t mps_mvff_size(mps_pool_t pool)
.. c:function:: mps_class_t mps_class_mvff_debug(void)

View file

@ -83,3 +83,63 @@ Eventually the MM product will include profiling tools that will help determine
Remember Wilson's statement that the goal of a memory manager is to exploit the regularities in allocation patterns? My intent in the interface parameters is to accept measurable regularities in object populations, then the implementation can exploit them.
Perhaps the pool should accept some description of the mean and deviation of the object sizes, object population, and object lifetimes. Is that what you are getting at? [Reserve_depth is in some sense a deviation.]
=========================
Declared in ``mpscmv2.h``
=========================
.. c:function:: mps_class_t mps_class_mvt(void)
Return the :term:`pool class` for an MVT (Manual Variable-size
Temporal-fit) :term:`pool`.
When creating an MVT pool, :c:func:`mps_pool_create` takes five
extra arguments::
mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
mps_class_t mps_class_mvt(),
size_t minimum_size,
size_t mean_size,
size_t maximum_size,
mps_count_t reserve_depth,
mps_count_t fragmentation_limit)
``minimum_size``, ``mean_size``, and ``maximum_size`` are the minimum,
mean, and maximum (typical) :term:`size` of :term:`blocks <block>`
expected to be allocated in the pool. Blocks smaller than
``minimum_size`` and larger than ``maximum_size`` may be allocated,
but the pool is not guaranteed to manage them space-efficiently.
Furthermore, partial freeing is not supported for blocks larger
than ``maximum_size``; doing so will result in the storage of the
block never being reused. ``mean_size`` need not be an accurate
mean, although the pool will manage ``mean_size`` blocks more
efficiently if it is.
``reserve_depth`` is the expected hysteresis of the population of
the pool. When blocks are freed, the pool will retain sufficient
storage to allocate ``reserve_depth`` blocks of ``mean_size`` for near
term allocations (rather than immediately making that storage
available to other pools).
``fragmentation_limit`` is a percentage in (0, 100] that can be used
to set an upper limit on the space overhead of MVT in case block
death times and allocations do not correlate well. If the free
space managed by the pool as a ratio of all the space managed by
the pool exceeds ``fragmentation_limit``, the pool falls back to a
first fit allocation policy, exploiting space more efficiently at
a cost in time efficiency. A fragmentation limit of 0 would cause
the pool to operate as a first-fit pool, at a significant cost in
time efficiency, therefore is not permitted.
=============================
Undocumented in ``mpscmv2.h``
=============================
.. c:function:: mps_class_t mps_class_mvt(void)
.. c:function:: size_t mps_mvt_free_size(mps_pool_t pool)
.. c:function:: size_t mps_mvt_size(mps_pool_t pool)

View file

@ -18,3 +18,30 @@ If an allocation point is created in an SNC pool, then the call to :c:func:`mps_
Objects in an SNC pool may not be registered for finalization.
Objects in an SNC pool will not move.
=========================
Declared in ``mpscsnc.h``
=========================
.. c:function:: mps_class_t mps_class_snc(void)
Return the :term:`pool class` for an SNC (Stack No Check)
:term:`pool`.
When creating an SNC pool, :c:func:`mps_pool_create` takes one
extra argument::
mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
mps_class_t mps_class_snc(),
mps_fmt_t fmt)
``fmt`` specifies the :term:`object format` for the objects
allocated in the pool. The format should provide at least the
methods scan, skip, and pad.
.. topics::
:ref:`pool-snc`.

View file

@ -54,7 +54,9 @@ Declared in ``mps.h``
``pool`` the pool to allocate in.
``size`` is the :term:`size` of the block to allocate.
``size`` is the :term:`size` of the block to allocate. This need
not be rounded up to the pool :term:`alignment` unless the pool
document says that it needs to be.
Some pool classes require additional arguments to be passed to
:c:func:`mps_alloc`. See the documentation for the pool class.
@ -892,6 +894,11 @@ Declared in ``mps.h``
.. note::
If your reference is :term:`tagged <tagged reference>`, you
must remove the tag before calling :c:func:`mps_fix`, and
restore the tag to the (possibly updated) reference
afterwards.
If you want to call this between :c:func:`MPS_SCAN_BEGIN` and
:c:func:`MPS_SCAN_END`, you must use :c:func:`MPS_FIX_CALL`
to ensure that the scan state is passed correctly.
@ -919,6 +926,9 @@ Declared in ``mps.h``
.. note::
If your reference is :term:`tagged <tagged reference>`, you
must remove the tag before calling :c:func:`MPS_FIX1`.
In the common case where the scan method does not need to do
anything between :c:func:`MPS_FIX1` and :c:func:`MPS_FIX2`,
you can use the convenience macro :c:func:`MPS_FIX12`.
@ -947,6 +957,11 @@ Declared in ``mps.h``
.. note::
If your reference is :term:`tagged <tagged reference>`, you
must remove the tag before calling :c:func:`MPS_FIX2`, and
restore the tag to the (possibly updated) reference
afterwards.
The macro :c:func:`MPS_FIX12` is a convenience for the common
case where :c:func:`MPS_FIX1` is immediately followed by
:c:func:`MPS_FIX2`.
@ -975,6 +990,11 @@ Declared in ``mps.h``
.. note::
If your reference is :term:`tagged <tagged reference>`, you
must remove the tag before calling :c:func:`MPS_FIX12`, and
restore the tag to the (possibly updated) reference
afterwards.
In the common case where the scan method does not need to do
anything between :c:func:`MPS_FIX1` and :c:func:`MPS_FIX2`,
you can use the convenience macro :c:func:`MPS_FIX12`.
@ -1473,29 +1493,33 @@ Declared in ``mps.h``
``ld`` is a location dependency.
``arena`` is an :term:`arena`.
``arena`` is the :term:`arena` to which ``addr`` belongs.
``addr`` is the address of the block. It can be any address: it
is not limited to addresses in ``arena``.
``addr`` is the address of the block.
After calling :c:func:`mps_ld_add`, and until ``ld`` is passed to
:c:func:`mps_ld_reset`, the call ::
mps_ld_isstale(ld, arena, addr)
will return true if the block has moved. It is possible to add the
same address more than once.
will return true if the block has moved.
:c:func:`mps_ld_add` is not thread-safe with respect to
:c:func:`mps_ld_add`, :c:func:`mps_ld_merge`, or
:c:func:`mps_ld_reset` on the same location dependency, but it is
thread-safe with respect to :c:func:`mps_ld_isstale` operations.
This means that calls to :c:func:`mps_ld_add` from different
:term:`threads <thread>` must interlock if they are using the same
location dependency. The practical upshot of this is that there
should be a lock associated with each location dependency.
.. note::
:c:func:`mps_ld_add` does not allocate.
It is an error to call :c:func:`mps_ld_add` on the same
location dependency with addresses from two different arenas.
If you need to test for staleness against multiple arenas,
then you need at least one location dependency for each arena.
:c:func:`mps_ld_add` is not thread-safe with respect to
:c:func:`mps_ld_add`, :c:func:`mps_ld_merge`, or
:c:func:`mps_ld_reset` on the same location dependency, but it
is thread-safe with respect to :c:func:`mps_ld_isstale`
operations. This means that calls to :c:func:`mps_ld_add` from
different :term:`threads <thread>` must interlock if they are
using the same location dependency. The practical upshot of
this is that there should be a lock associated with each
location dependency.
.. topics::
@ -1505,28 +1529,39 @@ Declared in ``mps.h``
.. c:function:: mps_bool_t mps_ld_isstale(mps_ld_t ld, mps_arena_t arena, mps_addr_t addr)
Determine if any of the depdencies in a :term:`location
dependency` are stale.
dependency` are stale with respect to an :term:`arena`.
``ld`` is the location dependency.
``arena`` is an arena.
``arena`` is the arena to test for staleness against. It must be
the same arena that was passed to all calls to :term:`mps_ld_add`
on ``ld``.
``addr`` is an address.
``addr`` is an address that may appear in :term:`telemetry`
related to this call (*not* an address to test for staleness).
The location dependency is examined to determine whether any of
the dependencies encapsulated in it have been made stale. If any
of the dependencies encapsulated in the location dependency are
stale (that is, the blocks whose location has been depended on
have moved) then :c:func:`mps_ld_isstale` will return true. If
there have been no calls to :c:func:`mps_ld_add` on ``ld`` since the
last call to :c:func:`mps_ld_reset`, then :c:func:`mps_ld_isstale`
will return false. :c:func:`mps_ld_isstale` may return any value
in other circumstances (but will strive to return false if the
objects encapsulated in the location dependency have not moved).
the dependencies encapsulated in it have been made stale with
respect to ``arena``. If any of the dependencies encapsulated in
the location dependency are stale (that is, the blocks whose
location has been depended on have been moved by ``arena``) then
:c:func:`mps_ld_isstale` will return true. If there have been no
calls to :c:func:`mps_ld_add` on ``ld`` since the last call to
:c:func:`mps_ld_reset`, then :c:func:`mps_ld_isstale` will return
false. :c:func:`mps_ld_isstale` may return any value in other
circumstances (but will strive to return false if the objects
encapsulated in the location dependency have not moved).
:c:func:`mps_ld_isstale` is thread-safe with respect to itself and
with respect to :c:func:`mps_ld_add`, but not with respect to
:c:func:`mps_ld_reset`.
.. note::
:c:func:`mps_ld_isstale` may report a false positive
(returning true despite none of the added addresses having
being moved by the arena) but never a false negative
(returning false when an added address has been moved).
:c:func:`mps_ld_isstale` is thread-safe with respect to itself
and with respect to :c:func:`mps_ld_add`, but not with respect
to :c:func:`mps_ld_reset`.
.. topics::
@ -1539,7 +1574,7 @@ Declared in ``mps.h``
``dest_ld`` is the destination of the merge.
``arena`` is an :term:`arena`.
``arena`` is the :term:`arena` .
``src_ld`` is the source of the merge.
@ -1562,10 +1597,10 @@ Declared in ``mps.h``
``arena`` is an arena.
After this call, ``ld`` encapsulates no dependencies. After the call
to :c:func:`mps_ld_reset` and prior to any call to
After this call, ``ld`` encapsulates no dependencies. After the
call to :c:func:`mps_ld_reset` and prior to any call to
:c:func:`mps_ld_add` on ``ld``, :c:func:`mps_ld_isstale` on ``ld``
will return false for all addresses.
will return false for all arenas.
:c:func:`mps_ld_reset` is not thread-safe with respect to any
other location dependency function.
@ -2536,10 +2571,10 @@ Declared in ``mps.h``
.. note::
:term:`Client programs <client program>` are not expected to
write their own scanning functions to pass to this function.
The built-in MPS function :c:func:`mps_stack_scan_ambig`
should be used.
It is not supported for :term:`Client programs <client
program>` to pass their own scanning functions to this
function. The built-in MPS function
:c:func:`mps_stack_scan_ambig` must be used.
.. c:function:: 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 count)
@ -3334,193 +3369,6 @@ Declared in ``mpsavm.h``
:ref:`topic-arena`.
=========================
Declared in ``mpscamc.h``
=========================
.. c:function:: void mps_amc_apply(mps_pool_t pool, void (*f)(mps_addr_t object, void *p, size_t s), void *p, size_t s)
Visit all :term:`formatted objects <formatted object>` in an
:ref:`pool-amc`.
``pool`` is the pool whose formatted objects you want to visit.
``f`` is a function that will be called for each formatted object in
the pool. It takes three arguments: ``object`` is the address of the
object; ``p`` and ``s`` are the corresponding arguments that were
passed to :c:func:`mps_amc_apply`.
``p`` and ``s`` are arguments that will be passed to ``f`` each time it
is called. This is intended to make it easy to pass, for example,
an array and its size as parameters.
You may only call this function when the :term:`arena` is in the
:term:`parked state`, for example, after calling
:c:func:`mps_arena_collect` or :c:func:`mps_arena_park`.
The function ``f`` will be called on both :term:`client <client
object>` and :term:`padding objects <padding object>`. It is the
job of ``f`` to distinguish, if necessary, between the two. It may
also be called on :term:`dead` objects that the collector has not
recycled or has been unable to recycle.
The function ``f`` may not allocate memory or access any
automatically-managed memory except within ``object``.
.. topics::
:ref:`topic-scanning`.
.. note::
There is no equivalent function for other pool classes, but
there is a more general function
:c:func:`mps_arena_formatted_objects_walk` that visits all
formatted objects in the arena.
.. c:function:: mps_class_t mps_class_amc(void)
Return the :term:`pool class` for an AMC (Automatic
Mostly-Copying) :term:`pool`.
When creating an AMC pool, :c:func:`mps_pool_create` takes two
extra arguments::
mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
mps_class_t mps_class_amc(),
mps_fmt_t fmt,
mps_chain_t chain)
``fmt`` specifies the :term:`object format` for the objects
allocated in the pool.
``chain`` specifies the :term:`generation chain` that the objects in
the pool will be collected into.
.. topics::
:ref:`pool-amc`.
==========================
Declared in ``mpscmvff.h``
==========================
.. c:function:: mps_class_t mps_class_mvff(void)
Return the :term:`pool class` for an MVFF (Manual Variable-size
First Fit) :term:`pool`.
When creating an MVFF pool, :c:func:`mps_pool_create` takes six
extra arguments::
mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
mps_class_t mps_class_mvff(),
mps_size_t extendBy,
mps_size_t avgSize,
mps_align_t alignment,
mps_bool_t slotHigh,
mps_bool_t arenaHigh,
mps_bool_t firstFit)
``extendBy`` is the :term:`size` of :term:`segment` to allocate by
default.
``avgSize`` is the average size of blocks to be allocated.
``alignment`` is the :term:`alignment` of addresses for allocation
(and freeing) in the pool. If an unaligned size is passed to
:c:func:`mps_alloc` or :c:func:`mps_free`, it will be rounded up
to the pool's alignment. The minimum alignment supported by pools
of this class is ``sizeof(void *)``.
``slotHigh``, ``arenaHigh``, and ``firstFit`` are undocumented and may
be set to (0, 0, 1) or (1, 1, 1). No other setting of these
parameters is currently recommended.
.. topics::
:ref:`pool-mvff`.
=========================
Declared in ``mpscmv2.h``
=========================
.. c:function:: mps_class_t mps_class_mvt(void)
Return the :term:`pool class` for an MVT (Manual Variable-size
Temporal-fit) :term:`pool`.
When creating an MVT pool, :c:func:`mps_pool_create` takes five
extra arguments::
mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
mps_class_t mps_class_mvt(),
size_t minimum_size,
size_t mean_size,
size_t maximum_size,
mps_count_t reserve_depth,
mps_count_t fragmentation_limit)
``minimum_size``, ``mean_size``, and ``maximum_size`` are the minimum,
mean, and maximum (typical) :term:`size` of :term:`blocks <block>`
expected to be allocated in the pool. Blocks smaller than
``minimum_size`` and larger than ``maximum_size`` may be allocated,
but the pool is not guaranteed to manage them space-efficiently.
Furthermore, partial freeing is not supported for blocks larger
than ``maximum_size``; doing so will result in the storage of the
block never being reused. ``mean_size`` need not be an accurate
mean, although the pool will manage ``mean_size`` blocks more
efficiently if it is.
``reserve_depth`` is the expected hysteresis of the population of
the pool. When blocks are freed, the pool will retain sufficient
storage to allocate ``reserve_depth`` blocks of ``mean_size`` for near
term allocations (rather than immediately making that storage
available to other pools).
``fragmentation_limit`` is a percentage in (0, 100] that can be used
to set an upper limit on the space overhead of MVT in case block
death times and allocations do not correlate well. If the free
space managed by the pool as a ratio of all the space managed by
the pool exceeds ``fragmentation_limit``, the pool falls back to a
first fit allocation policy, exploiting space more efficiently at
a cost in time efficiency. A fragmentation limit of 0 would cause
the pool to operate as a first-fit pool, at a significant cost in
time efficiency, therefore is not permitted.
.. topics::
:ref:`pool-mvt`
=========================
Declared in ``mpscsnc.h``
=========================
.. c:function:: mps_class_t mps_class_snc(void)
Return the :term:`pool class` for an SNC (Stack No Check)
:term:`pool`.
When creating an SNC pool, :c:func:`mps_pool_create` takes one
extra argument::
mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
mps_class_t mps_class_snc(),
mps_fmt_t fmt)
``fmt`` specifies the :term:`object format` for the objects
allocated in the pool. The format should provide at least the
methods scan, skip, and pad.
.. topics::
:ref:`pool-snc`.
=========================
Undocumented in ``mps.h``
=========================
@ -3570,63 +3418,6 @@ Undocumented in ``mps.h``
.. c:function:: void mps_pool_check_free_space(mps_pool_t mps_pool)
=============================
Undocumented in ``mpscamc.h``
=============================
.. c:function:: mps_class_t mps_class_amcz(void)
=============================
Undocumented in ``mpscams.h``
=============================
.. c:function:: mps_class_t mps_class_ams(void)
.. c:function:: mps_class_t mps_class_ams_debug(void)
=============================
Undocumented in ``mpscawl.h``
=============================
.. c:function:: mps_class_t mps_class_awl(void)
============================
Undocumented in ``mpsclo.h``
============================
.. c:function:: mps_class_t mps_class_lo(void)
============================
Undocumented in ``mpscmv.h``
============================
.. c:function:: size_t mps_mv_free_size(mps_pool_t pool)
.. c:function:: size_t mps_mv_size(mps_pool_t pool)
.. c:function:: mps_class_t mps_class_mv(void)
.. c:function:: mps_class_t mps_class_mv_debug(void)
=============================
Undocumented in ``mpscmv2.h``
=============================
.. c:function:: mps_class_t mps_class_mvt(void)
.. c:function:: size_t mps_mvt_free_size(mps_pool_t pool)
.. c:function:: size_t mps_mvt_size(mps_pool_t pool)
==============================
Undocumented in ``mpscmvff.h``
==============================
.. c:function:: size_t mps_mvff_free_size(mps_pool_t mpspool)
.. c:function:: size_t mps_mvff_size(mps_pool_t pool)
.. c:function:: mps_class_t mps_class_mvff_debug(void)
===========================
Undocumented in ``mpsw3.h``
===========================