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

Updated manual html

Copied from Perforce
 Change: 182619
 ServerID: perforce.ravenbrook.com
This commit is contained in:
Richard Brooksby 2013-06-08 12:44:13 +01:00
parent 2f6af8883a
commit dd4dcf5ca9
37 changed files with 4478 additions and 523 deletions

View file

@ -0,0 +1,106 @@
.. _design-abq:
Queue design
============
.. mps:prefix:: design.mps.abq
Introduction
------------
:mps:tag:`intro` This is the design of the ABQ module, which implements a
fixed-length queue of small objects.
:mps:tag:`readership` This document is intended for any MM developer.
:mps:tag:`name` The name ABQ originally stood for "Available Block Queue" as
the module is used by the MVT pool.
Requirements
------------
:mps:tag:`req.push` Clients can efficiently push new elements onto the queue.
:mps:tag:`req.pop` Clients can efficiently pop elements from the queue.
:mps:tag:`req.empty` Clients can efficiently test whether the queue is empty.
:mps:tag:`req.abstract` The ABQ module does not know anything about the
elements in the queue other than their size.
:mps:tag:`req.delete` Clients can delete elements from the queue. (Note: not necessarily efficiently.)
:mps:tag:`req.iterate` Clients can iterate over elements in the queue.
Interface
---------
.. c:type:: ABQStruct *ABQ
:c:macro:`ABQ` is the type of a queue. It is an alias for ``ABQStruct *``.
:c:type:`ABQStruct` is defined in the header so that it can be inlined in
client structures: clients must not depend on its implementation
details.
.. c:function:: ABQInit(Arena arena, ABQ abq, void *owner, Count elements, Size elementSize)
Initialize the queue ``abq``. The parameter ``arena`` is the arena
whose control pool should be used to allocate the memory for the
queue; ``owner`` is passed to :c:func:`MeterInit()` for the statistics;
``elements`` is the maximum number of elements that can be stored in
the queue; and ``elementSize`` is the size of each element.
.. c:function:: void ABQFinish(Arena arena, ABQ abq)
Finish ``abq`` and free all resources associated with it.
.. c:function:: Res ABQPush(ABQ abq, void *element)
If the queue is full, leave it unchanged and return ``ResFAIL``.
Otherwise, push ``element`` on to the queue and return ``ResOK``.
.. c:function:: Res ABQPop(ABQ abq, void *elementReturn)
If the queue is empty, return ``ResFAIL``. Othwreise, copy the first
element on the queue into the memory pointed to by ``elementReturn``,
remove the element from the queue, and return ``ResOK``.
.. c:function:: Res ABQPeek(ABQ abq, void *elementReturn)
If the queue is empty, return ``ResFAIL``. Otherwise, copy the first
element on the queue into the memory pointed to by ``elementReturn``
and return ``ResOK``. (This is the same as :c:func:`ABQPop()` except that
the queue is unchanged.)
.. c:function:: Bool ABQIsEmpty(ABQ abq)
If the queue is empty, return :c:macro:`TRUE`, otherwise return :c:macro:`FALSE`.
.. c:function:: Bool ABQIsFull(ABQ abq)
If the queue is full, return :c:macro:`TRUE`, otherwise return :c:macro:`FALSE`.
.. c:function:: Count ABQDepth(ABQ abq)
Return the number of elements in the queue.
.. c:type:: Bool (*ABQIterateMethod)(Bool *deleteReturn, void *element, void *closureP, Size closureS)
A callback function for :c:func:`ABQIterate()`. The parameter ``element`` is
an element in the queue, and ``closureP`` and ``closureS`` are the
values that were originally passed to :c:func:`ABQIterate()`. This function
must set ``*deleteReturn`` to :c:macro:`FALSE` if ``element`` must be kept in
the queue, or :c:macro:`TRUE` if ``element`` must be deleted from the queue.
It must return :c:macro:`TRUE` if the iteration must continue, or :c:macro:`FALSE`
if the iteration must stop after processing ``element``.
.. c:function:: void ABQIterate(ABQ abq, ABQIterateMethod iterate, void *closureP, Size closureS)
Call ``iterate`` for each elements in the queue, passing the element
and ``closureP``. See :c:type:`ABQIterateMethod` for details.

View file

@ -0,0 +1,37 @@
.. _design-boot:
The MPS Bootstrap
=================
.. mps:prefix:: design.mps.boot
Introduction
------------
The `Memory Pool System`_ starts with no memory, but must somehow
allocate its own control structures in order to provide memory to the
client program. The MPS is freestanding [ref?] and so it can't get its
memory from the C library's ``malloc``. So how does it get off the
ground? It pulls itself up by its own bootstraps. This document
describes how.
.. note::
This document was written as a prelude to reforming the bootstrap,
so it shouldn't be taken as advocating it as an amazing piece of
design.
Pretty much the first call to the MPS is to ``ArenaCreate``, which calls the
arena class specific ``init`` method. That must create an initialized arena,
except for the "control pool", from which many MPS data structures will be
allocated.
In the case of the VM arena, ``VMArenaInit`` creates a VM large enough to hold
a :c:type:`VMArenaStruct` (which contains the generic :c:type:`ArenaStruct`) and maps
pages into it. It then calls ``ArenaInit`` to initialise the generic part,
before filling in the VM-specific part. Having done that, it adds the initial
``VMChunk`` -- a large area of address space -- that will be used to supply
memory via ``ArenaAlloc``.

View file

@ -0,0 +1,329 @@
.. _design-cbs:
Coalescing block structure
==========================
.. mps:prefix:: design.mps.cbs
Introduction
------------
:mps:tag:`intro` This is the design for impl.c.cbs, which implements a data
structure for the management of non-intersecting memory ranges, with
eager coalescence.
:mps:tag:`readership` This document is intended for any MM developer.
:mps:tag:`source` design.mps.poolmv2, design.mps.poolmvff.
:mps:tag:`overview` The "coalescing block structure" is a set of addresses
(or a subset of address space), with provision for efficient
management of contiguous ranges, including insertion and deletion,
high level communication with the client about the size of contiguous
ranges, and detection of protocol violations.
Definitions
-----------
:mps:tag:`def.range` A (contiguous) *range* of addresses is a semi-open
interval on address space.
:mps:tag:`def.isolated` A contiguous range is *isolated* with respect to
some property it has, if adjacent elements do not have that property.
Requirements
------------
:mps:tag:`req.set` Must maintain a set of addresses.
:mps:tag:`req.fast` Common operations must have a low amortized cost.
:mps:tag:`req.add` Must be able to add address ranges to the set.
:mps:tag:`req.remove` Must be able to remove address ranges from the set.
:mps:tag:`req.size` Must report concisely to the client when isolated
contiguous ranges of at least a certain size appear and disappear.
:mps:tag:`req.iterate` Must support the iteration of all isolated
contiguous ranges. This will not be a common operation.
:mps:tag:`req.protocol` Must detect protocol violations.
:mps:tag:`req.debug` Must support debugging of client code.
:mps:tag:`req.small` Must have a small space overhead for the storage of
typical subsets of address space and not have abysmal overhead for the
storage of any subset of address space.
:mps:tag:`req.align` Must support an alignment (the alignment of all
addresses specifying ranges) of down to ``sizeof(void *)`` without
losing memory.
Interface
---------
:mps:tag:`header` CBS is used through impl.h.cbs.
External types
..............
.. c:type:: struct CBSStruct *CBS
:mps:tag:`type.cbs` :c:macro:`CBS` is the main data structure for manipulating a
CBS. It is intended that a :c:type:`CBSStruct` be embedded in another
structure. No convenience functions are provided for the allocation or
deallocation of the CBS.
.. c:type:: Bool (*CBSIterateMethod)(CBS cbs, Range range, void *closureP, Size closureS)
:mps:tag:`type.cbs.iterate.method` Type :c:type:`CBSIterateMethod` is a callback
function that may be passed to :c:func:`CBSIterate()`. It is called for
every isolated contiguous range in address order. The function must
returns a :c:type:`Bool` indicating whether to continue with the iteration.
External functions
..................
.. c:function:: Res CBSInit(Arena arena, CBS cbs, void *owner, Align alignment, Bool fastFind, ArgList args)
:mps:tag:`function.cbs.init` :c:func:`CBSInit()` is the function that initialises
the CBS structure. It performs allocation in the supplied arena. The
parameter ``owner`` is passed to :c:func:`MeterInit()`, an ``alignment``
indicates the alignment of ranges to be maintained. An initialised CBS
contains no ranges.
``fastFind``, if set, causes the CBS to maintain, for each subtree,
the size of the largest block in that subtree. This must be true if
any of the :c:func:`CBSFindFirst()`, :c:func:`CBSFindLast()`, or
:c:func:`CBSFindLargest()` functions are going to be used on the CBS.
:c:func:`CBSInit()` may take one keyword argument:
* :c:macro:`MPS_KEY_CBS_EXTEND_BY` (type :c:type:`Size`; default 4096) is the size
of segment that the CBS will request from the arena in which to
allocate its ``CBSBlock`` structures.
.. c:function:: void CBSFinish(CBS cbs)
:mps:tag:`function.cbs.finish` :c:func:`CBSFinish()` is the function that finishes
the CBS structure and discards any other resources associated with the
CBS.
.. c:function:: Res CBSInsert(Range rangeReturn, CBS cbs, Range range)
:mps:tag:`function.cbs.insert` If any part of ``range`` is already in the
CBS, then leave it unchanged and return ``ResFAIL``. Otherwise,
attempt to insert ``range`` into the CBS. If the insertion succeeds,
then update ``rangeReturn`` to describe the contiguous isolated range
containing the inserted range (this may differ from ``range`` if there
was coalescence on either side) and return ``ResOK``. If the insertion
fails, return a result code indicating allocation failure.
:mps:tag:`function.cbs.insert.fail` Insertion of a valid range (that is, one
that does not overlap with any range in the CBS) can only fail if the
new range is isolated and the allocation of the necessary data
structure to represent it failed.
.. c:function:: Res CBSDelete(Range rangeReturn, CBS cbs, Range range)
:mps:tag:`function.cbs.delete` If any part of the range is not in the CBS,
then leave the CBS unchanged and return ``ResFAIL``. Otherwise, update
``rangeReturn`` to describe the contiguous isolated range that
contains ``range`` (this may differ from ``range`` if there are
fragments on either side) and attempt to delete the range from the
CBS. If the deletion succeeds, return ``ResOK``. If the deletion
fails, return a result code indicating allocation failure.
:mps:tag:`function.cbs.delete.fail` Deletion of a valid range (that is, one
that is wholly contained in the CBS) can only fail if there are
fragments on both sides and the allocation of the necessary data
structures to represent them fails.
:mps:tag:`function.cbs.delete.return` :c:func:`CBSDelete()` returns the contiguous
isolated range that contains ``range`` even if the deletion fails.
This is so that the caller can try deleting the whole block (which is
guaranteed to succeed) and managing the fragments using a fallback
strategy.
.. c:function:: void CBSIterate(CBS cbs, CBSIterateMethod iterate, void *closureP, Size closureS)
:mps:tag:`function.cbs.iterate` :c:func:`CBSIterate()` is the function used to
iterate all isolated contiguous ranges in a CBS. It receives a
pointer, :c:type:`Size` closure pair to pass on to the iterator method,
and an iterator method to invoke on every range in address order. If
the iterator method returns :c:macro:`FALSE`, then the iteration is
terminated.
.. c:function:: Res CBSDescribe(CBS cbs, mps_lib_FILE *stream)
:mps:tag:`function.cbs.describe` :c:func:`CBSDescribe()` is a function that prints
a textual representation of the CBS to the given stream, indicating
the contiguous ranges in order, as well as the structure of the
underlying splay tree implementation. It is provided for debugging
purposes only.
.. c:function:: Bool CBSFindFirst(Range rangeReturn, Range oldRangeReturn, CBS cbs, Size size, FindDelete findDelete)
:mps:tag:`function.cbs.find.first` Locate the first block (in address order)
within the CBS of at least the specified size, update ``rangeReturn``
to describe that range, and return :c:macro:`TRUE`. If there is no such
block, it returns :c:macro:`FALSE`.
In addition, optionally delete the top, bottom, or all of the found
range, depending on the ``findDelete`` argument. This saves a separate
call to :c:func:`CBSDelete()`, and uses the knowledge of exactly where we
found the range. The value of ``findDelete`` must come from this
enumeration::
enum {
FindDeleteNONE, /* don't delete after finding */
FindDeleteLOW, /* delete size bytes from low end of block */
FindDeleteHIGH, /* delete size bytes from high end of block */
FindDeleteENTIRE /* delete entire range */
};
The original contiguous isolated range in which the range was found is
returned via the ``oldRangeReturn`` argument. (If ``findDelete`` is
``FindDeleteNONE`` or ``FindDeleteENTIRE``, then this will be
identical to the range returned via the ``rangeReturn`` argument.)
:c:func:`CBSFindFirst()` requires that ``fastFind`` was true when
:c:func:`CBSInit()` was called.
.. c:function:: Bool CBSFindLast(Range rangeReturn, Range oldRangeReturn, CBS cbs, Size size, FindDelete findDelete)
:mps:tag:`function.cbs.find.last` Like :c:func:`CBSFindFirst()`, except that it
finds the last block in address order.
.. c:function:: Bool CBSFindLargest(Range rangeReturn, Range oldRangeReturn, CBS cbs, Size size, FindDelete findDelete)
:mps:tag:`function.cbs.find.largest` Locate the largest block within the
CBS, and if that block is at least as big as ``size``, return its
range via the ``rangeReturn`` argument, and return :c:macro:`TRUE`. If there
are no blocks in the CBS at least as large as ``size``, return
:c:macro:`FALSE`. Pass 0 for ``size`` if you want the largest block
unconditionally.
Like :c:func:`CBSFindFirst()`, optionally delete the range (specifying
``FindDeleteLOW`` or ``FindDeleteHIGH`` has the same effect as
``FindDeleteENTIRE``). This feature requires that ``fastFind`` was
true when :c:func:`CBSInit()` was called.
Implementation
--------------
:mps:tag:`impl` This section is concerned with describing various aspects of
the implementation. It does not form part of the interface definition.
Splay tree
..........
:mps:tag:`impl.splay` The CBS is principally implemented using a splay tree
(see design.mps.splay_). Each splay tree node is embedded in a
``CBSBlock`` that represents a semi-open address range. The key passed
for comparison is the base of another range.
.. _design.mps.splay: splay
:mps:tag:`impl.splay.fast-find` :c:func:`CBSFindFirst()` and :c:func:`CBSFindLast()` use
the update/refresh facility of splay trees to store, in each
``CBSBlock``, an accurate summary of the maximum block size in the
tree rooted at the corresponding splay node. This allows rapid
location of the first or last suitable block, and very rapid failure
if there is no suitable block.
:mps:tag:`impl.find-largest` :c:func:`CBSFindLargest()` simply finds out the size
of the largest block in the CBS from the root of the tree, using
:c:func:`SplayRoot()`, and does :c:func:`SplayFindFirst()` for a block of that
size. This is O(log *n*) in the size of the free list, so it's about
the best you can do without maintaining a separate priority queue,
just to do :c:func:`CBSFindLargest()`.
Low memory behaviour
....................
:mps:tag:`impl.low-mem` When the CBS tries to allocate a new ``CBSBlock``
structure for a new isolated range as a result of either
:c:func:`CBSInsert()` or :c:func:`CBSDelete()`, and there is insufficient memory
to allocation the ``CBSBlock`` structure, then the range is not added
to the CBS or deleted from it, and the call to :c:func:`CBSInsert()` or
:c:func:`CBSDelete()` returns ``ResMEMORY``.
The CBS block
.............
:mps:tag:`impl.cbs.block` The block contains a base-limit pair and a splay
tree node.
:mps:tag:`impl.cbs.block.special` The base and limit may be equal if the
block is halfway through being deleted.
:mps:tag:`impl.cbs.block.special.just` This conflates values and status, but
is justified because block size is very important.
Testing
-------
:mps:tag:`test` The following testing will be performed on this module:
:mps:tag:`test.cbstest` There is a stress test for this module in
impl.c.cbstest. This allocates a large block of memory and then
simulates the allocation and deallocation of ranges within this block
using both a :c:macro:`CBS` and a :c:type:`BT`. It makes both valid and invalid
requests, and compares the :c:macro:`CBS` response to the correct behaviour
as determined by the :c:type:`BT`. It also iterates the ranges in the
:c:macro:`CBS`, comparing them to the :c:type:`BT`. It also invokes the
:c:func:`CBSDescribe()` method, but makes no automatic test of the resulting
output. It does not currently test the callbacks.
:mps:tag:`test.pool` Several pools (currently MVT_ and MVFF_) are implemented
on top of a CBS. These pool are subject to testing in development, QA,
and are/will be heavily exercised by customers.
.. _MVT: poolmvt
.. _MVFF: poolmvff
Notes for future development
----------------------------
:mps:tag:`future.not-splay` The initial implementation of CBSs is based on
splay trees. It could be revised to use any other data structure that
meets the requirements (especially :mps:ref:`.req.fast`).
:mps:tag:`future.hybrid` It would be possible to attenuate the problem of
:mps:ref:`.risk.overhead` (below) by using a single word bit set to represent
the membership in a (possibly aligned) word-width of grains. This
might be used for block sizes less than a word-width of grains,
converting them when they reach all free in the bit set. Note that
this would make coalescence slightly less eager, by up to
``(word-width - 1)``.
Risks
-----
:mps:tag:`risk.overhead` Clients should note that the current implementation
of CBSs has a space overhead proportional to the number of isolated
contiguous ranges. [Four words per range.] If the CBS contains every
other grain in an area, then the overhead will be large compared to
the size of that area. [Four words per two grains.] The CBS structure
is thus suitable only for managing large enough ranges.

View file

@ -0,0 +1,257 @@
.. _design-freelist:
Free list allocator
===================
.. mps:prefix:: design.mps.freelist
Introduction
------------
:mps:tag:`intro` This document describes the free list allocator for the
Memory Pool System.
:mps:tag:`readership` Any MPS developer.
Overview
--------
:mps:tag:`overview` The free list allocator is an "emergency" allocator. It
is intended for use as a fallback allocation strategy in low memory
situations, when memory is not available for the control structures
needed by other allocators. In these situations the free list allocator
ensures that memory is not lost, but with several disadvantages:
1. operations on the free list are O(n) in the number of free blocks;
2. the data structures are stored in client memory and so are
vulnerable to corruption;
3. the data structures have poor locality (and thus potentially poor
cache performance).
When memory becomes available again to allocate control structures,
the free lists can be "flushed" back into the more efficient data
structures.
:mps:tag:`bg` The free list allocator was formerly part of the Coalescing
Block Structure module (see design.mps.cbs) but it was split into its
own module because this makes it:
1. simpler (no need to interact with CBS) and thus more maintainable;
2. possible to test directly (no need to create a CBS and then force
its control pool to run out of memory); and
3. usable as a fallback allocator in other pools (not just in pools
that use CBS).
Definitions
-----------
:mps:tag:`def.range` A (contiguous) *range* of addresses is a semi-open
interval on address space.
:mps:tag:`def.isolated` A contiguous range is *isolated* with respect to
some property it has, if adjacent elements do not have that property.
Requirements
------------
:mps:tag:`req.set` Must maintain a set of free address ranges.
:mps:tag:`req.add` Must be able to add free address ranges to the set.
:mps:tag:`req.remove` Must be able to remove address ranges from the set (in
particular, when memory is allocated).
:mps:tag:`req.iterate` Must support the iteration of all isolated contiguous
ranges.
:mps:tag:`req.protocol` Must detect protocol violations.
:mps:tag:`req.align` Must support an alignment (the alignment of all
addresses specifying ranges) of down to ``sizeof(void *)`` without
losing memory.
:mps:tag:`req.zero-overhead` Must have zero space overhead for the storage
of any set of free blocks, so that it can be used to manage memory
when no memory can be allocated for control structures.
:mps:tag:`req.source` This set of requirements is derived from those of the
CBS module (see design.mps.cbs.req), except that there is no
equivalent of design.mps.cbs.req.fast, and design.mps.cbs.req.small
has been replaced with :mps:ref:`.req.zero-overhead`.
Interface
---------
Types
.....
.. c:type:: struct FreelistStruct *Freelist
:mps:tag:`type.freelist` The type of free lists. The structure
:c:type:`FreelistStruct` is declared in the header so that it can be inlined
in other structures, but you should not depend on its details.
.. c:type:: Bool (*FreelistIterateMethod)(Bool *deleteReturn, Freelist fl, Range range, void *closureP, Size closureS)
:mps:tag:`type.iterate.method` A callback function that may be passed to
:c:func:`FreelistIterate()`. It is called for every isolated contiguous
range in address order, and with the closure arguments that were
originally passed to :c:func:`FreelistIterate()`. It must update
``*deleteReturn`` to :c:macro:`TRUE` if the range must be deleted from the
free lists, or :c:macro:`FALSE` if the range must be kept. The function must
return :c:macro:`TRUE` if the iteration must continue, and :c:macro:`FALSE` if the
iteration must stop (after possibly deleting the current range).
Functions
.........
.. c:function:: Res FreelistInit(Freelist fl, Align alignment)
:mps:tag:`function.init` Initialize the ``Freelist`` structure pointed to by
``fl``. The argument ``alignment`` is the alignment of address ranges
to be maintained. An initialised free list contains no address ranges.
.. c:function:: void FreelistFinish(Freelist fl)
:mps:tag:`function.finish` Finish the free list pointed to by ``fl``.
.. c:function:: Res FreelistInsert(Range rangeReturn, Freelist fl, Range range)
:mps:tag:`function.insert` If any part of ``range`` is already in the free
list ``fl``, then leave the free list unchanged and return
``ResFAIL``. Otherwise, insert ``range`` into the free list ``fl``;
update ``rangeReturn`` to describe the contiguous isolated range
containing the inserted range (this may differ from ``range`` if there
was coalescence on either side) and return ``ResOK``.
.. c:function:: Res FreelistDelete(Range rangeReturn, Freelist fl, Range range)
:mps:tag:`function.delete` If any part of the range is not in the free list,
then leave the free list unchanged and return ``ResFAIL``. Otherwise,
remove ``range`` from the free list and update ``rangeReturn`` to
describe the contiguous isolated range that formerly contained the
deleted range (this may differ from ``range`` if there were fragments
left on either side), and return ``ResOK``.
.. c:function:: void FreelistIterate(Freelist fl, FreelistIterateMethod iterate, void *closureP, Size closureS)
:mps:tag:`function.iterate` Iterate all isolated contiguous ranges in the
free list ``fl`` in address order, calling ``iterate`` for each one.
See :c:type:`FreelistIterateMethod` for details.
.. c:function:: Bool FreelistFindFirst(Range rangeReturn, Range oldRangeReturn, Freelist fl, Size size, FindDelete findDelete)
:mps:tag:`function.find.first` Locate the first isolated contiguous range in
address order, within the free list ``fl``, of at least ``size``
bytes, update ``rangeReturn`` to that range, and return :c:macro:`TRUE`. If
there is no such continuous range, return :c:macro:`FALSE`.
In addition, optionally delete the found range from the free list,
depending on the ``findDelete`` argument. This saves a separate call
to :c:func:`FreelistDelete()`, and uses the knowledge of exactly where we
found the range. The value of ``findDelete`` must come from this
enumeration::
enum {
FindDeleteNONE, /* don't delete after finding */
FindDeleteLOW, /* delete size bytes from low end of block */
FindDeleteHIGH, /* delete size bytes from high end of block */
FindDeleteENTIRE /* delete entire range */
};
The original contiguous isolated range in which the range was found is
returned via the ``oldRangeReturn`` argument. (If ``findDelete`` is
``FindDeleteNONE`` or ``FindDeleteENTIRE``, then this will be
identical to the range returned via the ``rangeReturn`` argument.)
.. c:function:: Bool FreelistFindLast(Range rangeReturn, Range oldRangeReturn, Freelist fl, Size size, FindDelete findDelete)
:mps:tag:`function.find.last` Like :c:func:`FreelistFindFirst()`, except that it
finds the last block in address order.
.. c:function:: Bool FreelistFindLargest(Range rangeReturn, Range oldRangeReturn, Freelist fl, Size, size, FindDelete findDelete)
:mps:tag:`function.find.largest` Locate the largest block within the free
list ``fl``, and if that block is at least as big as ``size``, return
its range via the ``rangeReturn`` argument, and return :c:macro:`TRUE`. If
there are no blocks in the free list at least as large as ``size``,
return :c:macro:`FALSE`. Pass 0 for ``size`` if you want the largest block
unconditionally.
Like :c:func:`FreelistFindFirst()`, optionally delete the range from the
free list. (Always the whole range: specifying ``FindDeleteLOW`` or
``FindDeleteHIGH`` has the same effect as ``FindDeleteENTIRE``).
.. c:function:: void FreelistFlushToCBS(Freelist fl, CBS cbs)
Remove free address ranges from the free list ``fl`` and add them to
the Coalescing Block Structure ``cbs``. Continue until a call to
:c:func:`CBSInsert()` fails, or until the free list is empty, whichever
happens first.
.. c:function:: Res FreelistDescribe(Freelist fl, mps_lib_FILE *stream)
:mps:tag:`function.describe` Print a textual representation of the free
list ``fl`` to the given stream, indicating the contiguous ranges in
order. It is provided for debugging purposes only.
Implementation
--------------
:mps:tag:`impl.list` The isolated contiguous free address ranges are kept on
an address-ordered singly linked free list. (As in traditional
:c:func:`malloc()` implementations.)
:mps:tag:`impl.block` If the free address range is large enough to contain
an inline block descriptor consisting of two pointers, then the two
pointers stored are to the next free range in address order (or
:c:macro:`NULL` if there are no more ranges), and to the limit of current
free address range, in that order.
:mps:tag:`impl.grain` Otherwise, the free address range must be large enough
to contain a single pointer. The pointer stored is to the next free
range in address order, or :c:macro:`NULL` if there are no more ranges.
:mps:tag:`impl.tag` Grains and blocks are distinguished by a one-bit tag in
the low bit of the first word (the one containing the pointer to the
next range). Grains have this bit set; blocks have this bit reset.
:mps:tag:`impl.invariant` The ranges stored in the free list are *isolated*:
no two ranges are adjacent or overlapping.
:mps:tag:`impl.merge` When a free address range is added to the free list,
it is merged with adjacent ranges so as to maintain
:mps:ref:`.impl.invariant`.
:mps:tag:`impl.rule.break` The use of :c:macro:`NULL` to mark the end of the list
violates the rule that exceptional values should not be used to
distinguish exeptional situations. This infraction allows the
implementation to meet :mps:ref:`.req.zero-overhead`. (There are other ways to
do this, such as using another tag to indicate the last block in the
list, but these would be more complicated.)
Opportunities for improvement
-----------------------------
:mps:tag:`improve.length` When iterating over the list, we could check that
the number of elements visited in the course of the iteration does not
exceed the recorded size of the list.
:mps:tag:`improve.maxsize` We could maintain the maximum size of any range
on the list, and use that to make an early exit from
:c:func:`FreelistFindLargest()`. It's not clear that this would actually be
an improvement.

View file

@ -6,10 +6,14 @@ Design
.. toctree::
:numbered:
abq
cbs
config
critical-path
freelist
guide.hex.trans
guide.impl.c.format
keyword-arguments
range
ring
sig

View file

@ -120,9 +120,10 @@ Implementation
--------------
:mps:tag:`impl.free-list` The pool stores its free list in a CBS (see
`design.mps.cbs <cbs/>`_). It uses the CBS's mayUseInline facility to
avoid running out of memory to store the free list. This is the reason
for the alignment restriction above.
//gdr-peewit/info.ravenbrook.com/project/mps/branch/2013-05-17/emergency/design/poolmvff.txt
`design.mps.cbs <cbs/>`_), failing over in emergencies to a Freelist
(see design.mps.freelist) when the CBS cannot allocate new control
structures. This is the reason for the alignment restriction above.
Details

View file

@ -0,0 +1,952 @@
.. _design-poolmvt:
Manual Variable Temporal (MVT) pool design
==========================================
.. mps:prefix:: design.mps.poolmvt
Introduction
------------
:mps:tag:`intro` This is a second-generation design for a pool that manually
manages variable-sized objects. It is intended as a replacement for
poolmv (except in its control pool role) and poolepdl, and it is
intended to satisfy the requirements of the Dylan "misc" pool and the
product malloc/new drop-in replacement.
:mps:tag:`readership` MM developers
:mps:tag:`source` req.dylan(6), req.epcore(16), req.product(2)
:mps:tag:`background` design.mps.poolmv(0), design.mps.poolepdl(0),
design.product.soft.drop(0), paper.wil95(1), paper.vo96(0),
paper.grun92(1), paper.beck82(0), mail.ptw.1998-02-25.22-18(0)
Definitions
-----------
:mps:tag:`def.alignment` Alignment is a constraint on an object's address,
typically to be a power of 2 (see also, glossary.alignment )
:mps:tag:`def.bit-map` A bitmap is a boolean-valued vector (see also,
glossary.bitmap ).
:mps:tag:`def.block` A block is a contiguous extent of memory. In this
document, block is used to mean a contiguous extent of memory managed
by the pool for the pool client, typically a subset of a segment
(compare with :mps:ref:`.def.segment`).
:mps:tag:`def.cartesian-tree` A cartesian tree is a binary tree ordered by
two keys (paper.stephenson83(0)).
:mps:tag:`def.crossing-map` A mechanism that supports finding the start of
an object from any address within the object, typically only required
on untagged architectures (see also, glossary.crossing.map ).
:mps:tag:`def.footer` A block of descriptive information describing and
immediately following another block of memory (see also
:mps:ref:`.def.header`).
:mps:tag:`def.fragmentation` Fragmented memory is memory reserved to the
program but not usable by the program because of the arrangement of
memory already in use (see also, glossary.fragmentation ).
:mps:tag:`def.header` A block of descriptive information describing and
immediately preceding another block of memory (see also,
glossary.in-band.header ).
:mps:tag:`def.in-band` From "in band signalling", when descriptive
information about a data structure is stored in the data structure
itself (see also, glossary.in-band.header ).
:mps:tag:`def.out-of-band` When descriptive information about a data
structure is stored separately from the structure itself (see also,
glossary.out-of-band.header ).
:mps:tag:`def.refcount` A refcount is a count of the number of users of an
object (see also, glossary.reference.count ).
:mps:tag:`def.segment` A segment is a contiguous extent of memory. In this
document, segment is used to mean a contiguous extent of memory
managed by the MPS arena (design.mps.arena(1)) and subdivided by the
pool to provide blocks (see :mps:ref:`.def.block`) to its clients.
:mps:tag:`def.splay-tree` A splay tree is a self-adjusting binary tree
(paper.st85(0), paper.sleator96(0)).
:mps:tag:`def.splinter` A splinter is a fragment of memory that is too small
to be useful (see also, glossary.splinter )
:mps:tag:`def.subblock` A subblock is a contiguous extent of memory. In this
document, subblock is used to mean a contiguous extent of memory
manage by the client for its own use, typically a subset of a block
(compare with :mps:ref:`.def.block`).
Abbreviations
-------------
:mps:tag:`abbr.abq` ABQ = Available Block Queue
:mps:tag:`abbr.ap` AP = Allocation Point
:mps:tag:`abbr.cbs` CBS = Coalescing Block Structure
:mps:tag:`abbr.mps` MPS = Memory Pool System
:mps:tag:`abbr.mv` MV = Manual-Variable
:mps:tag:`abbr.ps` PS = PostScript
Overview
--------
:mps:tag:`overview` MVT is intended to satisfy the requirements of the
clients that need manual-variable pools, improving on the performance
of the existing manual-variable pool implementations, and reducing the
duplication of code that currently exists. The expected clients of MVT
are: Dylan (currently for its misc pool), EP (particularly the dl
pool, but all pools other than the PS object pool), and Product
(initially the malloc/new pool, but also other manual pool classes).
Requirements
------------
:mps:tag:`req.cat` Requirements are categorized per guide.req(2).
:mps:tag:`req.risk` req.epcore(16) is known to be obsolete, but the revised
document has not yet been accepted.
Critical requirements
.....................
:mps:tag:`req.fun.man-var` The pool class must support manual allocation and
freeing of variable-sized blocks (source: req.dylan.fun.misc.alloc,
req.epcore.fun.{dl,gen,tmp,stat,cache,trap}.{alloc,free},
req.product.fun.{malloc,new,man.man}).
:mps:tag:`non-req.fun.gc` There is not a requirement that the pool class
support formatted objects, scanning, or collection objects; but it
should not be arbitrarily precluded.
:mps:tag:`req.fun.align` The pool class must support aligned allocations to
client-specified alignments. An individual instance need only support
a single alignment; multiple instances may be used to support more
than one alignment (source: req.epcore.attr.align).
:mps:tag:`req.fun.reallocate` The pool class must support resizing of
allocated blocks (source req.epcore.fun.dl.promise.free,
req.product.dc.env.{ansi-c,cpp}).
:mps:tag:`non-req.fun.reallocate.in-place` There is not a requirement blocks
must be resized in place (where possible); but it seems like a good
idea.
:mps:tag:`req.fun.thread` Each instance of the pool class must support
multiple threads of allocation (source req.epcore.fun.dl.multi,
req.product.dc.env.{ansi-c,cpp}).
:mps:tag:`req.attr.performance` The pool class must meet or exceed
performance of "competitive" allocators (source:
rec.epcore.attr.{run-time,tp}, req.product.attr.{mkt.eval, perform}).
[Dylan does not seem to have any requirement that storage be allocated
with a particular response time or throughput, just so long as we
don't block for too long. Clearly there is a missing requirement.]
:mps:tag:`req.attr.performance.time` By inference, the time overhead must be
competetive.
:mps:tag:`req.attr.performance.space` By inference, the space overhead must
be competetive.
:mps:tag:`req.attr.reliability` The pool class must have "rock-solid
reliability" (source: req.dylan.attr.rel.mtbf, req.epcore.attr.rel,
req.product.attr.rel).
:mps:tag:`req.fun.range` The pool class must be able to manage blocks
ranging in size from 1 byte to all of addressable memory
(req.epcore.attr.{dl,gen,tmp,stat,cache,trap}.obj.{min,max}. The range
requirement may be satisfied by multiple instances each managing a
particular client-specified subrange of sizes. [Dylan has requirements
req.dylan.attr.{capacity,obj.max}, but no requirement that such
objects reside in a manual pool.]
:mps:tag:`req.fun.debug` The pool class must support debugging erroneous
usage by client programs (source: req.epcore.fun.{dc.variety,
debug.support}, req.product.attr.{mkt.eval,perform}). Debugging is
permitted to incur additional overhead.
:mps:tag:`req.fun.debug.boundaries` The pool class must support checking for
accesses outside the boundaries of live objects.
:mps:tag:`req.fun.debug.log` The pool class must support logging of all
allocations and deallocations.
:mps:tag:`req.fun.debug.enumerate` The pool class must support examining all
allocated objects.
:mps:tag:`req.fun.debug.free` The pool class must support detecting
incorrect, overlapping, and double frees.
:mps:tag:`req.fun.tolerant` The pool class must support tolerance of
erroneous usage (source req.product.attr.use.level.1).
Essential requirements
......................
:mps:tag:`req.fun.profile` The pool class should support memory usage
profiling (source: req.product.attr.{mkt.eval, perform}).
:mps:tag:`req.attr.flex` The pool class should be flexible so that it can be
tuned to specific allocation and freeing patterns (source:
req.product.attr.flex,req.epcore.attr.{dl,cache,trap}.typ). The
flexibility requirement may be satisfied by multiple instances each
optimizing a specific pattern.
:mps:tag:`req.attr.adapt` The pool class should be adaptive so that it can
accommodate changing allocation and freeing patterns (source:
req.epcore.fun.{tmp,stat}.policy,
req.product.attr.{mkt.eval,perform}).
Nice requirements
.................
:mps:tag:`req.fun.suballocate` The pool class may support freeing of any
aligned, contiguous subset of an allocated block (source
req.epcore.fun.dl.free.any, req.product.attr.{mkt.eval,perform}).
Architecture
------------
:mps:tag:`arch.overview` The pool has several layers: client allocation is
by Allocation Points (APs).
:mps:tag:`arch.overview.ap` APs acquire storage from the pool
available-block queue (ABQ).
:mps:tag:`arch.overview.abq` The ABQ holds blocks of a minimum configurable
size: "reuse size".
:mps:tag:`arch.overview.storage` The ABQ acquires storage from the arena,
and from its internal free block managers.
:mps:tag:`arch.overview.storage.contiguous` The arena storage is requested
to be contiguous to maximize opportunities for coalescing (Loci will
be used when available).
:mps:tag:`arch.overview.cbs` The free block managers hold blocks freed by
the client until, through coalescing, they have reached the reuse
size, at which point they are made available on the ABQ.
:mps:tag:`arch.ap` The pool will use allocation points as the allocation
interface to the client.
:mps:tag:`arch.ap.two-phase` Allocation points will request blocks from the
pool and suballocate those blocks (using the existing AP, compare and
increment, 2-phase mechanism) to satisfy client requests.
:mps:tag:`arch.ap.fill` The pool will have a configurable "fill size" that
will be the preferred size block used to fill the allocation point.
:mps:tag:`arch.ap.fill.size` The fill size should be chosen to amortize the
cost of refill over a number of typical reserve/commit operations, but
not so large as to exceed the typical object population of the pool.
:mps:tag:`arch.ap.no-fit` When an allocation does not fit in the remaining
space of the allocation point, there may be a remaining fragment.
:mps:tag:`arch.ap.no-fit.sawdust` If the fragment is below a configurable
threshold (minimum size), it will be left unused (but returned to the
free block managers so it will be reclaimed when adjacent objects are
freed).
:mps:tag:`arch.ap.no-fit.splinter` otherwise, the remaining fragment will be
(effectively) returned to the head of the available-block queue, so
that it will be used as soon as possible (that is, by objects of similar
birthdate).
:mps:tag:`arch.ap.no-fit.oversize` If the requested allocation exceeds the
fill size it is treated exceptionally (this may indicate the client
has either misconfigured or misused the pool and should either change
the pool configuration or create a separate pool for these exceptional
objects for best performance).
:mps:tag:`arch.ap.no-fit.oversize.policy` Oversize blocks are assumed to
have exceptional lifetimes, hence are allocated to one side and do not
participate in the normal storage recycling of the pool.
:mps:tag:`arch.ap.refill.overhead` If reuse size is small, or becomes small
due to :mps:ref:`.arch.adapt`, all allocations will effectively be treated
exceptionally (the AP will trip and a oldest-fit block will be chosen
on each allocation). This mode will be within a constant factor in
overhead of an unbuffered pool.
:mps:tag:`arch.abq` The available block queue holds blocks that have
coalesced sufficiently to reach reuse size.
:mps:tag:`arch.abq.reuse.size` A multiple of the quantum of virtual memory
is used as the reuse size (:mps:ref:`.anal.policy.size`).
:mps:tag:`arch.abq.fifo` It is a FIFO queue (recently coalesced blocks go to
the tail of the queue, blocks are taken from the head of the queue for
reuse).
:mps:tag:`arch.abq.delay-reuse` By thus delaying reuse, coalescing
opportunities are greater.
:mps:tag:`arch.abq.high-water` It has a configurable high water mark, which
when reached will cause blocks at the head of the queue to be returned
to the arena, rather than reused.
:mps:tag:`arch.abq.return` When the MPS supports it, the pool will be able
to return free blocks from the ABQ to the arena on demand.
:mps:tag:`arch.return.segment` arch.abq.return can be guaranteed to be able
to return a segment by setting reuse size to twice the size of the
segments the pool requests from the arena.
:mps:tag:`arch.cbs` The coalescing block structure holds blocks that have
been freed by the client.
:mps:tag:`arch.cbs.optimize` The data structure is optimized for coalescing.
:mps:tag:`arch.cbs.abq` When a block reaches reuse size, it is added to the
ABQ.
:mps:tag:`arch.cbs.data-structure` The data structures are organized so that
a block can be both in the free block managers and on the ABQ
simultaneously to permit additional coalescing, up until the time the
block is removed from the ABQ and assigned to an AP.
:mps:tag:`arch.fragmentation.internal` Internal fragmentation results from
The pool will request large segments from the arena to minimize the
internal fragmentation due to objects not crossing segment boundaries.
:mps:tag:`arch.modular` The architecture will be modular, to allow building
variations on the pool by assembling different parts.
:mps:tag:`arch.modular.example` For example, it should be possible to build
pools with any of the freelist mechanisms, with in-band or out-of-band
storage (where applicable), that do or do not support derived object
descriptions, etc.
:mps:tag:`arch.modular.initial` The initial architecture will use
:mps:ref:`.sol.mech.free-list` for the free block managers,
:mps:ref:`.sol.mech.storage.out-of-band`, :mps:ref:`.sol.mech.desc.derived`, and
:mps:ref:`.sol.mech.allocate.buffer`.
:mps:tag:`arch.segregate` The architecture will support segregated
allocation through the use of multiple allocation points. The client
will choose the appropriate allocation point either at run time, or
when possible, at compile time.
:mps:tag:`arch.segregate.initial` The initial architecture will segregate
allocations into two classes: large and small. This will be
implemented by creating two pools with different parameters.
:mps:tag:`arch.segregate.initial.choice` The initial architecture will
provide glue code to choose which pool to allocate from at run time.
If possible this glue code will be written in a way that a good
compiler can optimize the selection of pool at compile time.
Eventually this glue code should be subsumed by the client or
generated automatically by a tool.
:mps:tag:`arch.debug` Debugging features such as tags, fenceposts, types,
creators will be implemented in a layer above the pool and APs. A
generic pool debugging interface will be developed to support
debugging in this outer layer.
:mps:tag:`arch.debug.initial` The initial architecture will have counters
for objects/bytes allocated/freed and support for detecting
overlapping frees.
:mps:tag:`arch.dependency.loci` The architecture depends on the arena being
able to efficiently provide segments of varying sizes without
excessive fragmentation. The locus mechanism should satisfy this
dependency. (See :mps:ref:`.anal.strategy.risk`.)
:mps:tag:`arch.dependency.mfs` The architecture internal data structures
depend on efficient manual management of small, fixed-sized objects (2
different sizes). The MFS pool should satisfy this dependency.
:mps:tag:`arch.contingency` Since the strategy we propose is new, it may not
work.
:mps:tag:`arch.contingency.pathological` In particular, pathological
allocation patterns could result in fragmentation such that no blocks
recycle from the free bock managers to the ABQ.
:mps:tag:`arch.contingency.fallback` As a fallback, there will be a pool
creation parameter for a high water mark for the free space.
:mps:tag:`arch.contingency.fragmentation-limit` When the free space as a
percentage of all the memory managed by the pool (a measure of
fragmentation) reaches that high water mark, the free block managers
will be searched oldest-fit before requesting additional segments from
the arena.
:mps:tag:`arch.contingency.alternative` We also plan to implement
:mps:ref:`.mech.free-list.cartesian-tree` as an alternative free block manager,
which would permit more efficient searching of the free blocks.
:mps:tag:`arch.parameters` The architecture supports several parameters so
that multiple pools may be instantiated and tuned to support different
object cohorts. The important parameters are: reuse size, minimum
size, fill size, ABQ high water mark, free block fragmentation limit
(see :mps:ref:`.arch.contingency.fragmentation-limit`).
:mps:tag:`arch.parameters.client-visible` The client-visible parameters of
the pool are the minimum object size, the mean object size, the
maximum object size, the reserve depth and fragmentation limit. The
minimum object size determines when a splinter is kept on the head of
the ABQ (:mps:ref:`.arch.ap.no-fit.splinter`). The maximum object size
determines the fill size (:mps:ref:`.arch.ap.fill-size`) and hence when a
block is allocated exceptionally (:mps:ref:`.arch.ap.no-fit.oversize`). The
mean object size is the most likely object size. The reserve depth is
a measure of the hysteresis of the object population. The mean object
size, reserve depth and, maximum object size are used to determine the
size of the ABQ (:mps:ref:`.arch.abq.high-water`). The fragmentation limit is
used to determine when contingency mode is used to satisfy an
allocation request (:mps:ref:`.arch.contingency`).
:mps:tag:`arch.adapt` We believe that an important adaptation to explore is
tying the reuse size inversely to the fragmentation (as measured in
:mps:ref:`.arch.contingency.fragmentation-limit`).
:mps:tag:`arch.adapt.reuse` By setting reuse size low when fragmentation is
high, smaller blocks will be available for reuse, so fragmentation
should diminish.
:mps:tag:`arch.adapt.overhead` This will result in higher overhead as the AP
will need to be refilled more often, so reuse size should be raised
again as fragmentation diminishes.
:mps:tag:`arch.adapt.oldest-fit` In the limit, if reuse size goes to zero,
the pool will implement a "oldest-fit" policy: the oldest free block
of sufficient size will be used for each allocation.
:mps:tag:`arch.adapt.risk` This adaptation is an experimental policy and
should not be delivered to clients until thoroughly tested.
Analysis
--------
:mps:tag:`anal.discard` We have discarded many traditional solutions based
on experience and analysis in paper.wil95(1). In particular, managing
the free list as a linear list arranged by address or size and basing
policy on searching such a linear list in a particular direction, from
a particular starting point, using fit and/or immediacy as criteria.
We believe that none of these solutions is derived from considering
the root of the problem to be solved (as described in
:mps:ref:`.anal.strategy`), although their behavior as analyzed by Wilson
gives several insights.
:mps:tag:`anal.strategy` For any program to run in the minimum required
memory (with minimal overhead -- we discard solutions such as
compression for now), fragmentation must be eliminated. To eliminate
fragmentation, simply place blocks in memory so that they die "in
order" and can be immediately coalesced. This ideal is not achievable,
but we believe we can find object attributes that correlate with
deathtime and exploit them to approximate the ideal. Initially we
believe birth time and type (as approximated by size) will be useful
attributes to explore.
:mps:tag:`anal.strategy.perform` To meet :mps:ref:`.req.attr.performance`, the
implementation of :mps:ref:`.sol.strategy` must be competitive in both time
and space.
:mps:tag:`anal.strategy.risk` The current MPS segment substrate can cause
internal fragmentation which an individual pool can do nothing about.
We expect that `request.epcore.170193.sugg.loci`_ will be implemented to
remove this risk.
.. _`request.epcore.170193.sugg.loci`: https://info.ravenbrook.com/project/mps/import/2001-11-05/mmprevol/request/epcore/170193/
:mps:tag:`anal.policy` Deferred coalescing, when taken to the extreme will
not minimize the memory consumption of a program, as no memory would
ever be reused. Eager reuse appears to lead to more fragmentation,
whereas delayed reuse appears to reduce fragmentation
(paper.wil95(1)). The systems studied by Wilson did not directly
address deferring reuse. Our proposed policy is to reuse blocks when
they reach a (configurable) size. We believe that this policy along
with the policy of segregating allocations by death time, will greatly
reduce fragmentation.
:mps:tag:`anal.policy.risk` This policy could lead to pathological behavior
if allocations cannot be successfully segregated.
:mps:tag:`anal.policy.allocate.segregate` This policy has some similarities
to CustomAlloc (paper.grun92(1)). CustomAlloc segregates objects by
size classes, and then within those classes chooses a different
allocator depending on whether that size class has a stable or
unstable population. Classes with stable population recycle storage
within the class, whereas classes with unstable populations return
their storage to the general allocation pool for possible reuse by
another class. CustomAlloc, however, requires profiling the
application and tuning the allocator according to those profiles.
Although we intend to support such tuning, we do not want to require
it.
:mps:tag:`anal.policy.reallocate` For reallocation, :mps:ref:`.fun.suballocate` can
be used to free the remainder if a block is made smaller. Doing so
will cause the freed block to obey :mps:ref:`.sol.policy.allocate` (that is,
the freed block will not be treated specially, it will be subject to
the normal policy on reuse). Copying can be used if a block is made
larger. paper.vo96(0) reports success in over-allocating a block the
first time it is resized larger, presumably because blocks that are
resized once tend to be resized again and over-allocating may avoid a
subsequent copy. If each object that will be reallocated can be given
its own allocation point until its final reallocation, the allocation
point can be used to hold released or spare storage.
:mps:tag:`anal.policy.size` We believe that this will take advantage of the
underlying virtual memory system's ability to compact the physical
memory footprint of the program by discarding free fragments that
align with the virtual memory quantum. (In a VM system one can
approximate compaction by sparse mapping. If every other page of a
segment is unused, the unused pages can be unmapped, freeing up
physical memory that can be mapped to a new contiguous vm range.)
:mps:tag:`anal.mech.free-list` The literature (paper.grun92(1),
paper.vo96(0)) indicate that :mps:ref:`.sol.mech.free-list.cartesian-tree`
provides a space-efficient implementation at some cost in speed.
:mps:ref:`.sol.mech.free-list.splay-tree` is faster but less space-efficient.
:mps:ref:`.sol.mech.free-list.bitmap` is unstudied. Many of the faster
allocators maintain caches of free blocks by size to speed allocation
of "popular" sizes. We intend to initially explore not doing so, as we
believe that policy ultimately leads to fragmentation by mixing
objects of varying death times. Instead we intend to use a free list
mechanism to support fast coalescing, deferring reuse of blocks until
a minimum size has been reached.
:mps:tag:`anal.mech.allocate.optimize-small` Wilson (paper.wil95(1)) notes
that small blocks typically have short lifetimes and that overall
performance is improved if you optimize the management of small
blocks, e.g., :mps:ref:`.sol.mech.allocate.lookup-table` for all small blocks.
We believe that :mps:ref:`.sol.mech.allocate.buffer` does exactly that.
:mps:tag:`anal.mech.allocate.optimize-new` Wilson (paper.wil95(1)) reports
some benefit from "preserving wilderness", that is, when a block of
memory must be requested from the system to satisfy an allocation,
only the minimum amount of that block is used, the remainder is
preserved (effectively by putting it at the tail of the free list).
This mechanism may or may not implement :mps:ref:`.sol.policy.allocate`. We
believe a better mechanism is to choose to preserve or not, based on
:mps:ref:`.sol.policy.allocate`.
Ideas
-----
:mps:tag:`sol` Many solution ideas for manual management of variable-sized
memory blocks are enumerated by paper.wil95(1). Here we list the most
promising, and some of our own.
Strategy
........
:mps:tag:`sol.strategy` To run a program in the minimal required memory,
with minimal overhead, utilize memory efficiently. Memory becomes
unusable when fragmented. Strategy is to minimize fragmentation. So
place blocks where they won't cause fragmentation later.
:mps:tag:`sol.strategy.death` Objects that will die together (in time)
should be allocated together (in space); thus they will coalesce,
reducing fragmentation.
:mps:tag:`sol.strategy.death.birth` Assume objects allocated near each other
in time will have similar deathtimes (paper.beck82(0)).
:mps:tag:`sol.strategy.death.type` Assume objects of different type may have
different deathtimes, even if born together.
:mps:tag:`sol.strategy.death.predict` Find and use program features to predict deathtimes.
:mps:tag:`sol.strategy.reallocate` Reallocation implies rebirth, or at least
a change in lifetime
:mps:tag:`sol.strategy.debug` As much of the debugging functionality as
possible should be implemented as a generally available MPS utility;
the pool will provide support for debugging that would be expensive or
impossible to allocate outside the pool.
Policy
......
Policy is an implementable decision procedure, hopefully approximating
the strategy.
:mps:tag:`sol.policy.reuse` Defer reusing blocks, to encourage coalescing.
:mps:tag:`sol.policy.split` When a block is split to satisfy an allocation,
use the remainder as soon as possible.
:mps:tag:`sol.policy.size` Prevent :mps:ref:`.policy.reuse` from consuming all of
memory by choosing a (coalesced) block for reuse when it reaches a
minimum size.
:mps:tag:`sol.policy.size.fixed` Use the quantum of virtual memory (e.g.,
one page) as minimum size.
:mps:tag:`sol.policy.size.tune` Allow tuning minimum size.
:mps:tag:`sol.policy.size.adapt` Adaptively change minimum size.
:mps:tag:`sol.policy.allocate` Allocate objects with similar birthdate and
lifetime together.
:mps:tag:`sol.policy.allocate.segregate` Segregate allocations by type.
:mps:tag:`sol.policy.allocate.segregate.size` Use size as a substitute for type.
:mps:tag:`sol.policy.allocate.segregate.tune` Permit tuning of segregation.
:mps:tag:`sol.policy.allocate.segregate.adapt` Adaptively segregate allocations.
:mps:tag:`sol.policy.reallocate` Implement reallocation in a central
mechanism outside of the pool, create a generic pool interface in
support of same.
:mps:tag:`sol.policy.debug` Implement a pool debugging interface.
:mps:tag:`sol.policy.debug.counters` Implement debugging counters in the
pool that are queried with a generic interface.
:mps:tag:`sol.policy.debug.verify` Implement debugging error returns on
overlapping frees.
Mechanism
.........
Mechanisms are algorithms or data structures used to implement policy.
:mps:tag:`sol.mech.free-list` Mechanisms that can be used to describe the
free list.
:mps:tag:`sol.mech.free-list.cartesian-tree` Using address and size as keys
supports fast coalescing of adjacent blocks and fast searching for
optimal-sized blocks. Unfortunately, because the shape of the tree is
constrained by the second key, it can become unbalanced. This data
structure is used in the SunOS 4.1 malloc (paper.grun92(1)).
:mps:tag:`sol.mech.free-list.splay-tree` The amortized cost of a splay tree
is competitive with balanced binary trees in the worst case, but can
be significantly better for regular patterns of access because
recently-accessed keys are moved to the root of the tree and hence can
be re-accessed quickly. This data structure is used in the System Vr4
malloc (paper.vo96(0)). (For a complete analysis of the splay tree
algorithm time bounds see paper.st85(0).)
:mps:tag:`sol.mech.free-list.bit-map` Using address as an index and
fix-sized blocks, the booleans can represent whether a block is free
or not. Adjacent blocks can be used to construct larger blocks.
Efficient algorithms for searching for runs in a vector are known.
This data structure is used in many file system disk block managers.
:mps:tag:`sol.mech.free-list.refcount` A count of the number of allocated
but not freed subblocks of a block can be used to determine when a
block is available for reuse. This is an extremely compact data
structure, but does not support subblock reuse.
:mps:tag:`sol.mech.free-list.hybrid` Bitmaps appear suited particularly to
managing small, contiguous blocks. The tree structures appear suited
particularly to managing varying-sized, discontiguous blocks. A
refcount can be very efficient if objects can be placed accurately
according to death time. A hybrid mechanism may offer better
performance for a wider range of situations.
:mps:tag:`sol.mech.free-list.linked` An address-ordered singly linked free
list using space in each free block to store the block's size and a
pointer to the next block.
:mps:tag:`sol.mech.storage` Methods that can be used to store the free list description.
:mps:tag:`sol.mech.storage.in-band` The tree data structures (and
:mps:ref:`.sol.mech.free-list.linked`) are amenable to being stored in the
free blocks themselves, minimizing the space overhead of management.
To do so imposes a minimum size on free blocks and reduces the
locality of the data structure.
:mps:tag:`sol.mech.storage.out-of-band` The bit-map data structure must be
stored separately.
:mps:tag:`sol.mech.desc` for an allocated block to be freed, its base and
bound must be known
:mps:tag:`sol.mech.desc.derived` Most clients can supply the base of the
block. Some clients can supply the bound.
:mps:tag:`sol.mech.desc.in-band` When the bound cannot be supplied, it can
be stored as an in-band "header". If neither the base nor bound can be
supplied (e.g., the client may only have an interior pointer to the
block), a header and footer may be required.
:mps:tag:`sol.mech.desc.out-of-band` In un-tagged architectures, it may be
necessary to store the header and footer out-of-band to distinguish
them from client data. Out-of-band storage can improve locality and
reliability. Any of the free-list structures can also be used to
describe allocated blocks out-of-band.
:mps:tag:`sol.mech.desc.crossing-map` An alternative for untagged
architectures is to store a "crossing map" which records an encoding
of the start of objects and then store the descriptive information
in-band.
:mps:tag:`sol.mech.allocate` Mechanisms that can be used to allocate blocks
(these typically sit on top of a more general free-list manager).
:mps:tag:`sol.mech.allocate.lookup-table` Use a table of popular sizes to
cache free blocks of those sizes.
:mps:tag:`sol.mech.allocate.buffer` Allocate from contiguous blocks using
compare and increment.
:mps:tag:`sol.mech.allocate.optimize-small` Use a combination of techniques
to ensure the time spent managing a block is small relative to the
block's lifetime; assume small blocks typically have short lifetimes.
:mps:tag:`sol.mech.allocate.optimize-new` When "virgin" memory is acquired
from the operating system to satisfy a request, try to preserve it
(that is, use only what is necessary).
:mps:tag:`sol.mech.allocate.segregate.size` Use size as a substitute for
type.
:mps:tag:`sol.mech.reallocate` use :mps:ref:`.req.fun.suballocate` to return unused
memory when a block shrinks, but differentiate this from an erroneous
overlapping free by using separate interfaces.
Implementation
--------------
The implementation consists of the following separable modules:
Coalescing Block Structure
..........................
:mps:tag:`impl.c.cbs` The initial implementation will use
:mps:ref:`.sol.mech.free-list.splay-tree` and
:mps:ref:`.sol.mech.storage.out-of-band`. For locality, this storage should be
managed as a linked free list of splay nodes suballocated from blocks
acquired from a pool shared by all CBS's. Must support creation and
destruction of an empty tree. Must support search, insert and delete
by key of type Addr. Must support finding left and right neighbors of
a failed search for a key. Must support iterating over the elements of
the tree with reasonable efficiency. Must support storing and
retrieving a value of type Size associated with the key. Standard
checking and description should be provided. See design.mps.splay(0)
and design.mps.cbs(0).
Fail-over to address-ordered free list
......................................
:mps:tag:`impl.c.freelist` Because the CBS uses out-of-band storage, it may
be unable to handle insert (design.mps.cbs.function.cbs.insert.fail)
and delete (design.mps.cbs.function.cbs.delete.fail) operations. When
this happen MVT fails over to an address-ordered singly linked free
list. This uses in-band storage and so cannot run out of memory, but
it has much worse performance than the CBS. Therefore MVT eagerly
attempts to flush blocks from the free list back to the CBS. See
design.mps.freelist for the design and implementation of the free
list.
Available Block Queue
.....................
:mps:tag:`impl.c.abq` The initial implementation will be a queue of fixed
size (determined at pool creation time from the high water mark). Must
support creation and destruction of an empty queue. Must support
insertion at the head or tail of the queue (failing if full), peeking
at the head of the queue, and removal of the head (failing if empty)
or any element of the queue (found by a search). Standard checking and
description should be provided. See design.mps.abq.
Pool implementation
...................
:mps:tag:`impl.c` The initial implementation will use the above modules to
implement a buffered pool. Must support creation and destruction of
the pool. Creation takes parameters: minimum size, mean size, maximum
size, reserve depth and fragmentation limit. Minimum, mean, and
maximum size are used to calculate the internal fill and reuse sizes.
Reserve depth and mean size are used to calculate the ABQ high water
mark. Fragmentation limit is used to set the contingency mode. Must
support buffer initialization, filling and emptying. Must support
freeing. Standard checking and description should be provided.
[Eventually, it should support scanning, so it can be used with
collected pools, but no manual pool currently does.]
:mps:tag:`impl.c.future` The implementation should not preclude "buffered
free" (mail.ptw.1997-12-05.19-07(0), ff.) being added in the future.
:mps:tag:`impl.c.parameters` The pool parameters are calculated as follows
from the input parameters: minimum, mean, and maximum size are taked
directly from the parameters.
:mps:tag:`impl.c.parameter.fill-size` The fill size is set to the maximum
size times the reciprocal of the fragmentation limit, aligned to the
arena alignment.
:mps:tag:`imple.c.parameter.reuse-size` The reuse size is set to twice the
fill size (see :mps:ref:`.arch.abq.return.segment`,
:mps:ref:`.impl.c.free.merge.segment`).
:mps:tag:`impl.c.parameter.abq-limit` The ABQ high-water limit is set to the
reserve depth times the mean size (that is, the queue should hold as
many reuse blocks as would take to cover the population hysteresis if
the population consisted solely of mean-sized blocks, see
:mps:ref:`.arch.abq.high-water`).
:mps:tag:`impl.c.parameter.avail-limit` The free block high-water limit is
implemented by comparing the available free space to an "available
limit". The available limit is updated each time a segment is
allocated from or returned to the arena by setting it to the total
size of the pool times the fragmentation limit divide vy 100 (see
:mps:ref:`.arch.contingency.fallback`).
:mps:tag:`impl.c.ap.fill` An AP fill request will be handled as follows:
- If the request is larger than fill size, attempt to request a
segment from the arena sufficient to satisfy the request.
- Use any previously returned splinter (from :mps:ref:`.impl.c.ap.empty`), if
large enough.
- Attempt to retrieve a free block from the head of the ABQ (removing
it from ABQ and the free block managers if found).
- If above fragmentation limit, attempt to find a block in the free
block managers, using oldest-fit search.
- Attempt to request a segment of fill size from the arena.
- Attempt to find a block in the free block managers, using oldest-fit
search.
- Otherwise, fail.
:mps:tag:`impl.c.ap.empty` An AP empty request will be handled as follows:
- If remaining free is less than min size, return it to the free block
managers.
- If the remaining free is larger than any previous splinter, return
that splinter to the free block managers and save this one for use
by a subsequent fill.
- Otherwise return the remaining block to the free block managers.
:mps:tag:`impl.c.free` When blocks are returned to the free block managers
they may be merged with adjacent blocks. If a merge occurs with a
block on the ABQ, the ABQ must be adjusted to reflect the merge.
:mps:tag:`impl.c.free.exception` Exceptional blocks are returned directly to
the arena.
:mps:tag:`impl.c.free.merge` If a merge occurs and the merged block is
larger than reuse size:
- If the ABQ is full, remove the block at the head of the ABQ from the
ABQ and the free block managers and return it to the arena(*).
- Insert the newly merged block at the tail of the ABQ, leaving it in
the free block managers for further merging.
:mps:tag:`impl.c.free.merge.segment` (*) Merged blocks may not align with
arena segments. If necessary, return the interior segments of a block
to the arena and return the splinters to the free block managers.
:mps:tag:`impl.c.free.merge.segment.reuse` If the reuse size (the size at
which blocks recycle from the free block managers to the ABQ) is at
least twice the fill size (the size of segments the pool allocates
from the arena), we can guarantee that there will always be a
returnable segment in every ABQ block.
:mps:tag:`impl.c.free.merge.segment.overflow` If the reuse size is set
smaller (see :mps:ref:`.arch.adapt`), there may not be a returnable segment in
an ABQ block, in which case the ABQ has "overflowed". Whenever this
occurs, the ABQ will be refilled by searching the free block managers
for dropped reusable blocks when needed.
:mps:tag:`impl.c.free.merge.segment.risk` The current segment structure does
not really support what we would like to do. Loci should do better:
support reserving contiguous address space and mapping/unmapping any
portion of that address space.
:mps:tag:`impl.c.free.merge.alternative` Alternatively, if the MPS segment
substrate permitted mapping/unmapping of pages, the pool could use
very large segments and map/unmap pages as needed.
AP Dispatch
...........
:mps:tag:`impl.c.multiap` The initial implementation will be a glue layer
that selects among several AP's for allocation according to the
predicted deathtime (as approximated by size) of the requested
allocation. Each AP will be filled from a pool instance tuned to the
range of object sizes expected to be allocated from that AP. [For
bonus points provide an interface that creates a batch of pools and
AP's according to some set of expected object sizes. Eventually expand
to understand object lifetimes and general lifetime prediction keys.]
:mps:tag:`impl.c.multiap.sample-code` This glue code is not properly part of
the pool or MPS interface. It is a layer on top of the MPS interface,
intended as sample code for unsophisticated clients. Sophisticated
clients will likely want to choose among multiple AP's more directly.
Testing
-------
:mps:tag:`test.component` Components :mps:ref:`.impl.c.splay`, :mps:ref:`.impl.c.cbs`, and
:mps:ref:`.impl.c.abq` will be subjected to individual component tests to
verify their functionality.
:mps:tag:`test.regression` All tests applied to poolmv
(design.mps.poolmv(0)) and poolepdl (design.mps.poolepdl(0)) will be
applied to poolmvt to ensure that mvt is at least as functional as the
pools it is replacing.
:mps:tag:`test.qa` Once poolmvt is integrated into the MPS, the standard MPS
QA tests will be applied to poolmvt prior to each release.
:mps:tag:`test.customer` Customer acceptance tests will be performed on a
per-customer basis before release to that customer (cf.
proc.release.epcore(2).test)
Text
----
Possible tweaks (from mail.pekka.1998-04-15.13-10(0)):
- Try to coalesce splinters returned from AP's with the front (or any)
block on the ABQ.
- Sort ABQ in some other way to minimize splitting/splinters. For
example, proximity to recently allocated blocks.

View file

@ -0,0 +1,87 @@
.. _design-range:
Ranges
======
.. mps:prefix:: design.mps.range
Introduction
------------
:mps:tag:`intro` This is the design of the Range module, which implements
objects representing address ranges.
_`readership`: This document is intended for any MPS developer.
Requirements
------------
_`.req.range` A range object must be able to represent an arbitrary
range of addresses that does not include the top grain of the address
space.
_`.req.empty` A range object must be able to represent the empty
range.
_`.req.stack-alloc` It must be possible to allocate range objects on
the stack: that is, they do not require any heap resource.
Interface
---------
.. c:type:: RangeStruct *Range
``Range`` is the type of a range. It is an alias for ``RangeStruct *``. :c:type:`RangeStruct` is defined in the header so that it can be
inlined in client structures or allocated on the stack. Clients must
not depend on its implementation details.
.. c:function:: void RangeInit(Range range, Addr base, Addr limit)
Initialize a range object to represent the half-open address range
between ``base`` (inclusive) and ``limit`` (exclusive). It must be the
case that ``base <= limit``. If ``base == limit`` then the range is
empty.
.. c:function:: void RangeFinish(Range range)
Finish a range object. Because a range object uses no heap resources
(:mps:ref:`.req.stack-alloc`) it is not necessary to call this. However,
clients may wish to do so in order to ensure that the range object is
invalid.
.. c:function:: Addr RangeBase(Range range)
Return the base of the range. (This is implemented as a macro, but
there is a function too.)
.. c:function:: Addr RangeLimit(Range range)
Return the limit of the range. (This is implemented as a macro, but
there is a function too.)
.. c:function:: Size RangeSize(Range range)
Return the size of the range. (This is implemented as a macro, but
there is a function too. The macro evaluates its argument twice.)
.. c:function:: Bool RangeIsAligned(Range range, Align alignment)
Return :c:macro:`TRUE` if the base and limit of the range are both aligned to
the given alignment, or :c:macro:`FALSE` if either is not.
.. c:function:: Bool RangesOverlap(Range range1, Range range2)
Return :c:macro:`TRUE` if the two ranges overlap (have at least one address
in common), or :c:macro:`FALSE` if they do not. Note that ranges [*A*, *B*) and
[*B*, *C*) do not overlap.
.. c:function:: Bool RangesNest(Range outer, Range inner)
Return :c:macro:`TRUE` if all addresses in ``inner`` are also in ``outer``,
or :c:macro:`FALSE` otherwise.

View file

@ -1,2 +0,0 @@
* `Ravenbrook <http://www.ravenbrook.com/>`_
* `Google <http://www.google.com/>`_

View file

@ -1,33 +0,0 @@
.. _glossary:
Memory Management Glossary
**************************
.. include:: alphabet.txt
.. toctree::
:maxdepth: 1
a
b
c
d
e
f
g
h
i
k
l
m
n
o
p
q
r
s
t
u
v
w
z

View file

@ -101,7 +101,7 @@ May contain exact references? [4]_ yes --- yes yes ---
May contain ambiguous references? [4]_ no --- no no --- --- --- --- --- no
May contain weak references? [4]_ no --- no yes --- --- --- --- --- no
Allocations fixed or variable in size? var var var var var fixed var var var var
Alignment? [5]_ conf conf conf conf conf [6]_ [6]_ [7]_ [6]_ conf
Alignment? [5]_ conf conf conf conf conf [6]_ [6]_ [7]_ [7]_ conf
Dependent objects? [8]_ no --- no yes --- --- --- --- --- no
May use remote references? [9]_ no --- no no --- --- --- --- --- no
Blocks are automatically managed? [10]_ yes yes yes yes yes no no no no no
@ -137,12 +137,13 @@ Blocks may use :term:`in-band headers`? yes yes yes yes yes
.. [5] "Alignment" is "conf" if the client program may specify
:term:`alignment` for each pool.
.. [6] The alignment of blocks allocated from :ref:`pool-mv` and
:ref:`pool-mvt` pools is platform-dependent.
.. [6] The alignment of blocks allocated from :ref:`pool-mv` pools
is platform-dependent.
.. [7] :ref:`pool-mvff` pools have configurable alignment, but it
may not be smaller than the :term:`natural alignment` for
the :term:`platform` (see :c:macro:`MPS_PF_ALIGN`).
.. [7] :ref:`pool-mvt` and :ref:`pool-mvff` pools have
configurable alignment, but it may not be smaller than the
:term:`natural alignment` for the :term:`platform` (see
:c:macro:`MPS_PF_ALIGN`).
.. [8] In pools with this property, each object may specify an
:term:`dependent object` which the client program

View file

@ -113,7 +113,15 @@ MVT interface
Temporal) :term:`pool`.
When creating an MVT pool, :c:func:`mps_pool_create_k` may take
five :term:`keyword arguments`:
six :term:`keyword arguments`:
* :c:macro:`MPS_KEY_ALIGN` (type :c:type:`mps_align_t`, default is
smallest general purpose alignment for the architecture) 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 *)``.
* :c:macro:`MPS_KEY_MIN_SIZE` (type :c:type:`size_t`, default is
smallest general purpose alignment for the architecture) is the
@ -130,9 +138,9 @@ MVT interface
this; doing so will result in the storage of the block never
being reused.
These three arguments are *hints* to the MPS: the pool will be
less efficient if they are wrong, but the only thing that will
break is the partial freeing of large blocks.
The three ``SIZE`` arguments above are *hints* to the MPS: the
pool will be less efficient if they are wrong, but the only thing
that will break is the partial freeing of large blocks.
* :c:macro:`MPS_KEY_MVT_RESERVE_DEPTH` (type
:c:type:`mps_count_t`) is the expected hysteresis of the

View file

@ -83,8 +83,11 @@ a.mpstag:hover {
color: #FFFFFF;
}
p.logo {
text-align: center;
}
img.logo {
width: 100%;
width: 75%;
}
div.sphinxsidebar {

View file

@ -0,0 +1,232 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>1. Queue design &mdash; Memory Pool System 1.111.0 documentation</title>
<link rel="stylesheet" href="../_static/mps.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../',
VERSION: '1.111.0',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<link rel="copyright" title="Copyright" href="../copyright.html" />
<link rel="top" title="Memory Pool System 1.111.0 documentation" href="../index.html" />
<link rel="up" title="Design" href="index.html" />
<link rel="next" title="2. Coalescing block structure" href="cbs.html" />
<link rel="prev" title="Design" href="index.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="cbs.html" title="2. Coalescing block structure"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="index.html" title="Design"
accesskey="P">previous</a> |</li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
<li><a href="index.html" accesskey="U">Design</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="queue-design">
<span id="design-abq"></span><h1>1. Queue design<a class="headerlink" href="#queue-design" title="Permalink to this headline"></a></h1>
<div class="section" id="introduction">
<span id="design.mps.abq"></span><h2>1.1. Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.abq.intro"></span><a class="mpstag reference internal" href="#design.mps.abq.intro">.intro:</a> This is the design of the ABQ module, which implements a
fixed-length queue of small objects.</p>
<p><span class="target" id="design.mps.abq.readership"></span><a class="mpstag reference internal" href="#design.mps.abq.readership">.readership:</a> This document is intended for any MM developer.</p>
<p><span class="target" id="design.mps.abq.name"></span><a class="mpstag reference internal" href="#design.mps.abq.name">.name:</a> The name ABQ originally stood for &#8220;Available Block Queue&#8221; as
the module is used by the MVT pool.</p>
</div>
<div class="section" id="requirements">
<h2>1.2. Requirements<a class="headerlink" href="#requirements" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.abq.req.push"></span><a class="mpstag reference internal" href="#design.mps.abq.req.push">.req.push:</a> Clients can efficiently push new elements onto the queue.</p>
<p><span class="target" id="design.mps.abq.req.pop"></span><a class="mpstag reference internal" href="#design.mps.abq.req.pop">.req.pop:</a> Clients can efficiently pop elements from the queue.</p>
<p><span class="target" id="design.mps.abq.req.empty"></span><a class="mpstag reference internal" href="#design.mps.abq.req.empty">.req.empty:</a> Clients can efficiently test whether the queue is empty.</p>
<p><span class="target" id="design.mps.abq.req.abstract"></span><a class="mpstag reference internal" href="#design.mps.abq.req.abstract">.req.abstract:</a> The ABQ module does not know anything about the
elements in the queue other than their size.</p>
<p><span class="target" id="design.mps.abq.req.delete"></span><a class="mpstag reference internal" href="#design.mps.abq.req.delete">.req.delete:</a> Clients can delete elements from the queue. (Note: not necessarily efficiently.)</p>
<p><span class="target" id="design.mps.abq.req.iterate"></span><a class="mpstag reference internal" href="#design.mps.abq.req.iterate">.req.iterate:</a> Clients can iterate over elements in the queue.</p>
</div>
<div class="section" id="interface">
<h2>1.3. Interface<a class="headerlink" href="#interface" title="Permalink to this headline"></a></h2>
<dl class="type">
<dt id="ABQ">
ABQStruct *<tt class="descname">ABQ</tt><a class="headerlink" href="#ABQ" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p><a class="reference internal" href="#ABQ" title="ABQ"><tt class="xref c c-macro docutils literal"><span class="pre">ABQ</span></tt></a> is the type of a queue. It is an alias for <tt class="docutils literal"><span class="pre">ABQStruct</span> <span class="pre">*</span></tt>.
<tt class="xref c c-type docutils literal"><span class="pre">ABQStruct</span></tt> is defined in the header so that it can be inlined in
client structures: clients must not depend on its implementation
details.</p>
<dl class="function">
<dt id="ABQInit">
<tt class="descname">ABQInit</tt><big>(</big><a class="reference internal" href="arena.html#Arena" title="Arena">Arena</a><em>&nbsp;arena</em>, <a class="reference internal" href="#ABQ" title="ABQ">ABQ</a><em>&nbsp;abq</em>, void<em>&nbsp;*owner</em>, <a class="reference internal" href="type.html#Count" title="Count">Count</a><em>&nbsp;elements</em>, <a class="reference internal" href="type.html#Size" title="Size">Size</a><em>&nbsp;elementSize</em><big>)</big><a class="headerlink" href="#ABQInit" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p>Initialize the queue <tt class="docutils literal"><span class="pre">abq</span></tt>. The parameter <tt class="docutils literal"><span class="pre">arena</span></tt> is the arena
whose control pool should be used to allocate the memory for the
queue; <tt class="docutils literal"><span class="pre">owner</span></tt> is passed to <tt class="xref c c-func docutils literal"><span class="pre">MeterInit()</span></tt> for the statistics;
<tt class="docutils literal"><span class="pre">elements</span></tt> is the maximum number of elements that can be stored in
the queue; and <tt class="docutils literal"><span class="pre">elementSize</span></tt> is the size of each element.</p>
<dl class="function">
<dt id="ABQFinish">
void <tt class="descname">ABQFinish</tt><big>(</big><a class="reference internal" href="arena.html#Arena" title="Arena">Arena</a><em>&nbsp;arena</em>, <a class="reference internal" href="#ABQ" title="ABQ">ABQ</a><em>&nbsp;abq</em><big>)</big><a class="headerlink" href="#ABQFinish" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p>Finish <tt class="docutils literal"><span class="pre">abq</span></tt> and free all resources associated with it.</p>
<dl class="function">
<dt id="ABQPush">
<a class="reference internal" href="type.html#Res" title="Res">Res</a> <tt class="descname">ABQPush</tt><big>(</big><a class="reference internal" href="#ABQ" title="ABQ">ABQ</a><em>&nbsp;abq</em>, void<em>&nbsp;*element</em><big>)</big><a class="headerlink" href="#ABQPush" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p>If the queue is full, leave it unchanged and return <tt class="docutils literal"><span class="pre">ResFAIL</span></tt>.
Otherwise, push <tt class="docutils literal"><span class="pre">element</span></tt> on to the queue and return <tt class="docutils literal"><span class="pre">ResOK</span></tt>.</p>
<dl class="function">
<dt id="ABQPop">
<a class="reference internal" href="type.html#Res" title="Res">Res</a> <tt class="descname">ABQPop</tt><big>(</big><a class="reference internal" href="#ABQ" title="ABQ">ABQ</a><em>&nbsp;abq</em>, void<em>&nbsp;*elementReturn</em><big>)</big><a class="headerlink" href="#ABQPop" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p>If the queue is empty, return <tt class="docutils literal"><span class="pre">ResFAIL</span></tt>. Othwreise, copy the first
element on the queue into the memory pointed to by <tt class="docutils literal"><span class="pre">elementReturn</span></tt>,
remove the element from the queue, and return <tt class="docutils literal"><span class="pre">ResOK</span></tt>.</p>
<dl class="function">
<dt id="ABQPeek">
<a class="reference internal" href="type.html#Res" title="Res">Res</a> <tt class="descname">ABQPeek</tt><big>(</big><a class="reference internal" href="#ABQ" title="ABQ">ABQ</a><em>&nbsp;abq</em>, void<em>&nbsp;*elementReturn</em><big>)</big><a class="headerlink" href="#ABQPeek" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p>If the queue is empty, return <tt class="docutils literal"><span class="pre">ResFAIL</span></tt>. Otherwise, copy the first
element on the queue into the memory pointed to by <tt class="docutils literal"><span class="pre">elementReturn</span></tt>
and return <tt class="docutils literal"><span class="pre">ResOK</span></tt>. (This is the same as <a class="reference internal" href="#ABQPop" title="ABQPop"><tt class="xref c c-func docutils literal"><span class="pre">ABQPop()</span></tt></a> except that
the queue is unchanged.)</p>
<dl class="function">
<dt id="ABQIsEmpty">
<a class="reference internal" href="type.html#Bool" title="Bool">Bool</a> <tt class="descname">ABQIsEmpty</tt><big>(</big><a class="reference internal" href="#ABQ" title="ABQ">ABQ</a><em>&nbsp;abq</em><big>)</big><a class="headerlink" href="#ABQIsEmpty" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p>If the queue is empty, return <tt class="xref c c-macro docutils literal"><span class="pre">TRUE</span></tt>, otherwise return <tt class="xref c c-macro docutils literal"><span class="pre">FALSE</span></tt>.</p>
<dl class="function">
<dt id="ABQIsFull">
<a class="reference internal" href="type.html#Bool" title="Bool">Bool</a> <tt class="descname">ABQIsFull</tt><big>(</big><a class="reference internal" href="#ABQ" title="ABQ">ABQ</a><em>&nbsp;abq</em><big>)</big><a class="headerlink" href="#ABQIsFull" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p>If the queue is full, return <tt class="xref c c-macro docutils literal"><span class="pre">TRUE</span></tt>, otherwise return <tt class="xref c c-macro docutils literal"><span class="pre">FALSE</span></tt>.</p>
<dl class="function">
<dt id="ABQDepth">
<a class="reference internal" href="type.html#Count" title="Count">Count</a> <tt class="descname">ABQDepth</tt><big>(</big><a class="reference internal" href="#ABQ" title="ABQ">ABQ</a><em>&nbsp;abq</em><big>)</big><a class="headerlink" href="#ABQDepth" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p>Return the number of elements in the queue.</p>
<dl class="type">
<dt id="ABQIterateMethod">
<a class="reference internal" href="type.html#Bool" title="Bool">Bool</a> <tt class="descname">(*ABQIterateMethod)</tt><big>(</big><a class="reference internal" href="type.html#Bool" title="Bool">Bool</a><em>&nbsp;*deleteReturn</em>, void<em>&nbsp;*element</em>, void<em>&nbsp;*closureP</em>, <a class="reference internal" href="type.html#Size" title="Size">Size</a><em>&nbsp;closureS</em><big>)</big><a class="headerlink" href="#ABQIterateMethod" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p>A callback function for <a class="reference internal" href="#ABQIterate" title="ABQIterate"><tt class="xref c c-func docutils literal"><span class="pre">ABQIterate()</span></tt></a>. The parameter <tt class="docutils literal"><span class="pre">element</span></tt> is
an element in the queue, and <tt class="docutils literal"><span class="pre">closureP</span></tt> and <tt class="docutils literal"><span class="pre">closureS</span></tt> are the
values that were originally passed to <a class="reference internal" href="#ABQIterate" title="ABQIterate"><tt class="xref c c-func docutils literal"><span class="pre">ABQIterate()</span></tt></a>. This function
must set <tt class="docutils literal"><span class="pre">*deleteReturn</span></tt> to <tt class="xref c c-macro docutils literal"><span class="pre">FALSE</span></tt> if <tt class="docutils literal"><span class="pre">element</span></tt> must be kept in
the queue, or <tt class="xref c c-macro docutils literal"><span class="pre">TRUE</span></tt> if <tt class="docutils literal"><span class="pre">element</span></tt> must be deleted from the queue.
It must return <tt class="xref c c-macro docutils literal"><span class="pre">TRUE</span></tt> if the iteration must continue, or <tt class="xref c c-macro docutils literal"><span class="pre">FALSE</span></tt>
if the iteration must stop after processing <tt class="docutils literal"><span class="pre">element</span></tt>.</p>
<dl class="function">
<dt id="ABQIterate">
void <tt class="descname">ABQIterate</tt><big>(</big><a class="reference internal" href="#ABQ" title="ABQ">ABQ</a><em>&nbsp;abq</em>, <a class="reference internal" href="#ABQIterateMethod" title="ABQIterateMethod">ABQIterateMethod</a><em>&nbsp;iterate</em>, void<em>&nbsp;*closureP</em>, <a class="reference internal" href="type.html#Size" title="Size">Size</a><em>&nbsp;closureS</em><big>)</big><a class="headerlink" href="#ABQIterate" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p>Call <tt class="docutils literal"><span class="pre">iterate</span></tt> for each elements in the queue, passing the element
and <tt class="docutils literal"><span class="pre">closureP</span></tt>. See <a class="reference internal" href="#ABQIterateMethod" title="ABQIterateMethod"><tt class="xref c c-type docutils literal"><span class="pre">ABQIterateMethod</span></tt></a> for details.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../index.html">
<img class="logo" src="../_static/logo.png" alt="Logo"/>
</a></p>
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">1. Queue design</a><ul>
<li><a class="reference internal" href="#introduction">1.1. Introduction</a></li>
<li><a class="reference internal" href="#requirements">1.2. Requirements</a></li>
<li><a class="reference internal" href="#interface">1.3. Interface</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="index.html"
title="previous chapter">Design</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="cbs.html"
title="next chapter">2. Coalescing block structure</a></p><h4>Downloads</h4>
<p class="topless">
<a href="http://www.ravenbrook.com/project/mps/release/1.111.0/">MPS Kit release 1.111.0</a><br>
<a href="http://www.ravenbrook.com/project/mps/release/">All MPS Kit releases</a>
</p>
<h4>Issues</h4>
<p class="topless">
<a href="http://www.ravenbrook.com/project/mps/issue/?action=list&amp;view=status%3dopen&amp;display=Job:Priority:Title&amp;sort=Priority">Known issues</a><br>
<a href="http://www.ravenbrook.com/project/mps/issue/?action=fixed&release_fixed=1.111.0">Issues fixed in release 1.111.0</a>
</p><h4>Contact us</h4>
<p class="topless"><a href="mailto:mps-questions@ravenbrook.com">mps-questions@ravenbrook.com</a></p>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="cbs.html" title="2. Coalescing block structure"
>next</a> |</li>
<li class="right" >
<a href="index.html" title="Design"
>previous</a> |</li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
<li><a href="index.html" >Design</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; <a href="../copyright.html">Copyright</a> 2013, Ravenbrook Limited.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

View file

@ -8,7 +8,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>&lt;no title&gt; &mdash; Memory Pool System 1.111.0 documentation</title>
<title>The MPS Bootstrap &mdash; Memory Pool System 1.111.0 documentation</title>
<link rel="stylesheet" href="../_static/mps.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
@ -44,10 +44,34 @@
<div class="bodywrapper">
<div class="body">
<ul class="simple">
<li><a class="reference external" href="http://www.ravenbrook.com/">Ravenbrook</a></li>
<li><a class="reference external" href="http://www.google.com/">Google</a></li>
</ul>
<div class="section" id="the-mps-bootstrap">
<span id="design-boot"></span><h1>The MPS Bootstrap<a class="headerlink" href="#the-mps-bootstrap" title="Permalink to this headline"></a></h1>
<div class="section" id="introduction">
<span id="design.mps.boot"></span><h2>Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline"></a></h2>
<p>The <a href="#id1"><span class="problematic" id="id2">`Memory Pool System`_</span></a> starts with no memory, but must somehow
allocate its own control structures in order to provide memory to the
client program. The MPS is freestanding [ref?] and so it can&#8217;t get its
memory from the C library&#8217;s <tt class="docutils literal"><span class="pre">malloc</span></tt>. So how does it get off the
ground? It pulls itself up by its own bootstraps. This document
describes how.</p>
<div class="admonition-note admonition">
<p class="first admonition-title">Note</p>
<p class="last">This document was written as a prelude to reforming the bootstrap,
so it shouldn&#8217;t be taken as advocating it as an amazing piece of
design.</p>
</div>
<p>Pretty much the first call to the MPS is to <tt class="docutils literal"><span class="pre">ArenaCreate</span></tt>, which calls the
arena class specific <tt class="docutils literal"><span class="pre">init</span></tt> method. That must create an initialized arena,
except for the &#8220;control pool&#8221;, from which many MPS data structures will be
allocated.</p>
<p>In the case of the VM arena, <tt class="docutils literal"><span class="pre">VMArenaInit</span></tt> creates a VM large enough to hold
a <tt class="xref c c-type docutils literal"><span class="pre">VMArenaStruct</span></tt> (which contains the generic <tt class="xref c c-type docutils literal"><span class="pre">ArenaStruct</span></tt>) and maps
pages into it. It then calls <tt class="docutils literal"><span class="pre">ArenaInit</span></tt> to initialise the generic part,
before filling in the VM-specific part. Having done that, it adds the initial
<tt class="docutils literal"><span class="pre">VMChunk</span></tt> &#8211; a large area of address space &#8211; that will be used to supply
memory via <tt class="docutils literal"><span class="pre">ArenaAlloc</span></tt>.</p>
</div>
</div>
</div>
@ -57,7 +81,15 @@
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../index.html">
<img class="logo" src="../_static/logo.png" alt="Logo"/>
</a></p><h4>Downloads</h4>
</a></p>
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">The MPS Bootstrap</a><ul>
<li><a class="reference internal" href="#introduction">Introduction</a></li>
</ul>
</li>
</ul>
<h4>Downloads</h4>
<p class="topless">
<a href="http://www.ravenbrook.com/project/mps/release/1.111.0/">MPS Kit release 1.111.0</a><br>

View file

@ -713,8 +713,8 @@ development.</p>
intended to execute all of the module&#8217;s code in at least some minimal
way.</p>
<p><span class="target" id="design.mps.bt.test.cbstest"></span><a class="mpstag reference internal" href="#design.mps.bt.test.cbstest">.test.cbstest:</a> <tt class="docutils literal"><span class="pre">cbstest.c</span></tt>. This was written as a test of the
<tt class="xref c c-macro docutils literal"><span class="pre">CBS</span></tt> module (design.mps.cbs(2)). It compares the functional
operation of a <tt class="xref c c-macro docutils literal"><span class="pre">CBS</span></tt> with that of a <a class="reference internal" href="#BT" title="BT"><tt class="xref c c-type docutils literal"><span class="pre">BT</span></tt></a> so is a good functional
<a class="reference internal" href="cbs.html#CBS" title="CBS"><tt class="xref c c-macro docutils literal"><span class="pre">CBS</span></tt></a> module (design.mps.cbs(2)). It compares the functional
operation of a <a class="reference internal" href="cbs.html#CBS" title="CBS"><tt class="xref c c-macro docutils literal"><span class="pre">CBS</span></tt></a> with that of a <a class="reference internal" href="#BT" title="BT"><tt class="xref c c-type docutils literal"><span class="pre">BT</span></tt></a> so is a good functional
test of either module.</p>
<p><span class="target" id="design.mps.bt.test.mmqa.120"></span><a class="mpstag reference internal" href="#design.mps.bt.test.mmqa.120">.test.mmqa.120:</a> MMQA_test_function!210.c. This is used because it has
a fair amount of segment allocation and freeing so exercises the arena

View file

@ -0,0 +1,422 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>2. Coalescing block structure &mdash; Memory Pool System 1.111.0 documentation</title>
<link rel="stylesheet" href="../_static/mps.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../',
VERSION: '1.111.0',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<link rel="copyright" title="Copyright" href="../copyright.html" />
<link rel="top" title="Memory Pool System 1.111.0 documentation" href="../index.html" />
<link rel="up" title="Design" href="index.html" />
<link rel="next" title="3. MPS Configuration" href="config.html" />
<link rel="prev" title="1. Queue design" href="abq.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="config.html" title="3. MPS Configuration"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="abq.html" title="1. Queue design"
accesskey="P">previous</a> |</li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
<li><a href="index.html" accesskey="U">Design</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="coalescing-block-structure">
<span id="design-cbs"></span><h1>2. Coalescing block structure<a class="headerlink" href="#coalescing-block-structure" title="Permalink to this headline"></a></h1>
<div class="section" id="introduction">
<span id="design.mps.cbs"></span><h2>2.1. Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.cbs.intro"></span><a class="mpstag reference internal" href="#design.mps.cbs.intro">.intro:</a> This is the design for impl.c.cbs, which implements a data
structure for the management of non-intersecting memory ranges, with
eager coalescence.</p>
<p><span class="target" id="design.mps.cbs.readership"></span><a class="mpstag reference internal" href="#design.mps.cbs.readership">.readership:</a> This document is intended for any MM developer.</p>
<p><span class="target" id="design.mps.cbs.source"></span><a class="mpstag reference internal" href="#design.mps.cbs.source">.source:</a> design.mps.poolmv2, design.mps.poolmvff.</p>
<p><span class="target" id="design.mps.cbs.overview"></span><a class="mpstag reference internal" href="#design.mps.cbs.overview">.overview:</a> The &#8220;coalescing block structure&#8221; is a set of addresses
(or a subset of address space), with provision for efficient
management of contiguous ranges, including insertion and deletion,
high level communication with the client about the size of contiguous
ranges, and detection of protocol violations.</p>
</div>
<div class="section" id="definitions">
<h2>2.2. Definitions<a class="headerlink" href="#definitions" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.cbs.def.range"></span><a class="mpstag reference internal" href="#design.mps.cbs.def.range">.def.range:</a> A (contiguous) <em>range</em> of addresses is a semi-open
interval on address space.</p>
<p><span class="target" id="design.mps.cbs.def.isolated"></span><a class="mpstag reference internal" href="#design.mps.cbs.def.isolated">.def.isolated:</a> A contiguous range is <em>isolated</em> with respect to
some property it has, if adjacent elements do not have that property.</p>
</div>
<div class="section" id="requirements">
<h2>2.3. Requirements<a class="headerlink" href="#requirements" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.cbs.req.set"></span><a class="mpstag reference internal" href="#design.mps.cbs.req.set">.req.set:</a> Must maintain a set of addresses.</p>
<p><span class="target" id="design.mps.cbs.req.fast"></span><a class="mpstag reference internal" href="#design.mps.cbs.req.fast">.req.fast:</a> Common operations must have a low amortized cost.</p>
<p><span class="target" id="design.mps.cbs.req.add"></span><a class="mpstag reference internal" href="#design.mps.cbs.req.add">.req.add:</a> Must be able to add address ranges to the set.</p>
<p><span class="target" id="design.mps.cbs.req.remove"></span><a class="mpstag reference internal" href="#design.mps.cbs.req.remove">.req.remove:</a> Must be able to remove address ranges from the set.</p>
<p><span class="target" id="design.mps.cbs.req.size"></span><a class="mpstag reference internal" href="#design.mps.cbs.req.size">.req.size:</a> Must report concisely to the client when isolated
contiguous ranges of at least a certain size appear and disappear.</p>
<p><span class="target" id="design.mps.cbs.req.iterate"></span><a class="mpstag reference internal" href="#design.mps.cbs.req.iterate">.req.iterate:</a> Must support the iteration of all isolated
contiguous ranges. This will not be a common operation.</p>
<p><span class="target" id="design.mps.cbs.req.protocol"></span><a class="mpstag reference internal" href="#design.mps.cbs.req.protocol">.req.protocol:</a> Must detect protocol violations.</p>
<p><span class="target" id="design.mps.cbs.req.debug"></span><a class="mpstag reference internal" href="#design.mps.cbs.req.debug">.req.debug:</a> Must support debugging of client code.</p>
<p><span class="target" id="design.mps.cbs.req.small"></span><a class="mpstag reference internal" href="#design.mps.cbs.req.small">.req.small:</a> Must have a small space overhead for the storage of
typical subsets of address space and not have abysmal overhead for the
storage of any subset of address space.</p>
<p><span class="target" id="design.mps.cbs.req.align"></span><a class="mpstag reference internal" href="#design.mps.cbs.req.align">.req.align:</a> Must support an alignment (the alignment of all
addresses specifying ranges) of down to <tt class="docutils literal"><span class="pre">sizeof(void&nbsp;*)</span></tt> without
losing memory.</p>
</div>
<div class="section" id="interface">
<h2>2.4. Interface<a class="headerlink" href="#interface" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.cbs.header"></span><a class="mpstag reference internal" href="#design.mps.cbs.header">.header:</a> CBS is used through impl.h.cbs.</p>
<div class="section" id="external-types">
<h3>2.4.1. External types<a class="headerlink" href="#external-types" title="Permalink to this headline"></a></h3>
<dl class="type">
<dt id="CBS">
struct CBSStruct *<tt class="descname">CBS</tt><a class="headerlink" href="#CBS" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p><span class="target" id="design.mps.cbs.type.cbs"></span><a class="mpstag reference internal" href="#design.mps.cbs.type.cbs">.type.cbs:</a> <a class="reference internal" href="#CBS" title="CBS"><tt class="xref c c-macro docutils literal"><span class="pre">CBS</span></tt></a> is the main data structure for manipulating a
CBS. It is intended that a <tt class="xref c c-type docutils literal"><span class="pre">CBSStruct</span></tt> be embedded in another
structure. No convenience functions are provided for the allocation or
deallocation of the CBS.</p>
<dl class="type">
<dt id="CBSIterateMethod">
<a class="reference internal" href="type.html#Bool" title="Bool">Bool</a> <tt class="descname">(*CBSIterateMethod)</tt><big>(</big><a class="reference internal" href="#CBS" title="CBS">CBS</a><em>&nbsp;cbs</em>, <a class="reference internal" href="range.html#Range" title="Range">Range</a><em>&nbsp;range</em>, void<em>&nbsp;*closureP</em>, <a class="reference internal" href="type.html#Size" title="Size">Size</a><em>&nbsp;closureS</em><big>)</big><a class="headerlink" href="#CBSIterateMethod" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p><span class="target" id="design.mps.cbs.type.cbs.iterate.method"></span><a class="mpstag reference internal" href="#design.mps.cbs.type.cbs.iterate.method">.type.cbs.iterate.method:</a> Type <a class="reference internal" href="#CBSIterateMethod" title="CBSIterateMethod"><tt class="xref c c-type docutils literal"><span class="pre">CBSIterateMethod</span></tt></a> is a callback
function that may be passed to <a class="reference internal" href="#CBSIterate" title="CBSIterate"><tt class="xref c c-func docutils literal"><span class="pre">CBSIterate()</span></tt></a>. It is called for
every isolated contiguous range in address order. The function must
returns a <a class="reference internal" href="type.html#Bool" title="Bool"><tt class="xref c c-type docutils literal"><span class="pre">Bool</span></tt></a> indicating whether to continue with the iteration.</p>
</div>
<div class="section" id="external-functions">
<h3>2.4.2. External functions<a class="headerlink" href="#external-functions" title="Permalink to this headline"></a></h3>
<dl class="function">
<dt id="CBSInit">
<a class="reference internal" href="type.html#Res" title="Res">Res</a> <tt class="descname">CBSInit</tt><big>(</big><a class="reference internal" href="arena.html#Arena" title="Arena">Arena</a><em>&nbsp;arena</em>, <a class="reference internal" href="#CBS" title="CBS">CBS</a><em>&nbsp;cbs</em>, void<em>&nbsp;*owner</em>, <a class="reference internal" href="type.html#Align" title="Align">Align</a><em>&nbsp;alignment</em>, <a class="reference internal" href="type.html#Bool" title="Bool">Bool</a><em>&nbsp;fastFind</em>, ArgList<em>&nbsp;args</em><big>)</big><a class="headerlink" href="#CBSInit" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p><span class="target" id="design.mps.cbs.function.cbs.init"></span><a class="mpstag reference internal" href="#design.mps.cbs.function.cbs.init">.function.cbs.init:</a> <a class="reference internal" href="#CBSInit" title="CBSInit"><tt class="xref c c-func docutils literal"><span class="pre">CBSInit()</span></tt></a> is the function that initialises
the CBS structure. It performs allocation in the supplied arena. The
parameter <tt class="docutils literal"><span class="pre">owner</span></tt> is passed to <tt class="xref c c-func docutils literal"><span class="pre">MeterInit()</span></tt>, an <tt class="docutils literal"><span class="pre">alignment</span></tt>
indicates the alignment of ranges to be maintained. An initialised CBS
contains no ranges.</p>
<p><tt class="docutils literal"><span class="pre">fastFind</span></tt>, if set, causes the CBS to maintain, for each subtree,
the size of the largest block in that subtree. This must be true if
any of the <a class="reference internal" href="#CBSFindFirst" title="CBSFindFirst"><tt class="xref c c-func docutils literal"><span class="pre">CBSFindFirst()</span></tt></a>, <a class="reference internal" href="#CBSFindLast" title="CBSFindLast"><tt class="xref c c-func docutils literal"><span class="pre">CBSFindLast()</span></tt></a>, or
<a class="reference internal" href="#CBSFindLargest" title="CBSFindLargest"><tt class="xref c c-func docutils literal"><span class="pre">CBSFindLargest()</span></tt></a> functions are going to be used on the CBS.</p>
<p><a class="reference internal" href="#CBSInit" title="CBSInit"><tt class="xref c c-func docutils literal"><span class="pre">CBSInit()</span></tt></a> may take one keyword argument:</p>
<ul class="simple">
<li><tt class="xref c c-macro docutils literal"><span class="pre">MPS_KEY_CBS_EXTEND_BY</span></tt> (type <a class="reference internal" href="type.html#Size" title="Size"><tt class="xref c c-type docutils literal"><span class="pre">Size</span></tt></a>; default 4096) is the size
of segment that the CBS will request from the arena in which to
allocate its <tt class="docutils literal"><span class="pre">CBSBlock</span></tt> structures.</li>
</ul>
<dl class="function">
<dt id="CBSFinish">
void <tt class="descname">CBSFinish</tt><big>(</big><a class="reference internal" href="#CBS" title="CBS">CBS</a><em>&nbsp;cbs</em><big>)</big><a class="headerlink" href="#CBSFinish" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p><span class="target" id="design.mps.cbs.function.cbs.finish"></span><a class="mpstag reference internal" href="#design.mps.cbs.function.cbs.finish">.function.cbs.finish:</a> <a class="reference internal" href="#CBSFinish" title="CBSFinish"><tt class="xref c c-func docutils literal"><span class="pre">CBSFinish()</span></tt></a> is the function that finishes
the CBS structure and discards any other resources associated with the
CBS.</p>
<dl class="function">
<dt id="CBSInsert">
<a class="reference internal" href="type.html#Res" title="Res">Res</a> <tt class="descname">CBSInsert</tt><big>(</big><a class="reference internal" href="range.html#Range" title="Range">Range</a><em>&nbsp;rangeReturn</em>, <a class="reference internal" href="#CBS" title="CBS">CBS</a><em>&nbsp;cbs</em>, <a class="reference internal" href="range.html#Range" title="Range">Range</a><em>&nbsp;range</em><big>)</big><a class="headerlink" href="#CBSInsert" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p><span class="target" id="design.mps.cbs.function.cbs.insert"></span><a class="mpstag reference internal" href="#design.mps.cbs.function.cbs.insert">.function.cbs.insert:</a> If any part of <tt class="docutils literal"><span class="pre">range</span></tt> is already in the
CBS, then leave it unchanged and return <tt class="docutils literal"><span class="pre">ResFAIL</span></tt>. Otherwise,
attempt to insert <tt class="docutils literal"><span class="pre">range</span></tt> into the CBS. If the insertion succeeds,
then update <tt class="docutils literal"><span class="pre">rangeReturn</span></tt> to describe the contiguous isolated range
containing the inserted range (this may differ from <tt class="docutils literal"><span class="pre">range</span></tt> if there
was coalescence on either side) and return <tt class="docutils literal"><span class="pre">ResOK</span></tt>. If the insertion
fails, return a result code indicating allocation failure.</p>
<p><span class="target" id="design.mps.cbs.function.cbs.insert.fail"></span><a class="mpstag reference internal" href="#design.mps.cbs.function.cbs.insert.fail">.function.cbs.insert.fail:</a> Insertion of a valid range (that is, one
that does not overlap with any range in the CBS) can only fail if the
new range is isolated and the allocation of the necessary data
structure to represent it failed.</p>
<dl class="function">
<dt id="CBSDelete">
<a class="reference internal" href="type.html#Res" title="Res">Res</a> <tt class="descname">CBSDelete</tt><big>(</big><a class="reference internal" href="range.html#Range" title="Range">Range</a><em>&nbsp;rangeReturn</em>, <a class="reference internal" href="#CBS" title="CBS">CBS</a><em>&nbsp;cbs</em>, <a class="reference internal" href="range.html#Range" title="Range">Range</a><em>&nbsp;range</em><big>)</big><a class="headerlink" href="#CBSDelete" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p><span class="target" id="design.mps.cbs.function.cbs.delete"></span><a class="mpstag reference internal" href="#design.mps.cbs.function.cbs.delete">.function.cbs.delete:</a> If any part of the range is not in the CBS,
then leave the CBS unchanged and return <tt class="docutils literal"><span class="pre">ResFAIL</span></tt>. Otherwise, update
<tt class="docutils literal"><span class="pre">rangeReturn</span></tt> to describe the contiguous isolated range that
contains <tt class="docutils literal"><span class="pre">range</span></tt> (this may differ from <tt class="docutils literal"><span class="pre">range</span></tt> if there are
fragments on either side) and attempt to delete the range from the
CBS. If the deletion succeeds, return <tt class="docutils literal"><span class="pre">ResOK</span></tt>. If the deletion
fails, return a result code indicating allocation failure.</p>
<p><span class="target" id="design.mps.cbs.function.cbs.delete.fail"></span><a class="mpstag reference internal" href="#design.mps.cbs.function.cbs.delete.fail">.function.cbs.delete.fail:</a> Deletion of a valid range (that is, one
that is wholly contained in the CBS) can only fail if there are
fragments on both sides and the allocation of the necessary data
structures to represent them fails.</p>
<p><span class="target" id="design.mps.cbs.function.cbs.delete.return"></span><a class="mpstag reference internal" href="#design.mps.cbs.function.cbs.delete.return">.function.cbs.delete.return:</a> <a class="reference internal" href="#CBSDelete" title="CBSDelete"><tt class="xref c c-func docutils literal"><span class="pre">CBSDelete()</span></tt></a> returns the contiguous
isolated range that contains <tt class="docutils literal"><span class="pre">range</span></tt> even if the deletion fails.
This is so that the caller can try deleting the whole block (which is
guaranteed to succeed) and managing the fragments using a fallback
strategy.</p>
<dl class="function">
<dt id="CBSIterate">
void <tt class="descname">CBSIterate</tt><big>(</big><a class="reference internal" href="#CBS" title="CBS">CBS</a><em>&nbsp;cbs</em>, <a class="reference internal" href="#CBSIterateMethod" title="CBSIterateMethod">CBSIterateMethod</a><em>&nbsp;iterate</em>, void<em>&nbsp;*closureP</em>, <a class="reference internal" href="type.html#Size" title="Size">Size</a><em>&nbsp;closureS</em><big>)</big><a class="headerlink" href="#CBSIterate" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p><span class="target" id="design.mps.cbs.function.cbs.iterate"></span><a class="mpstag reference internal" href="#design.mps.cbs.function.cbs.iterate">.function.cbs.iterate:</a> <a class="reference internal" href="#CBSIterate" title="CBSIterate"><tt class="xref c c-func docutils literal"><span class="pre">CBSIterate()</span></tt></a> is the function used to
iterate all isolated contiguous ranges in a CBS. It receives a
pointer, <a class="reference internal" href="type.html#Size" title="Size"><tt class="xref c c-type docutils literal"><span class="pre">Size</span></tt></a> closure pair to pass on to the iterator method,
and an iterator method to invoke on every range in address order. If
the iterator method returns <tt class="xref c c-macro docutils literal"><span class="pre">FALSE</span></tt>, then the iteration is
terminated.</p>
<dl class="function">
<dt id="CBSDescribe">
<a class="reference internal" href="type.html#Res" title="Res">Res</a> <tt class="descname">CBSDescribe</tt><big>(</big><a class="reference internal" href="#CBS" title="CBS">CBS</a><em>&nbsp;cbs</em>, <a class="reference internal" href="../topic/plinth.html#mps_lib_FILE" title="mps_lib_FILE">mps_lib_FILE</a><em>&nbsp;*stream</em><big>)</big><a class="headerlink" href="#CBSDescribe" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p><span class="target" id="design.mps.cbs.function.cbs.describe"></span><a class="mpstag reference internal" href="#design.mps.cbs.function.cbs.describe">.function.cbs.describe:</a> <a class="reference internal" href="#CBSDescribe" title="CBSDescribe"><tt class="xref c c-func docutils literal"><span class="pre">CBSDescribe()</span></tt></a> is a function that prints
a textual representation of the CBS to the given stream, indicating
the contiguous ranges in order, as well as the structure of the
underlying splay tree implementation. It is provided for debugging
purposes only.</p>
<dl class="function">
<dt id="CBSFindFirst">
<a class="reference internal" href="type.html#Bool" title="Bool">Bool</a> <tt class="descname">CBSFindFirst</tt><big>(</big><a class="reference internal" href="range.html#Range" title="Range">Range</a><em>&nbsp;rangeReturn</em>, <a class="reference internal" href="range.html#Range" title="Range">Range</a><em>&nbsp;oldRangeReturn</em>, <a class="reference internal" href="#CBS" title="CBS">CBS</a><em>&nbsp;cbs</em>, <a class="reference internal" href="type.html#Size" title="Size">Size</a><em>&nbsp;size</em>, FindDelete<em>&nbsp;findDelete</em><big>)</big><a class="headerlink" href="#CBSFindFirst" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p><span class="target" id="design.mps.cbs.function.cbs.find.first"></span><a class="mpstag reference internal" href="#design.mps.cbs.function.cbs.find.first">.function.cbs.find.first:</a> Locate the first block (in address order)
within the CBS of at least the specified size, update <tt class="docutils literal"><span class="pre">rangeReturn</span></tt>
to describe that range, and return <tt class="xref c c-macro docutils literal"><span class="pre">TRUE</span></tt>. If there is no such
block, it returns <tt class="xref c c-macro docutils literal"><span class="pre">FALSE</span></tt>.</p>
<p>In addition, optionally delete the top, bottom, or all of the found
range, depending on the <tt class="docutils literal"><span class="pre">findDelete</span></tt> argument. This saves a separate
call to <a class="reference internal" href="#CBSDelete" title="CBSDelete"><tt class="xref c c-func docutils literal"><span class="pre">CBSDelete()</span></tt></a>, and uses the knowledge of exactly where we
found the range. The value of <tt class="docutils literal"><span class="pre">findDelete</span></tt> must come from this
enumeration:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">enum</span> <span class="p">{</span>
<span class="n">FindDeleteNONE</span><span class="p">,</span> <span class="cm">/* don&#39;t delete after finding */</span>
<span class="n">FindDeleteLOW</span><span class="p">,</span> <span class="cm">/* delete size bytes from low end of block */</span>
<span class="n">FindDeleteHIGH</span><span class="p">,</span> <span class="cm">/* delete size bytes from high end of block */</span>
<span class="n">FindDeleteENTIRE</span> <span class="cm">/* delete entire range */</span>
<span class="p">};</span>
</pre></div>
</div>
<p>The original contiguous isolated range in which the range was found is
returned via the <tt class="docutils literal"><span class="pre">oldRangeReturn</span></tt> argument. (If <tt class="docutils literal"><span class="pre">findDelete</span></tt> is
<tt class="docutils literal"><span class="pre">FindDeleteNONE</span></tt> or <tt class="docutils literal"><span class="pre">FindDeleteENTIRE</span></tt>, then this will be
identical to the range returned via the <tt class="docutils literal"><span class="pre">rangeReturn</span></tt> argument.)</p>
<p><a class="reference internal" href="#CBSFindFirst" title="CBSFindFirst"><tt class="xref c c-func docutils literal"><span class="pre">CBSFindFirst()</span></tt></a> requires that <tt class="docutils literal"><span class="pre">fastFind</span></tt> was true when
<a class="reference internal" href="#CBSInit" title="CBSInit"><tt class="xref c c-func docutils literal"><span class="pre">CBSInit()</span></tt></a> was called.</p>
<dl class="function">
<dt id="CBSFindLast">
<a class="reference internal" href="type.html#Bool" title="Bool">Bool</a> <tt class="descname">CBSFindLast</tt><big>(</big><a class="reference internal" href="range.html#Range" title="Range">Range</a><em>&nbsp;rangeReturn</em>, <a class="reference internal" href="range.html#Range" title="Range">Range</a><em>&nbsp;oldRangeReturn</em>, <a class="reference internal" href="#CBS" title="CBS">CBS</a><em>&nbsp;cbs</em>, <a class="reference internal" href="type.html#Size" title="Size">Size</a><em>&nbsp;size</em>, FindDelete<em>&nbsp;findDelete</em><big>)</big><a class="headerlink" href="#CBSFindLast" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p><span class="target" id="design.mps.cbs.function.cbs.find.last"></span><a class="mpstag reference internal" href="#design.mps.cbs.function.cbs.find.last">.function.cbs.find.last:</a> Like <a class="reference internal" href="#CBSFindFirst" title="CBSFindFirst"><tt class="xref c c-func docutils literal"><span class="pre">CBSFindFirst()</span></tt></a>, except that it
finds the last block in address order.</p>
<dl class="function">
<dt id="CBSFindLargest">
<a class="reference internal" href="type.html#Bool" title="Bool">Bool</a> <tt class="descname">CBSFindLargest</tt><big>(</big><a class="reference internal" href="range.html#Range" title="Range">Range</a><em>&nbsp;rangeReturn</em>, <a class="reference internal" href="range.html#Range" title="Range">Range</a><em>&nbsp;oldRangeReturn</em>, <a class="reference internal" href="#CBS" title="CBS">CBS</a><em>&nbsp;cbs</em>, <a class="reference internal" href="type.html#Size" title="Size">Size</a><em>&nbsp;size</em>, FindDelete<em>&nbsp;findDelete</em><big>)</big><a class="headerlink" href="#CBSFindLargest" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p><span class="target" id="design.mps.cbs.function.cbs.find.largest"></span><a class="mpstag reference internal" href="#design.mps.cbs.function.cbs.find.largest">.function.cbs.find.largest:</a> Locate the largest block within the
CBS, and if that block is at least as big as <tt class="docutils literal"><span class="pre">size</span></tt>, return its
range via the <tt class="docutils literal"><span class="pre">rangeReturn</span></tt> argument, and return <tt class="xref c c-macro docutils literal"><span class="pre">TRUE</span></tt>. If there
are no blocks in the CBS at least as large as <tt class="docutils literal"><span class="pre">size</span></tt>, return
<tt class="xref c c-macro docutils literal"><span class="pre">FALSE</span></tt>. Pass 0 for <tt class="docutils literal"><span class="pre">size</span></tt> if you want the largest block
unconditionally.</p>
<p>Like <a class="reference internal" href="#CBSFindFirst" title="CBSFindFirst"><tt class="xref c c-func docutils literal"><span class="pre">CBSFindFirst()</span></tt></a>, optionally delete the range (specifying
<tt class="docutils literal"><span class="pre">FindDeleteLOW</span></tt> or <tt class="docutils literal"><span class="pre">FindDeleteHIGH</span></tt> has the same effect as
<tt class="docutils literal"><span class="pre">FindDeleteENTIRE</span></tt>). This feature requires that <tt class="docutils literal"><span class="pre">fastFind</span></tt> was
true when <a class="reference internal" href="#CBSInit" title="CBSInit"><tt class="xref c c-func docutils literal"><span class="pre">CBSInit()</span></tt></a> was called.</p>
</div>
</div>
<div class="section" id="implementation">
<h2>2.5. Implementation<a class="headerlink" href="#implementation" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.cbs.impl"></span><a class="mpstag reference internal" href="#design.mps.cbs.impl">.impl:</a> This section is concerned with describing various aspects of
the implementation. It does not form part of the interface definition.</p>
<div class="section" id="splay-tree">
<h3>2.5.1. Splay tree<a class="headerlink" href="#splay-tree" title="Permalink to this headline"></a></h3>
<p><span class="target" id="design.mps.cbs.impl.splay"></span><a class="mpstag reference internal" href="#design.mps.cbs.impl.splay">.impl.splay:</a> The CBS is principally implemented using a splay tree
(see <a class="reference external" href="splay">design.mps.splay</a>). Each splay tree node is embedded in a
<tt class="docutils literal"><span class="pre">CBSBlock</span></tt> that represents a semi-open address range. The key passed
for comparison is the base of another range.</p>
<p><span class="target" id="design.mps.cbs.impl.splay.fast-find"></span><a class="mpstag reference internal" href="#design.mps.cbs.impl.splay.fast-find">.impl.splay.fast-find:</a> <a class="reference internal" href="#CBSFindFirst" title="CBSFindFirst"><tt class="xref c c-func docutils literal"><span class="pre">CBSFindFirst()</span></tt></a> and <a class="reference internal" href="#CBSFindLast" title="CBSFindLast"><tt class="xref c c-func docutils literal"><span class="pre">CBSFindLast()</span></tt></a> use
the update/refresh facility of splay trees to store, in each
<tt class="docutils literal"><span class="pre">CBSBlock</span></tt>, an accurate summary of the maximum block size in the
tree rooted at the corresponding splay node. This allows rapid
location of the first or last suitable block, and very rapid failure
if there is no suitable block.</p>
<p><span class="target" id="design.mps.cbs.impl.find-largest"></span><a class="mpstag reference internal" href="#design.mps.cbs.impl.find-largest">.impl.find-largest:</a> <a class="reference internal" href="#CBSFindLargest" title="CBSFindLargest"><tt class="xref c c-func docutils literal"><span class="pre">CBSFindLargest()</span></tt></a> simply finds out the size
of the largest block in the CBS from the root of the tree, using
<a class="reference internal" href="splay.html#SplayRoot" title="SplayRoot"><tt class="xref c c-func docutils literal"><span class="pre">SplayRoot()</span></tt></a>, and does <a class="reference internal" href="splay.html#SplayFindFirst" title="SplayFindFirst"><tt class="xref c c-func docutils literal"><span class="pre">SplayFindFirst()</span></tt></a> for a block of that
size. This is O(log&nbsp;<em>n</em>) in the size of the free list, so it&#8217;s about
the best you can do without maintaining a separate priority queue,
just to do <a class="reference internal" href="#CBSFindLargest" title="CBSFindLargest"><tt class="xref c c-func docutils literal"><span class="pre">CBSFindLargest()</span></tt></a>.</p>
</div>
<div class="section" id="low-memory-behaviour">
<h3>2.5.2. Low memory behaviour<a class="headerlink" href="#low-memory-behaviour" title="Permalink to this headline"></a></h3>
<p><span class="target" id="design.mps.cbs.impl.low-mem"></span><a class="mpstag reference internal" href="#design.mps.cbs.impl.low-mem">.impl.low-mem:</a> When the CBS tries to allocate a new <tt class="docutils literal"><span class="pre">CBSBlock</span></tt>
structure for a new isolated range as a result of either
<a class="reference internal" href="#CBSInsert" title="CBSInsert"><tt class="xref c c-func docutils literal"><span class="pre">CBSInsert()</span></tt></a> or <a class="reference internal" href="#CBSDelete" title="CBSDelete"><tt class="xref c c-func docutils literal"><span class="pre">CBSDelete()</span></tt></a>, and there is insufficient memory
to allocation the <tt class="docutils literal"><span class="pre">CBSBlock</span></tt> structure, then the range is not added
to the CBS or deleted from it, and the call to <a class="reference internal" href="#CBSInsert" title="CBSInsert"><tt class="xref c c-func docutils literal"><span class="pre">CBSInsert()</span></tt></a> or
<a class="reference internal" href="#CBSDelete" title="CBSDelete"><tt class="xref c c-func docutils literal"><span class="pre">CBSDelete()</span></tt></a> returns <tt class="docutils literal"><span class="pre">ResMEMORY</span></tt>.</p>
</div>
<div class="section" id="the-cbs-block">
<h3>2.5.3. The CBS block<a class="headerlink" href="#the-cbs-block" title="Permalink to this headline"></a></h3>
<p><span class="target" id="design.mps.cbs.impl.cbs.block"></span><a class="mpstag reference internal" href="#design.mps.cbs.impl.cbs.block">.impl.cbs.block:</a> The block contains a base-limit pair and a splay
tree node.</p>
<p><span class="target" id="design.mps.cbs.impl.cbs.block.special"></span><a class="mpstag reference internal" href="#design.mps.cbs.impl.cbs.block.special">.impl.cbs.block.special:</a> The base and limit may be equal if the
block is halfway through being deleted.</p>
<p><span class="target" id="design.mps.cbs.impl.cbs.block.special.just"></span><a class="mpstag reference internal" href="#design.mps.cbs.impl.cbs.block.special.just">.impl.cbs.block.special.just:</a> This conflates values and status, but
is justified because block size is very important.</p>
</div>
</div>
<div class="section" id="testing">
<h2>2.6. Testing<a class="headerlink" href="#testing" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.cbs.test"></span><a class="mpstag reference internal" href="#design.mps.cbs.test">.test:</a> The following testing will be performed on this module:</p>
<p><span class="target" id="design.mps.cbs.test.cbstest"></span><a class="mpstag reference internal" href="#design.mps.cbs.test.cbstest">.test.cbstest:</a> There is a stress test for this module in
impl.c.cbstest. This allocates a large block of memory and then
simulates the allocation and deallocation of ranges within this block
using both a <a class="reference internal" href="#CBS" title="CBS"><tt class="xref c c-macro docutils literal"><span class="pre">CBS</span></tt></a> and a <a class="reference internal" href="bt.html#BT" title="BT"><tt class="xref c c-type docutils literal"><span class="pre">BT</span></tt></a>. It makes both valid and invalid
requests, and compares the <a class="reference internal" href="#CBS" title="CBS"><tt class="xref c c-macro docutils literal"><span class="pre">CBS</span></tt></a> response to the correct behaviour
as determined by the <a class="reference internal" href="bt.html#BT" title="BT"><tt class="xref c c-type docutils literal"><span class="pre">BT</span></tt></a>. It also iterates the ranges in the
<a class="reference internal" href="#CBS" title="CBS"><tt class="xref c c-macro docutils literal"><span class="pre">CBS</span></tt></a>, comparing them to the <a class="reference internal" href="bt.html#BT" title="BT"><tt class="xref c c-type docutils literal"><span class="pre">BT</span></tt></a>. It also invokes the
<a class="reference internal" href="#CBSDescribe" title="CBSDescribe"><tt class="xref c c-func docutils literal"><span class="pre">CBSDescribe()</span></tt></a> method, but makes no automatic test of the resulting
output. It does not currently test the callbacks.</p>
<p><span class="target" id="design.mps.cbs.test.pool"></span><a class="mpstag reference internal" href="#design.mps.cbs.test.pool">.test.pool:</a> Several pools (currently <a class="reference external" href="poolmvt">MVT</a> and <a class="reference external" href="poolmvff">MVFF</a>) are implemented
on top of a CBS. These pool are subject to testing in development, QA,
and are/will be heavily exercised by customers.</p>
</div>
<div class="section" id="notes-for-future-development">
<h2>2.7. Notes for future development<a class="headerlink" href="#notes-for-future-development" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.cbs.future.not-splay"></span><a class="mpstag reference internal" href="#design.mps.cbs.future.not-splay">.future.not-splay:</a> The initial implementation of CBSs is based on
splay trees. It could be revised to use any other data structure that
meets the requirements (especially <a class="reference internal" href="#design.mps.cbs.req.fast">.req.fast</a>).</p>
<p><span class="target" id="design.mps.cbs.future.hybrid"></span><a class="mpstag reference internal" href="#design.mps.cbs.future.hybrid">.future.hybrid:</a> It would be possible to attenuate the problem of
<a class="reference internal" href="#design.mps.cbs.risk.overhead">.risk.overhead</a> (below) by using a single word bit set to represent
the membership in a (possibly aligned) word-width of grains. This
might be used for block sizes less than a word-width of grains,
converting them when they reach all free in the bit set. Note that
this would make coalescence slightly less eager, by up to
<tt class="docutils literal"><span class="pre">(word-width</span> <span class="pre">-</span> <span class="pre">1)</span></tt>.</p>
</div>
<div class="section" id="risks">
<h2>2.8. Risks<a class="headerlink" href="#risks" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.cbs.risk.overhead"></span><a class="mpstag reference internal" href="#design.mps.cbs.risk.overhead">.risk.overhead:</a> Clients should note that the current implementation
of CBSs has a space overhead proportional to the number of isolated
contiguous ranges. [Four words per range.] If the CBS contains every
other grain in an area, then the overhead will be large compared to
the size of that area. [Four words per two grains.] The CBS structure
is thus suitable only for managing large enough ranges.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../index.html">
<img class="logo" src="../_static/logo.png" alt="Logo"/>
</a></p>
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">2. Coalescing block structure</a><ul>
<li><a class="reference internal" href="#introduction">2.1. Introduction</a></li>
<li><a class="reference internal" href="#definitions">2.2. Definitions</a></li>
<li><a class="reference internal" href="#requirements">2.3. Requirements</a></li>
<li><a class="reference internal" href="#interface">2.4. Interface</a><ul>
<li><a class="reference internal" href="#external-types">2.4.1. External types</a></li>
<li><a class="reference internal" href="#external-functions">2.4.2. External functions</a></li>
</ul>
</li>
<li><a class="reference internal" href="#implementation">2.5. Implementation</a><ul>
<li><a class="reference internal" href="#splay-tree">2.5.1. Splay tree</a></li>
<li><a class="reference internal" href="#low-memory-behaviour">2.5.2. Low memory behaviour</a></li>
<li><a class="reference internal" href="#the-cbs-block">2.5.3. The CBS block</a></li>
</ul>
</li>
<li><a class="reference internal" href="#testing">2.6. Testing</a></li>
<li><a class="reference internal" href="#notes-for-future-development">2.7. Notes for future development</a></li>
<li><a class="reference internal" href="#risks">2.8. Risks</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="abq.html"
title="previous chapter">1. Queue design</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="config.html"
title="next chapter">3. MPS Configuration</a></p><h4>Downloads</h4>
<p class="topless">
<a href="http://www.ravenbrook.com/project/mps/release/1.111.0/">MPS Kit release 1.111.0</a><br>
<a href="http://www.ravenbrook.com/project/mps/release/">All MPS Kit releases</a>
</p>
<h4>Issues</h4>
<p class="topless">
<a href="http://www.ravenbrook.com/project/mps/issue/?action=list&amp;view=status%3dopen&amp;display=Job:Priority:Title&amp;sort=Priority">Known issues</a><br>
<a href="http://www.ravenbrook.com/project/mps/issue/?action=fixed&release_fixed=1.111.0">Issues fixed in release 1.111.0</a>
</p><h4>Contact us</h4>
<p class="topless"><a href="mailto:mps-questions@ravenbrook.com">mps-questions@ravenbrook.com</a></p>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="config.html" title="3. MPS Configuration"
>next</a> |</li>
<li class="right" >
<a href="abq.html" title="1. Queue design"
>previous</a> |</li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
<li><a href="index.html" >Design</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; <a href="../copyright.html">Copyright</a> 2013, Ravenbrook Limited.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

View file

@ -8,7 +8,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>1. MPS Configuration &mdash; Memory Pool System 1.111.0 documentation</title>
<title>3. MPS Configuration &mdash; Memory Pool System 1.111.0 documentation</title>
<link rel="stylesheet" href="../_static/mps.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
@ -28,8 +28,8 @@
<link rel="copyright" title="Copyright" href="../copyright.html" />
<link rel="top" title="Memory Pool System 1.111.0 documentation" href="../index.html" />
<link rel="up" title="Design" href="index.html" />
<link rel="next" title="2. The critical path through the MPS" href="critical-path.html" />
<link rel="prev" title="Design" href="index.html" />
<link rel="next" title="4. The critical path through the MPS" href="critical-path.html" />
<link rel="prev" title="2. Coalescing block structure" href="cbs.html" />
</head>
<body>
<div class="related">
@ -39,10 +39,10 @@
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="critical-path.html" title="2. The critical path through the MPS"
<a href="critical-path.html" title="4. The critical path through the MPS"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="index.html" title="Design"
<a href="cbs.html" title="2. Coalescing block structure"
accesskey="P">previous</a> |</li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
<li><a href="index.html" accesskey="U">Design</a> &raquo;</li>
@ -55,15 +55,15 @@
<div class="body">
<span class="target" id="design-config"></span><div class="section" id="mps-configuration">
<span id="index-0"></span><h1>1. MPS Configuration<a class="headerlink" href="#mps-configuration" title="Permalink to this headline"></a></h1>
<span id="index-0"></span><h1>3. MPS Configuration<a class="headerlink" href="#mps-configuration" title="Permalink to this headline"></a></h1>
<div class="section" id="introduction">
<span id="design.mps.config"></span><h2>1.1. Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline"></a></h2>
<span id="design.mps.config"></span><h2>3.1. Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.config.intro"></span><a class="mpstag reference internal" href="#design.mps.config.intro">.intro:</a> This document describes how the <a class="reference external" href="http://www.ravenbrook.com/project/mps/">Memory Pool System</a> source code is configured so
that it can target different architectures, operating systems, build
environments, varieties, and products.</p>
</div>
<div class="section" id="requirements">
<h2>1.2. Requirements<a class="headerlink" href="#requirements" title="Permalink to this headline"></a></h2>
<h2>3.2. Requirements<a class="headerlink" href="#requirements" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.config.req.import"></span><a class="mpstag reference internal" href="#design.mps.config.req.import">.req.import:</a> The MPS must be simple to include in third-party projects.</p>
<p><span class="target" id="design.mps.config.req.arch"></span><a class="mpstag reference internal" href="#design.mps.config.req.arch">.req.arch:</a> Allow architecture specific configurations of the MPS, so
that we can vary the MPS according to the target architecture.</p>
@ -79,7 +79,7 @@ maintainability of the implementation.</p>
<p><span class="target" id="design.mps.config.req.maint"></span><a class="mpstag reference internal" href="#design.mps.config.req.maint">.req.maint:</a> Maintenance of the configuration and build system should
not consume much developer time.</p>
<div class="section" id="retired-requirements">
<h3>1.2.1. Retired requirements<a class="headerlink" href="#retired-requirements" title="Permalink to this headline"></a></h3>
<h3>3.2.1. Retired requirements<a class="headerlink" href="#retired-requirements" title="Permalink to this headline"></a></h3>
<p><span class="target" id="design.mps.config.req.prod"></span><a class="mpstag reference internal" href="#design.mps.config.req.prod">.req.prod:</a> Allow product specific configurations of the MPS, so that
we can build variants of the MPS for use in different products. This
requirement has been retired on 2012-09-03 as part of work on the
@ -89,7 +89,7 @@ reduce costs and increase reliability. See <a class="reference internal" href="
</div>
</div>
<div class="section" id="definitions">
<h2>1.3. Definitions<a class="headerlink" href="#definitions" title="Permalink to this headline"></a></h2>
<h2>3.3. Definitions<a class="headerlink" href="#definitions" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.config.def.platform"></span><a class="mpstag reference internal" href="#design.mps.config.def.platform">.def.platform:</a> A <em>platform</em> is a combination of an architecture
(<a class="reference internal" href="#design.mps.config.def.arch">.def.arch</a>), an operating system (<a class="reference internal" href="#design.mps.config.def.os">.def.os</a>), and a builder
(<a class="reference internal" href="#design.mps.config.def.builder">.def.builder</a>). The set of supported platforms is maintained in the
@ -117,7 +117,7 @@ as a dimension of configuration since <a class="reference internal" href="#desig
<p><span class="target" id="design.mps.config.def.target"></span><a class="mpstag reference internal" href="#design.mps.config.def.target">.def.target:</a> The <em>target</em> is the result of the build.</p>
</div>
<div class="section" id="overview">
<h2>1.4. Overview<a class="headerlink" href="#overview" title="Permalink to this headline"></a></h2>
<h2>3.4. Overview<a class="headerlink" href="#overview" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.config.import.source"></span><a class="mpstag reference internal" href="#design.mps.config.import.source">.import.source:</a> The MPS can be simply included in client products as
source code. Since <a class="reference external" href="http://www.ravenbrook.com/project/mps/version/1.110/">version 1.110</a> we made it possible to simply
include the file <tt class="docutils literal"><span class="pre">mps.c</span></tt> in a client&#8217;s build process, without
@ -139,9 +139,9 @@ general rules for implementation [ref?] that are enforced by MPS
development procedures including code review and inspection.</p>
</div>
<div class="section" id="the-build-system">
<h2>1.5. The build system<a class="headerlink" href="#the-build-system" title="Permalink to this headline"></a></h2>
<h2>3.5. The build system<a class="headerlink" href="#the-build-system" title="Permalink to this headline"></a></h2>
<div class="section" id="abstract-build-function">
<h3>1.5.1. Abstract build function<a class="headerlink" href="#abstract-build-function" title="Permalink to this headline"></a></h3>
<h3>3.5.1. Abstract build function<a class="headerlink" href="#abstract-build-function" title="Permalink to this headline"></a></h3>
<p><span class="target" id="design.mps.config.build.fun"></span><a class="mpstag reference internal" href="#design.mps.config.build.fun">.build.fun:</a> The MPS implementation assumes only a simple &#8220;build
function&#8221; that takes a set of sources, possibly in several languages,
compiles them with a set of predefined preprocessor symbols, and links
@ -199,7 +199,7 @@ example, when building a test program, it might include the ANSI C
library and an operating system interface library.</p>
</div>
<div class="section" id="file-structure">
<h3>1.5.2. File Structure<a class="headerlink" href="#file-structure" title="Permalink to this headline"></a></h3>
<h3>3.5.2. File Structure<a class="headerlink" href="#file-structure" title="Permalink to this headline"></a></h3>
<p><span class="target" id="design.mps.config.file.dir"></span><a class="mpstag reference internal" href="#design.mps.config.file.dir">.file.dir:</a> The MPS source code is arranged in a single directory
called &#8220;code&#8221; containing all the sources for the whole family of
targets.</p>
@ -213,7 +213,7 @@ indicates the source language.</p>
in their name. See <a class="reference internal" href="#design.mps.config.mod.impls">.mod.impls</a>.</p>
</div>
<div class="section" id="modules-and-naming">
<h3>1.5.3. Modules and naming<a class="headerlink" href="#modules-and-naming" title="Permalink to this headline"></a></h3>
<h3>3.5.3. Modules and naming<a class="headerlink" href="#modules-and-naming" title="Permalink to this headline"></a></h3>
<p><span class="target" id="design.mps.config.mod.unique"></span><a class="mpstag reference internal" href="#design.mps.config.mod.unique">.mod.unique:</a> Each module has an identifier which is unique within the MPS.</p>
<p><span class="target" id="design.mps.config.mod.impls"></span><a class="mpstag reference internal" href="#design.mps.config.mod.impls">.mod.impls:</a> Each module has one or more implementations which may be
in any language supported by the relevant build environment.</p>
@ -234,7 +234,7 @@ platform-independent C in <a class="reference external" href="../code/ss.c">ss.c
architecture built with Microsoft Visual C.</p>
</div>
<div class="section" id="build-system-rationale">
<h3>1.5.4. Build system rationale<a class="headerlink" href="#build-system-rationale" title="Permalink to this headline"></a></h3>
<h3>3.5.4. Build system rationale<a class="headerlink" href="#build-system-rationale" title="Permalink to this headline"></a></h3>
<p><span class="target" id="design.mps.config.build.rat"></span><a class="mpstag reference internal" href="#design.mps.config.build.rat">.build.rat:</a> This simple design makes it possible to build the MPS
using many different tools. Microsoft Visual C and other graphical
development tools do not support much in the way of generated sources,
@ -266,7 +266,7 @@ Publishing division of Harlequin.</p>
</div>
</div>
<div class="section" id="implementation">
<h2>1.6. Implementation<a class="headerlink" href="#implementation" title="Permalink to this headline"></a></h2>
<h2>3.6. Implementation<a class="headerlink" href="#implementation" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.config.impl"></span><a class="mpstag reference internal" href="#design.mps.config.impl">.impl:</a> The two implementation files <a class="reference external" href="&lt;../code/config.h&gt;">config.h</a> and <a class="reference external" href="&lt;../code/mpstd.h&gt;">mpstd.h</a> can be
seen as preprocessor programs which &#8220;accept&#8221; build parameters and &#8220;emit&#8221;
configuration parameters (<a class="reference internal" href="#design.mps.config.fig.impl">.fig.impl</a>). The build parameters are
@ -302,7 +302,7 @@ identifers beginning &#8220;CONFIG_&#8221; should only appear in impl.h.config.
Code may depend on configuration parameters in certain, limited ways, as
defined below (<a class="reference internal" href="#design.mps.config.conf">.conf</a>).</p>
<div class="section" id="target-platform-detection">
<h3>1.6.1. Target platform detection<a class="headerlink" href="#target-platform-detection" title="Permalink to this headline"></a></h3>
<h3>3.6.1. Target platform detection<a class="headerlink" href="#target-platform-detection" title="Permalink to this headline"></a></h3>
<p><span class="target" id="design.mps.config.pf"></span><a class="mpstag reference internal" href="#design.mps.config.pf">.pf:</a> The target platform is &#8220;detected&#8221; by the preprocessor directives in
<a class="reference external" href="&lt;../code/mpstd.h&gt;">mpstd.h</a>.</p>
<p><span class="target" id="design.mps.config.pf.form"></span><a class="mpstag reference internal" href="#design.mps.config.pf.form">.pf.form:</a> This file consists of sets of directives of the form:</p>
@ -379,7 +379,7 @@ that is used to identify the target platform in <a class="reference external" hr
</div>
</div>
<div class="section" id="target-varieties">
<h3>1.6.2. Target varieties<a class="headerlink" href="#target-varieties" title="Permalink to this headline"></a></h3>
<h3>3.6.2. Target varieties<a class="headerlink" href="#target-varieties" title="Permalink to this headline"></a></h3>
<p><span class="target" id="design.mps.config.var"></span><a class="mpstag reference internal" href="#design.mps.config.var">.var:</a> The target variety is handled by preprocessor directives in
impl.h.config.</p>
<p><span class="target" id="design.mps.config.var.form"></span><a class="mpstag reference internal" href="#design.mps.config.var.form">.var.form:</a> The file contains sets of directives of the form:</p>
@ -403,7 +403,7 @@ should all begin with the prefix <tt class="xref c c-macro docutils literal"><sp
</div>
</div>
<div class="section" id="source-code-configuration">
<h2>1.7. Source code configuration<a class="headerlink" href="#source-code-configuration" title="Permalink to this headline"></a></h2>
<h2>3.7. Source code configuration<a class="headerlink" href="#source-code-configuration" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.config.conf"></span><a class="mpstag reference internal" href="#design.mps.config.conf">.conf:</a> This section describes how the configuration may affect the
source code of the MPS.</p>
<p><span class="target" id="design.mps.config.conf.limit"></span><a class="mpstag reference internal" href="#design.mps.config.conf.limit">.conf.limit:</a> The form of dependency allowed is carefully limited to
@ -412,7 +412,7 @@ ensure that code remains maintainable and portable (<a class="reference internal
be kept to a minimum in order to keep the system maintainable
(<a class="reference internal" href="#design.mps.config.req.impact">.req.impact</a>).</p>
<div class="section" id="configuration-parameters">
<h3>1.7.1. Configuration Parameters<a class="headerlink" href="#configuration-parameters" title="Permalink to this headline"></a></h3>
<h3>3.7.1. Configuration Parameters<a class="headerlink" href="#configuration-parameters" title="Permalink to this headline"></a></h3>
<p><span class="target" id="design.mps.config.conf.params"></span><a class="mpstag reference internal" href="#design.mps.config.conf.params">.conf.params:</a> The compilation of a module is parameterized by:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="n">MPS_ARCH_</span><span class="o">&lt;</span><span class="n">arch</span><span class="o">-</span><span class="n">code</span><span class="o">&gt;</span>
<span class="n">MPS_OS_</span><span class="o">&lt;</span><span class="n">os</span><span class="o">-</span><span class="n">code</span><span class="o">&gt;</span>
@ -422,7 +422,7 @@ be kept to a minimum in order to keep the system maintainable
</div>
</div>
<div class="section" id="abstract-and-concrete-module-interfaces">
<h3>1.7.2. Abstract and Concrete Module Interfaces<a class="headerlink" href="#abstract-and-concrete-module-interfaces" title="Permalink to this headline"></a></h3>
<h3>3.7.2. Abstract and Concrete Module Interfaces<a class="headerlink" href="#abstract-and-concrete-module-interfaces" title="Permalink to this headline"></a></h3>
<p><span class="target" id="design.mps.config.abs.caller"></span><a class="mpstag reference internal" href="#design.mps.config.abs.caller">.abs.caller:</a> Basic principle: the caller musn&#8217;t be affected by
configuration of a module. This reduces complexity and dependency of
configuration. All callers use the same abstract interface. Caller
@ -490,7 +490,7 @@ For example, this sort of thing:</p>
</div>
</div>
<div class="section" id="to-document">
<h2>1.8. To document<a class="headerlink" href="#to-document" title="Permalink to this headline"></a></h2>
<h2>3.8. To document<a class="headerlink" href="#to-document" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li>What about constants in config.h?</li>
<li>Update files to refer to this design document.</li>
@ -503,7 +503,7 @@ elsewhere.)</li>
</ul>
</div>
<div class="section" id="references">
<h2>1.9. References<a class="headerlink" href="#references" title="Permalink to this headline"></a></h2>
<h2>3.9. References<a class="headerlink" href="#references" title="Permalink to this headline"></a></h2>
<table class="docutils citation" frame="void" id="rb-2012-09-07" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
@ -536,43 +536,43 @@ elsewhere.)</li>
</a></p>
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">1. MPS Configuration</a><ul>
<li><a class="reference internal" href="#introduction">1.1. Introduction</a></li>
<li><a class="reference internal" href="#requirements">1.2. Requirements</a><ul>
<li><a class="reference internal" href="#retired-requirements">1.2.1. Retired requirements</a></li>
<li><a class="reference internal" href="#">3. MPS Configuration</a><ul>
<li><a class="reference internal" href="#introduction">3.1. Introduction</a></li>
<li><a class="reference internal" href="#requirements">3.2. Requirements</a><ul>
<li><a class="reference internal" href="#retired-requirements">3.2.1. Retired requirements</a></li>
</ul>
</li>
<li><a class="reference internal" href="#definitions">1.3. Definitions</a></li>
<li><a class="reference internal" href="#overview">1.4. Overview</a></li>
<li><a class="reference internal" href="#the-build-system">1.5. The build system</a><ul>
<li><a class="reference internal" href="#abstract-build-function">1.5.1. Abstract build function</a></li>
<li><a class="reference internal" href="#file-structure">1.5.2. File Structure</a></li>
<li><a class="reference internal" href="#modules-and-naming">1.5.3. Modules and naming</a></li>
<li><a class="reference internal" href="#build-system-rationale">1.5.4. Build system rationale</a></li>
<li><a class="reference internal" href="#definitions">3.3. Definitions</a></li>
<li><a class="reference internal" href="#overview">3.4. Overview</a></li>
<li><a class="reference internal" href="#the-build-system">3.5. The build system</a><ul>
<li><a class="reference internal" href="#abstract-build-function">3.5.1. Abstract build function</a></li>
<li><a class="reference internal" href="#file-structure">3.5.2. File Structure</a></li>
<li><a class="reference internal" href="#modules-and-naming">3.5.3. Modules and naming</a></li>
<li><a class="reference internal" href="#build-system-rationale">3.5.4. Build system rationale</a></li>
</ul>
</li>
<li><a class="reference internal" href="#implementation">1.6. Implementation</a><ul>
<li><a class="reference internal" href="#target-platform-detection">1.6.1. Target platform detection</a></li>
<li><a class="reference internal" href="#target-varieties">1.6.2. Target varieties</a></li>
<li><a class="reference internal" href="#implementation">3.6. Implementation</a><ul>
<li><a class="reference internal" href="#target-platform-detection">3.6.1. Target platform detection</a></li>
<li><a class="reference internal" href="#target-varieties">3.6.2. Target varieties</a></li>
</ul>
</li>
<li><a class="reference internal" href="#source-code-configuration">1.7. Source code configuration</a><ul>
<li><a class="reference internal" href="#configuration-parameters">1.7.1. Configuration Parameters</a></li>
<li><a class="reference internal" href="#abstract-and-concrete-module-interfaces">1.7.2. Abstract and Concrete Module Interfaces</a></li>
<li><a class="reference internal" href="#source-code-configuration">3.7. Source code configuration</a><ul>
<li><a class="reference internal" href="#configuration-parameters">3.7.1. Configuration Parameters</a></li>
<li><a class="reference internal" href="#abstract-and-concrete-module-interfaces">3.7.2. Abstract and Concrete Module Interfaces</a></li>
</ul>
</li>
<li><a class="reference internal" href="#to-document">1.8. To document</a></li>
<li><a class="reference internal" href="#references">1.9. References</a></li>
<li><a class="reference internal" href="#to-document">3.8. To document</a></li>
<li><a class="reference internal" href="#references">3.9. References</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="index.html"
title="previous chapter">Design</a></p>
<p class="topless"><a href="cbs.html"
title="previous chapter">2. Coalescing block structure</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="critical-path.html"
title="next chapter">2. The critical path through the MPS</a></p><h4>Downloads</h4>
title="next chapter">4. The critical path through the MPS</a></p><h4>Downloads</h4>
<p class="topless">
<a href="http://www.ravenbrook.com/project/mps/release/1.111.0/">MPS Kit release 1.111.0</a><br>
@ -598,10 +598,10 @@ elsewhere.)</li>
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="critical-path.html" title="2. The critical path through the MPS"
<a href="critical-path.html" title="4. The critical path through the MPS"
>next</a> |</li>
<li class="right" >
<a href="index.html" title="Design"
<a href="cbs.html" title="2. Coalescing block structure"
>previous</a> |</li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
<li><a href="index.html" >Design</a> &raquo;</li>

View file

@ -8,7 +8,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>2. The critical path through the MPS &mdash; Memory Pool System 1.111.0 documentation</title>
<title>4. The critical path through the MPS &mdash; Memory Pool System 1.111.0 documentation</title>
<link rel="stylesheet" href="../_static/mps.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
@ -28,8 +28,8 @@
<link rel="copyright" title="Copyright" href="../copyright.html" />
<link rel="top" title="Memory Pool System 1.111.0 documentation" href="../index.html" />
<link rel="up" title="Design" href="index.html" />
<link rel="next" title="3. Transliterating the alphabet into hexadecimal" href="guide.hex.trans.html" />
<link rel="prev" title="1. MPS Configuration" href="config.html" />
<link rel="next" title="5. Free list allocator" href="freelist.html" />
<link rel="prev" title="3. MPS Configuration" href="config.html" />
</head>
<body>
<div class="related">
@ -39,10 +39,10 @@
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="guide.hex.trans.html" title="3. Transliterating the alphabet into hexadecimal"
<a href="freelist.html" title="5. Free list allocator"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="config.html" title="1. MPS Configuration"
<a href="config.html" title="3. MPS Configuration"
accesskey="P">previous</a> |</li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
<li><a href="index.html" accesskey="U">Design</a> &raquo;</li>
@ -55,13 +55,13 @@
<div class="body">
<span class="target" id="design-critical-path"></span><div class="section" id="the-critical-path-through-the-mps">
<span id="index-0"></span><h1>2. The critical path through the MPS<a class="headerlink" href="#the-critical-path-through-the-mps" title="Permalink to this headline"></a></h1>
<span id="index-0"></span><h1>4. The critical path through the MPS<a class="headerlink" href="#the-critical-path-through-the-mps" title="Permalink to this headline"></a></h1>
<blockquote>
<div>single: critical path
single: path; critical
single: Memory Pool System; critical path</div></blockquote>
<div class="section" id="introduction">
<h2>2.1. Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline"></a></h2>
<h2>4.1. Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline"></a></h2>
<p>The critical path is a key concept in the design of the <a class="reference external" href="http://www.ravenbrook.com/project/mps/">Memory Pool
System</a>. Code on the critical
path is usually executed more than any other code in the process. A
@ -72,7 +72,7 @@ This document describes the critical path and explains some of that
design, with reference to more detailed documents.</p>
</div>
<div class="section" id="what-makes-the-critical-path-critical">
<h2>2.2. What makes the critical path critical<a class="headerlink" href="#what-makes-the-critical-path-critical" title="Permalink to this headline"></a></h2>
<h2>4.2. What makes the critical path critical<a class="headerlink" href="#what-makes-the-critical-path-critical" title="Permalink to this headline"></a></h2>
<p>In order to determine which object can be recycled, the garbage
collector has to frequently examine a very large number of pointers in
the program&#8217;s objects. It does this by <a class="reference external" href="http://www.memorymanagement.org/glossary/s.html#scan">scanning</a> memory, both
@ -90,7 +90,7 @@ the objects in existence. The path through fixing must also be highly
optimised, especially in the early stages.</p>
</div>
<div class="section" id="how-the-mps-avoids-scanning-and-fixing">
<h2>2.3. How the MPS avoids scanning and fixing<a class="headerlink" href="#how-the-mps-avoids-scanning-and-fixing" title="Permalink to this headline"></a></h2>
<h2>4.3. How the MPS avoids scanning and fixing<a class="headerlink" href="#how-the-mps-avoids-scanning-and-fixing" title="Permalink to this headline"></a></h2>
<p>This is just a brief overview of how the MPS is designed to reduce
unnecessary scanning and fixing.</p>
<p>Firstly, the MPS must occasionally decide which objects to try to
@ -133,7 +133,7 @@ their objects even once, but many other programs will preserve nearly
all of theirs many times.)</p>
</div>
<div class="section" id="where-to-find-the-critical-path">
<h2>2.4. Where to find the critical path<a class="headerlink" href="#where-to-find-the-critical-path" title="Permalink to this headline"></a></h2>
<h2>4.4. Where to find the critical path<a class="headerlink" href="#where-to-find-the-critical-path" title="Permalink to this headline"></a></h2>
<p>Very briefly, the critical path consists of five stages:</p>
<ol class="arabic">
<li><p class="first">The scanner, which iterates over pointers in objects. The MPS has
@ -174,7 +174,7 @@ contains pointers.</li>
</ol>
</div>
<div class="section" id="the-format-scanner">
<h2>2.5. The format scanner<a class="headerlink" href="#the-format-scanner" title="Permalink to this headline"></a></h2>
<h2>4.5. The format scanner<a class="headerlink" href="#the-format-scanner" title="Permalink to this headline"></a></h2>
<p>The critical path starts when a format scan method is called. That is a
call from the MPS to a client function of type <a class="reference internal" href="../topic/format.html#mps_fmt_scan_t" title="mps_fmt_scan_t"><tt class="xref c c-type docutils literal"><span class="pre">mps_fmt_scan_t</span></tt></a>
registered with one of the <tt class="xref c c-func docutils literal"><span class="pre">mps_format_create()</span></tt> functions in <a class="reference external" href="../code/mps.h">mps.h</a>.</p>
@ -245,7 +245,7 @@ about inlining parts of <tt class="docutils literal"><span class="pre">_mps_fix2
instructions for doing this are in <a class="reference external" href="../manual/build.txt">Building the Memory Pool System</a>, part of the manual.</p>
</div>
<div class="section" id="the-second-stage-fix-in-the-mpm">
<h2>2.6. The second stage fix in the MPM<a class="headerlink" href="#the-second-stage-fix-in-the-mpm" title="Permalink to this headline"></a></h2>
<h2>4.6. The second stage fix in the MPM<a class="headerlink" href="#the-second-stage-fix-in-the-mpm" title="Permalink to this headline"></a></h2>
<p>If a pointer gets past the first-stage fix filters, it is passed to
<tt class="docutils literal"><span class="pre">_mps_fix2</span></tt>, the &#8220;second stage fix&#8221;. The second stage can filter out
yet more pointers using information about segments before it has to
@ -290,7 +290,7 @@ exploited to optimize fixing in the AMC Pool depending on what kind of
object format it is managing.</p>
</div>
<div class="section" id="the-third-stage-fix-in-the-pool-class">
<h2>2.7. The third stage fix in the pool class<a class="headerlink" href="#the-third-stage-fix-in-the-pool-class" title="Permalink to this headline"></a></h2>
<h2>4.7. The third stage fix in the pool class<a class="headerlink" href="#the-third-stage-fix-in-the-pool-class" title="Permalink to this headline"></a></h2>
<p>The final stage of fixing is entirely dependent on the pool class. The
MPM can&#8217;t, in general, know how the objects within a pool are arranged,
so this is pool class specific code.</p>
@ -328,7 +328,7 @@ recycling when <cite>LOReclaim</cite> is called later on. <cite>LOFix</cite> ill
about the minimum and most efficient thing a pool fix method can do.</p>
</div>
<div class="section" id="other-considerations">
<h2>2.8. Other considerations<a class="headerlink" href="#other-considerations" title="Permalink to this headline"></a></h2>
<h2>4.8. Other considerations<a class="headerlink" href="#other-considerations" title="Permalink to this headline"></a></h2>
<p>So far this document has described the ways in which the garbage
collector is designed around optimising the critical path. There are a
few other things that the MPS does that are important.</p>
@ -349,7 +349,7 @@ review around the critical path is especially vigilant.</p>
<p>And we write long documents about it.</p>
</div>
<div class="section" id="references">
<h2>2.9. References<a class="headerlink" href="#references" title="Permalink to this headline"></a></h2>
<h2>4.9. References<a class="headerlink" href="#references" title="Permalink to this headline"></a></h2>
<table class="docutils citation" frame="void" id="mmref" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
@ -370,26 +370,26 @@ review around the critical path is especially vigilant.</p>
</a></p>
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">2. The critical path through the MPS</a><ul>
<li><a class="reference internal" href="#introduction">2.1. Introduction</a></li>
<li><a class="reference internal" href="#what-makes-the-critical-path-critical">2.2. What makes the critical path critical</a></li>
<li><a class="reference internal" href="#how-the-mps-avoids-scanning-and-fixing">2.3. How the MPS avoids scanning and fixing</a></li>
<li><a class="reference internal" href="#where-to-find-the-critical-path">2.4. Where to find the critical path</a></li>
<li><a class="reference internal" href="#the-format-scanner">2.5. The format scanner</a></li>
<li><a class="reference internal" href="#the-second-stage-fix-in-the-mpm">2.6. The second stage fix in the MPM</a></li>
<li><a class="reference internal" href="#the-third-stage-fix-in-the-pool-class">2.7. The third stage fix in the pool class</a></li>
<li><a class="reference internal" href="#other-considerations">2.8. Other considerations</a></li>
<li><a class="reference internal" href="#references">2.9. References</a></li>
<li><a class="reference internal" href="#">4. The critical path through the MPS</a><ul>
<li><a class="reference internal" href="#introduction">4.1. Introduction</a></li>
<li><a class="reference internal" href="#what-makes-the-critical-path-critical">4.2. What makes the critical path critical</a></li>
<li><a class="reference internal" href="#how-the-mps-avoids-scanning-and-fixing">4.3. How the MPS avoids scanning and fixing</a></li>
<li><a class="reference internal" href="#where-to-find-the-critical-path">4.4. Where to find the critical path</a></li>
<li><a class="reference internal" href="#the-format-scanner">4.5. The format scanner</a></li>
<li><a class="reference internal" href="#the-second-stage-fix-in-the-mpm">4.6. The second stage fix in the MPM</a></li>
<li><a class="reference internal" href="#the-third-stage-fix-in-the-pool-class">4.7. The third stage fix in the pool class</a></li>
<li><a class="reference internal" href="#other-considerations">4.8. Other considerations</a></li>
<li><a class="reference internal" href="#references">4.9. References</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="config.html"
title="previous chapter">1. MPS Configuration</a></p>
title="previous chapter">3. MPS Configuration</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="guide.hex.trans.html"
title="next chapter">3. Transliterating the alphabet into hexadecimal</a></p><h4>Downloads</h4>
<p class="topless"><a href="freelist.html"
title="next chapter">5. Free list allocator</a></p><h4>Downloads</h4>
<p class="topless">
<a href="http://www.ravenbrook.com/project/mps/release/1.111.0/">MPS Kit release 1.111.0</a><br>
@ -415,10 +415,10 @@ review around the critical path is especially vigilant.</p>
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="guide.hex.trans.html" title="3. Transliterating the alphabet into hexadecimal"
<a href="freelist.html" title="5. Free list allocator"
>next</a> |</li>
<li class="right" >
<a href="config.html" title="1. MPS Configuration"
<a href="config.html" title="3. MPS Configuration"
>previous</a> |</li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
<li><a href="index.html" >Design</a> &raquo;</li>

View file

@ -0,0 +1,370 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>5. Free list allocator &mdash; Memory Pool System 1.111.0 documentation</title>
<link rel="stylesheet" href="../_static/mps.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../',
VERSION: '1.111.0',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<link rel="copyright" title="Copyright" href="../copyright.html" />
<link rel="top" title="Memory Pool System 1.111.0 documentation" href="../index.html" />
<link rel="up" title="Design" href="index.html" />
<link rel="next" title="6. Transliterating the alphabet into hexadecimal" href="guide.hex.trans.html" />
<link rel="prev" title="4. The critical path through the MPS" href="critical-path.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="guide.hex.trans.html" title="6. Transliterating the alphabet into hexadecimal"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="critical-path.html" title="4. The critical path through the MPS"
accesskey="P">previous</a> |</li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
<li><a href="index.html" accesskey="U">Design</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="free-list-allocator">
<span id="design-freelist"></span><h1>5. Free list allocator<a class="headerlink" href="#free-list-allocator" title="Permalink to this headline"></a></h1>
<div class="section" id="introduction">
<span id="design.mps.freelist"></span><h2>5.1. Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.freelist.intro"></span><a class="mpstag reference internal" href="#design.mps.freelist.intro">.intro:</a> This document describes the free list allocator for the
Memory Pool System.</p>
<p><span class="target" id="design.mps.freelist.readership"></span><a class="mpstag reference internal" href="#design.mps.freelist.readership">.readership:</a> Any MPS developer.</p>
</div>
<div class="section" id="overview">
<h2>5.2. Overview<a class="headerlink" href="#overview" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.freelist.overview"></span><a class="mpstag reference internal" href="#design.mps.freelist.overview">.overview:</a> The free list allocator is an &#8220;emergency&#8221; allocator. It
is intended for use as a fallback allocation strategy in low memory
situations, when memory is not available for the control structures
needed by other allocators. In these situations the free list allocator
ensures that memory is not lost, but with several disadvantages:</p>
<ol class="arabic simple">
<li>operations on the free list are O(n) in the number of free blocks;</li>
<li>the data structures are stored in client memory and so are
vulnerable to corruption;</li>
<li>the data structures have poor locality (and thus potentially poor
cache performance).</li>
</ol>
<p>When memory becomes available again to allocate control structures,
the free lists can be &#8220;flushed&#8221; back into the more efficient data
structures.</p>
<p><span class="target" id="design.mps.freelist.bg"></span><a class="mpstag reference internal" href="#design.mps.freelist.bg">.bg:</a> The free list allocator was formerly part of the Coalescing
Block Structure module (see design.mps.cbs) but it was split into its
own module because this makes it:</p>
<ol class="arabic simple">
<li>simpler (no need to interact with CBS) and thus more maintainable;</li>
<li>possible to test directly (no need to create a CBS and then force
its control pool to run out of memory); and</li>
<li>usable as a fallback allocator in other pools (not just in pools
that use CBS).</li>
</ol>
</div>
<div class="section" id="definitions">
<h2>5.3. Definitions<a class="headerlink" href="#definitions" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.freelist.def.range"></span><a class="mpstag reference internal" href="#design.mps.freelist.def.range">.def.range:</a> A (contiguous) <em>range</em> of addresses is a semi-open
interval on address space.</p>
<p><span class="target" id="design.mps.freelist.def.isolated"></span><a class="mpstag reference internal" href="#design.mps.freelist.def.isolated">.def.isolated:</a> A contiguous range is <em>isolated</em> with respect to
some property it has, if adjacent elements do not have that property.</p>
</div>
<div class="section" id="requirements">
<h2>5.4. Requirements<a class="headerlink" href="#requirements" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.freelist.req.set"></span><a class="mpstag reference internal" href="#design.mps.freelist.req.set">.req.set:</a> Must maintain a set of free address ranges.</p>
<p><span class="target" id="design.mps.freelist.req.add"></span><a class="mpstag reference internal" href="#design.mps.freelist.req.add">.req.add:</a> Must be able to add free address ranges to the set.</p>
<p><span class="target" id="design.mps.freelist.req.remove"></span><a class="mpstag reference internal" href="#design.mps.freelist.req.remove">.req.remove:</a> Must be able to remove address ranges from the set (in
particular, when memory is allocated).</p>
<p><span class="target" id="design.mps.freelist.req.iterate"></span><a class="mpstag reference internal" href="#design.mps.freelist.req.iterate">.req.iterate:</a> Must support the iteration of all isolated contiguous
ranges.</p>
<p><span class="target" id="design.mps.freelist.req.protocol"></span><a class="mpstag reference internal" href="#design.mps.freelist.req.protocol">.req.protocol:</a> Must detect protocol violations.</p>
<p><span class="target" id="design.mps.freelist.req.align"></span><a class="mpstag reference internal" href="#design.mps.freelist.req.align">.req.align:</a> Must support an alignment (the alignment of all
addresses specifying ranges) of down to <tt class="docutils literal"><span class="pre">sizeof(void&nbsp;*)</span></tt> without
losing memory.</p>
<p><span class="target" id="design.mps.freelist.req.zero-overhead"></span><a class="mpstag reference internal" href="#design.mps.freelist.req.zero-overhead">.req.zero-overhead:</a> Must have zero space overhead for the storage
of any set of free blocks, so that it can be used to manage memory
when no memory can be allocated for control structures.</p>
<p><span class="target" id="design.mps.freelist.req.source"></span><a class="mpstag reference internal" href="#design.mps.freelist.req.source">.req.source:</a> This set of requirements is derived from those of the
CBS module (see design.mps.cbs.req), except that there is no
equivalent of design.mps.cbs.req.fast, and design.mps.cbs.req.small
has been replaced with <a class="reference internal" href="#design.mps.freelist.req.zero-overhead">.req.zero-overhead</a>.</p>
</div>
<div class="section" id="interface">
<h2>5.5. Interface<a class="headerlink" href="#interface" title="Permalink to this headline"></a></h2>
<div class="section" id="types">
<h3>5.5.1. Types<a class="headerlink" href="#types" title="Permalink to this headline"></a></h3>
<dl class="type">
<dt id="Freelist">
struct FreelistStruct *<tt class="descname">Freelist</tt><a class="headerlink" href="#Freelist" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p><span class="target" id="design.mps.freelist.type.freelist"></span><a class="mpstag reference internal" href="#design.mps.freelist.type.freelist">.type.freelist:</a> The type of free lists. The structure
<tt class="xref c c-type docutils literal"><span class="pre">FreelistStruct</span></tt> is declared in the header so that it can be inlined
in other structures, but you should not depend on its details.</p>
<dl class="type">
<dt id="FreelistIterateMethod">
<a class="reference internal" href="type.html#Bool" title="Bool">Bool</a> <tt class="descname">(*FreelistIterateMethod)</tt><big>(</big><a class="reference internal" href="type.html#Bool" title="Bool">Bool</a><em>&nbsp;*deleteReturn</em>, <a class="reference internal" href="#Freelist" title="Freelist">Freelist</a><em>&nbsp;fl</em>, <a class="reference internal" href="range.html#Range" title="Range">Range</a><em>&nbsp;range</em>, void<em>&nbsp;*closureP</em>, <a class="reference internal" href="type.html#Size" title="Size">Size</a><em>&nbsp;closureS</em><big>)</big><a class="headerlink" href="#FreelistIterateMethod" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p><span class="target" id="design.mps.freelist.type.iterate.method"></span><a class="mpstag reference internal" href="#design.mps.freelist.type.iterate.method">.type.iterate.method:</a> A callback function that may be passed to
<a class="reference internal" href="#FreelistIterate" title="FreelistIterate"><tt class="xref c c-func docutils literal"><span class="pre">FreelistIterate()</span></tt></a>. It is called for every isolated contiguous
range in address order, and with the closure arguments that were
originally passed to <a class="reference internal" href="#FreelistIterate" title="FreelistIterate"><tt class="xref c c-func docutils literal"><span class="pre">FreelistIterate()</span></tt></a>. It must update
<tt class="docutils literal"><span class="pre">*deleteReturn</span></tt> to <tt class="xref c c-macro docutils literal"><span class="pre">TRUE</span></tt> if the range must be deleted from the
free lists, or <tt class="xref c c-macro docutils literal"><span class="pre">FALSE</span></tt> if the range must be kept. The function must
return <tt class="xref c c-macro docutils literal"><span class="pre">TRUE</span></tt> if the iteration must continue, and <tt class="xref c c-macro docutils literal"><span class="pre">FALSE</span></tt> if the
iteration must stop (after possibly deleting the current range).</p>
</div>
<div class="section" id="functions">
<h3>5.5.2. Functions<a class="headerlink" href="#functions" title="Permalink to this headline"></a></h3>
<dl class="function">
<dt id="FreelistInit">
<a class="reference internal" href="type.html#Res" title="Res">Res</a> <tt class="descname">FreelistInit</tt><big>(</big><a class="reference internal" href="#Freelist" title="Freelist">Freelist</a><em>&nbsp;fl</em>, <a class="reference internal" href="type.html#Align" title="Align">Align</a><em>&nbsp;alignment</em><big>)</big><a class="headerlink" href="#FreelistInit" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p><span class="target" id="design.mps.freelist.function.init"></span><a class="mpstag reference internal" href="#design.mps.freelist.function.init">.function.init:</a> Initialize the <tt class="docutils literal"><span class="pre">Freelist</span></tt> structure pointed to by
<tt class="docutils literal"><span class="pre">fl</span></tt>. The argument <tt class="docutils literal"><span class="pre">alignment</span></tt> is the alignment of address ranges
to be maintained. An initialised free list contains no address ranges.</p>
<dl class="function">
<dt id="FreelistFinish">
void <tt class="descname">FreelistFinish</tt><big>(</big><a class="reference internal" href="#Freelist" title="Freelist">Freelist</a><em>&nbsp;fl</em><big>)</big><a class="headerlink" href="#FreelistFinish" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p><span class="target" id="design.mps.freelist.function.finish"></span><a class="mpstag reference internal" href="#design.mps.freelist.function.finish">.function.finish:</a> Finish the free list pointed to by <tt class="docutils literal"><span class="pre">fl</span></tt>.</p>
<dl class="function">
<dt id="FreelistInsert">
<a class="reference internal" href="type.html#Res" title="Res">Res</a> <tt class="descname">FreelistInsert</tt><big>(</big><a class="reference internal" href="range.html#Range" title="Range">Range</a><em>&nbsp;rangeReturn</em>, <a class="reference internal" href="#Freelist" title="Freelist">Freelist</a><em>&nbsp;fl</em>, <a class="reference internal" href="range.html#Range" title="Range">Range</a><em>&nbsp;range</em><big>)</big><a class="headerlink" href="#FreelistInsert" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p><span class="target" id="design.mps.freelist.function.insert"></span><a class="mpstag reference internal" href="#design.mps.freelist.function.insert">.function.insert:</a> If any part of <tt class="docutils literal"><span class="pre">range</span></tt> is already in the free
list <tt class="docutils literal"><span class="pre">fl</span></tt>, then leave the free list unchanged and return
<tt class="docutils literal"><span class="pre">ResFAIL</span></tt>. Otherwise, insert <tt class="docutils literal"><span class="pre">range</span></tt> into the free list <tt class="docutils literal"><span class="pre">fl</span></tt>;
update <tt class="docutils literal"><span class="pre">rangeReturn</span></tt> to describe the contiguous isolated range
containing the inserted range (this may differ from <tt class="docutils literal"><span class="pre">range</span></tt> if there
was coalescence on either side) and return <tt class="docutils literal"><span class="pre">ResOK</span></tt>.</p>
<dl class="function">
<dt id="FreelistDelete">
<a class="reference internal" href="type.html#Res" title="Res">Res</a> <tt class="descname">FreelistDelete</tt><big>(</big><a class="reference internal" href="range.html#Range" title="Range">Range</a><em>&nbsp;rangeReturn</em>, <a class="reference internal" href="#Freelist" title="Freelist">Freelist</a><em>&nbsp;fl</em>, <a class="reference internal" href="range.html#Range" title="Range">Range</a><em>&nbsp;range</em><big>)</big><a class="headerlink" href="#FreelistDelete" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p><span class="target" id="design.mps.freelist.function.delete"></span><a class="mpstag reference internal" href="#design.mps.freelist.function.delete">.function.delete:</a> If any part of the range is not in the free list,
then leave the free list unchanged and return <tt class="docutils literal"><span class="pre">ResFAIL</span></tt>. Otherwise,
remove <tt class="docutils literal"><span class="pre">range</span></tt> from the free list and update <tt class="docutils literal"><span class="pre">rangeReturn</span></tt> to
describe the contiguous isolated range that formerly contained the
deleted range (this may differ from <tt class="docutils literal"><span class="pre">range</span></tt> if there were fragments
left on either side), and return <tt class="docutils literal"><span class="pre">ResOK</span></tt>.</p>
<dl class="function">
<dt id="FreelistIterate">
void <tt class="descname">FreelistIterate</tt><big>(</big><a class="reference internal" href="#Freelist" title="Freelist">Freelist</a><em>&nbsp;fl</em>, <a class="reference internal" href="#FreelistIterateMethod" title="FreelistIterateMethod">FreelistIterateMethod</a><em>&nbsp;iterate</em>, void<em>&nbsp;*closureP</em>, <a class="reference internal" href="type.html#Size" title="Size">Size</a><em>&nbsp;closureS</em><big>)</big><a class="headerlink" href="#FreelistIterate" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p><span class="target" id="design.mps.freelist.function.iterate"></span><a class="mpstag reference internal" href="#design.mps.freelist.function.iterate">.function.iterate:</a> Iterate all isolated contiguous ranges in the
free list <tt class="docutils literal"><span class="pre">fl</span></tt> in address order, calling <tt class="docutils literal"><span class="pre">iterate</span></tt> for each one.
See <a class="reference internal" href="#FreelistIterateMethod" title="FreelistIterateMethod"><tt class="xref c c-type docutils literal"><span class="pre">FreelistIterateMethod</span></tt></a> for details.</p>
<dl class="function">
<dt id="FreelistFindFirst">
<a class="reference internal" href="type.html#Bool" title="Bool">Bool</a> <tt class="descname">FreelistFindFirst</tt><big>(</big><a class="reference internal" href="range.html#Range" title="Range">Range</a><em>&nbsp;rangeReturn</em>, <a class="reference internal" href="range.html#Range" title="Range">Range</a><em>&nbsp;oldRangeReturn</em>, <a class="reference internal" href="#Freelist" title="Freelist">Freelist</a><em>&nbsp;fl</em>, <a class="reference internal" href="type.html#Size" title="Size">Size</a><em>&nbsp;size</em>, FindDelete<em>&nbsp;findDelete</em><big>)</big><a class="headerlink" href="#FreelistFindFirst" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p><span class="target" id="design.mps.freelist.function.find.first"></span><a class="mpstag reference internal" href="#design.mps.freelist.function.find.first">.function.find.first:</a> Locate the first isolated contiguous range in
address order, within the free list <tt class="docutils literal"><span class="pre">fl</span></tt>, of at least <tt class="docutils literal"><span class="pre">size</span></tt>
bytes, update <tt class="docutils literal"><span class="pre">rangeReturn</span></tt> to that range, and return <tt class="xref c c-macro docutils literal"><span class="pre">TRUE</span></tt>. If
there is no such continuous range, return <tt class="xref c c-macro docutils literal"><span class="pre">FALSE</span></tt>.</p>
<p>In addition, optionally delete the found range from the free list,
depending on the <tt class="docutils literal"><span class="pre">findDelete</span></tt> argument. This saves a separate call
to <a class="reference internal" href="#FreelistDelete" title="FreelistDelete"><tt class="xref c c-func docutils literal"><span class="pre">FreelistDelete()</span></tt></a>, and uses the knowledge of exactly where we
found the range. The value of <tt class="docutils literal"><span class="pre">findDelete</span></tt> must come from this
enumeration:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">enum</span> <span class="p">{</span>
<span class="n">FindDeleteNONE</span><span class="p">,</span> <span class="cm">/* don&#39;t delete after finding */</span>
<span class="n">FindDeleteLOW</span><span class="p">,</span> <span class="cm">/* delete size bytes from low end of block */</span>
<span class="n">FindDeleteHIGH</span><span class="p">,</span> <span class="cm">/* delete size bytes from high end of block */</span>
<span class="n">FindDeleteENTIRE</span> <span class="cm">/* delete entire range */</span>
<span class="p">};</span>
</pre></div>
</div>
<p>The original contiguous isolated range in which the range was found is
returned via the <tt class="docutils literal"><span class="pre">oldRangeReturn</span></tt> argument. (If <tt class="docutils literal"><span class="pre">findDelete</span></tt> is
<tt class="docutils literal"><span class="pre">FindDeleteNONE</span></tt> or <tt class="docutils literal"><span class="pre">FindDeleteENTIRE</span></tt>, then this will be
identical to the range returned via the <tt class="docutils literal"><span class="pre">rangeReturn</span></tt> argument.)</p>
<dl class="function">
<dt id="FreelistFindLast">
<a class="reference internal" href="type.html#Bool" title="Bool">Bool</a> <tt class="descname">FreelistFindLast</tt><big>(</big><a class="reference internal" href="range.html#Range" title="Range">Range</a><em>&nbsp;rangeReturn</em>, <a class="reference internal" href="range.html#Range" title="Range">Range</a><em>&nbsp;oldRangeReturn</em>, <a class="reference internal" href="#Freelist" title="Freelist">Freelist</a><em>&nbsp;fl</em>, <a class="reference internal" href="type.html#Size" title="Size">Size</a><em>&nbsp;size</em>, FindDelete<em>&nbsp;findDelete</em><big>)</big><a class="headerlink" href="#FreelistFindLast" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p><span class="target" id="design.mps.freelist.function.find.last"></span><a class="mpstag reference internal" href="#design.mps.freelist.function.find.last">.function.find.last:</a> Like <a class="reference internal" href="#FreelistFindFirst" title="FreelistFindFirst"><tt class="xref c c-func docutils literal"><span class="pre">FreelistFindFirst()</span></tt></a>, except that it
finds the last block in address order.</p>
<dl class="function">
<dt id="FreelistFindLargest">
<a class="reference internal" href="type.html#Bool" title="Bool">Bool</a> <tt class="descname">FreelistFindLargest</tt><big>(</big><a class="reference internal" href="range.html#Range" title="Range">Range</a><em>&nbsp;rangeReturn</em>, <a class="reference internal" href="range.html#Range" title="Range">Range</a><em>&nbsp;oldRangeReturn</em>, <a class="reference internal" href="#Freelist" title="Freelist">Freelist</a><em>&nbsp;fl</em>, <a class="reference internal" href="type.html#Size" title="Size">Size</a>, size, FindDelete<em>&nbsp;findDelete</em><big>)</big><a class="headerlink" href="#FreelistFindLargest" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p><span class="target" id="design.mps.freelist.function.find.largest"></span><a class="mpstag reference internal" href="#design.mps.freelist.function.find.largest">.function.find.largest:</a> Locate the largest block within the free
list <tt class="docutils literal"><span class="pre">fl</span></tt>, and if that block is at least as big as <tt class="docutils literal"><span class="pre">size</span></tt>, return
its range via the <tt class="docutils literal"><span class="pre">rangeReturn</span></tt> argument, and return <tt class="xref c c-macro docutils literal"><span class="pre">TRUE</span></tt>. If
there are no blocks in the free list at least as large as <tt class="docutils literal"><span class="pre">size</span></tt>,
return <tt class="xref c c-macro docutils literal"><span class="pre">FALSE</span></tt>. Pass 0 for <tt class="docutils literal"><span class="pre">size</span></tt> if you want the largest block
unconditionally.</p>
<p>Like <a class="reference internal" href="#FreelistFindFirst" title="FreelistFindFirst"><tt class="xref c c-func docutils literal"><span class="pre">FreelistFindFirst()</span></tt></a>, optionally delete the range from the
free list. (Always the whole range: specifying <tt class="docutils literal"><span class="pre">FindDeleteLOW</span></tt> or
<tt class="docutils literal"><span class="pre">FindDeleteHIGH</span></tt> has the same effect as <tt class="docutils literal"><span class="pre">FindDeleteENTIRE</span></tt>).</p>
<dl class="function">
<dt id="FreelistFlushToCBS">
void <tt class="descname">FreelistFlushToCBS</tt><big>(</big><a class="reference internal" href="#Freelist" title="Freelist">Freelist</a><em>&nbsp;fl</em>, <a class="reference internal" href="cbs.html#CBS" title="CBS">CBS</a><em>&nbsp;cbs</em><big>)</big><a class="headerlink" href="#FreelistFlushToCBS" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p>Remove free address ranges from the free list <tt class="docutils literal"><span class="pre">fl</span></tt> and add them to
the Coalescing Block Structure <tt class="docutils literal"><span class="pre">cbs</span></tt>. Continue until a call to
<a class="reference internal" href="cbs.html#CBSInsert" title="CBSInsert"><tt class="xref c c-func docutils literal"><span class="pre">CBSInsert()</span></tt></a> fails, or until the free list is empty, whichever
happens first.</p>
<dl class="function">
<dt id="FreelistDescribe">
<a class="reference internal" href="type.html#Res" title="Res">Res</a> <tt class="descname">FreelistDescribe</tt><big>(</big><a class="reference internal" href="#Freelist" title="Freelist">Freelist</a><em>&nbsp;fl</em>, <a class="reference internal" href="../topic/plinth.html#mps_lib_FILE" title="mps_lib_FILE">mps_lib_FILE</a><em>&nbsp;*stream</em><big>)</big><a class="headerlink" href="#FreelistDescribe" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p><span class="target" id="design.mps.freelist.function.describe"></span><a class="mpstag reference internal" href="#design.mps.freelist.function.describe">.function.describe:</a> Print a textual representation of the free
list <tt class="docutils literal"><span class="pre">fl</span></tt> to the given stream, indicating the contiguous ranges in
order. It is provided for debugging purposes only.</p>
</div>
</div>
<div class="section" id="implementation">
<h2>5.6. Implementation<a class="headerlink" href="#implementation" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.freelist.impl.list"></span><a class="mpstag reference internal" href="#design.mps.freelist.impl.list">.impl.list:</a> The isolated contiguous free address ranges are kept on
an address-ordered singly linked free list. (As in traditional
<tt class="xref c c-func docutils literal"><span class="pre">malloc()</span></tt> implementations.)</p>
<p><span class="target" id="design.mps.freelist.impl.block"></span><a class="mpstag reference internal" href="#design.mps.freelist.impl.block">.impl.block:</a> If the free address range is large enough to contain
an inline block descriptor consisting of two pointers, then the two
pointers stored are to the next free range in address order (or
<tt class="xref c c-macro docutils literal"><span class="pre">NULL</span></tt> if there are no more ranges), and to the limit of current
free address range, in that order.</p>
<p><span class="target" id="design.mps.freelist.impl.grain"></span><a class="mpstag reference internal" href="#design.mps.freelist.impl.grain">.impl.grain:</a> Otherwise, the free address range must be large enough
to contain a single pointer. The pointer stored is to the next free
range in address order, or <tt class="xref c c-macro docutils literal"><span class="pre">NULL</span></tt> if there are no more ranges.</p>
<p><span class="target" id="design.mps.freelist.impl.tag"></span><a class="mpstag reference internal" href="#design.mps.freelist.impl.tag">.impl.tag:</a> Grains and blocks are distinguished by a one-bit tag in
the low bit of the first word (the one containing the pointer to the
next range). Grains have this bit set; blocks have this bit reset.</p>
<p><span class="target" id="design.mps.freelist.impl.invariant"></span><a class="mpstag reference internal" href="#design.mps.freelist.impl.invariant">.impl.invariant:</a> The ranges stored in the free list are <em>isolated</em>:
no two ranges are adjacent or overlapping.</p>
<p><span class="target" id="design.mps.freelist.impl.merge"></span><a class="mpstag reference internal" href="#design.mps.freelist.impl.merge">.impl.merge:</a> When a free address range is added to the free list,
it is merged with adjacent ranges so as to maintain
<a class="reference internal" href="#design.mps.freelist.impl.invariant">.impl.invariant</a>.</p>
<p><span class="target" id="design.mps.freelist.impl.rule.break"></span><a class="mpstag reference internal" href="#design.mps.freelist.impl.rule.break">.impl.rule.break:</a> The use of <tt class="xref c c-macro docutils literal"><span class="pre">NULL</span></tt> to mark the end of the list
violates the rule that exceptional values should not be used to
distinguish exeptional situations. This infraction allows the
implementation to meet <a class="reference internal" href="#design.mps.freelist.req.zero-overhead">.req.zero-overhead</a>. (There are other ways to
do this, such as using another tag to indicate the last block in the
list, but these would be more complicated.)</p>
</div>
<div class="section" id="opportunities-for-improvement">
<h2>5.7. Opportunities for improvement<a class="headerlink" href="#opportunities-for-improvement" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.freelist.improve.length"></span><a class="mpstag reference internal" href="#design.mps.freelist.improve.length">.improve.length:</a> When iterating over the list, we could check that
the number of elements visited in the course of the iteration does not
exceed the recorded size of the list.</p>
<p><span class="target" id="design.mps.freelist.improve.maxsize"></span><a class="mpstag reference internal" href="#design.mps.freelist.improve.maxsize">.improve.maxsize:</a> We could maintain the maximum size of any range
on the list, and use that to make an early exit from
<a class="reference internal" href="#FreelistFindLargest" title="FreelistFindLargest"><tt class="xref c c-func docutils literal"><span class="pre">FreelistFindLargest()</span></tt></a>. It&#8217;s not clear that this would actually be
an improvement.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../index.html">
<img class="logo" src="../_static/logo.png" alt="Logo"/>
</a></p>
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">5. Free list allocator</a><ul>
<li><a class="reference internal" href="#introduction">5.1. Introduction</a></li>
<li><a class="reference internal" href="#overview">5.2. Overview</a></li>
<li><a class="reference internal" href="#definitions">5.3. Definitions</a></li>
<li><a class="reference internal" href="#requirements">5.4. Requirements</a></li>
<li><a class="reference internal" href="#interface">5.5. Interface</a><ul>
<li><a class="reference internal" href="#types">5.5.1. Types</a></li>
<li><a class="reference internal" href="#functions">5.5.2. Functions</a></li>
</ul>
</li>
<li><a class="reference internal" href="#implementation">5.6. Implementation</a></li>
<li><a class="reference internal" href="#opportunities-for-improvement">5.7. Opportunities for improvement</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="critical-path.html"
title="previous chapter">4. The critical path through the MPS</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="guide.hex.trans.html"
title="next chapter">6. Transliterating the alphabet into hexadecimal</a></p><h4>Downloads</h4>
<p class="topless">
<a href="http://www.ravenbrook.com/project/mps/release/1.111.0/">MPS Kit release 1.111.0</a><br>
<a href="http://www.ravenbrook.com/project/mps/release/">All MPS Kit releases</a>
</p>
<h4>Issues</h4>
<p class="topless">
<a href="http://www.ravenbrook.com/project/mps/issue/?action=list&amp;view=status%3dopen&amp;display=Job:Priority:Title&amp;sort=Priority">Known issues</a><br>
<a href="http://www.ravenbrook.com/project/mps/issue/?action=fixed&release_fixed=1.111.0">Issues fixed in release 1.111.0</a>
</p><h4>Contact us</h4>
<p class="topless"><a href="mailto:mps-questions@ravenbrook.com">mps-questions@ravenbrook.com</a></p>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="guide.hex.trans.html" title="6. Transliterating the alphabet into hexadecimal"
>next</a> |</li>
<li class="right" >
<a href="critical-path.html" title="4. The critical path through the MPS"
>previous</a> |</li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
<li><a href="index.html" >Design</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; <a href="../copyright.html">Copyright</a> 2013, Ravenbrook Limited.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

View file

@ -8,7 +8,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>3. Transliterating the alphabet into hexadecimal &mdash; Memory Pool System 1.111.0 documentation</title>
<title>6. Transliterating the alphabet into hexadecimal &mdash; Memory Pool System 1.111.0 documentation</title>
<link rel="stylesheet" href="../_static/mps.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
@ -28,8 +28,8 @@
<link rel="copyright" title="Copyright" href="../copyright.html" />
<link rel="top" title="Memory Pool System 1.111.0 documentation" href="../index.html" />
<link rel="up" title="Design" href="index.html" />
<link rel="next" title="4. C Style formatting" href="guide.impl.c.format.html" />
<link rel="prev" title="2. The critical path through the MPS" href="critical-path.html" />
<link rel="next" title="7. C Style formatting" href="guide.impl.c.format.html" />
<link rel="prev" title="5. Free list allocator" href="freelist.html" />
</head>
<body>
<div class="related">
@ -39,10 +39,10 @@
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="guide.impl.c.format.html" title="4. C Style formatting"
<a href="guide.impl.c.format.html" title="7. C Style formatting"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="critical-path.html" title="2. The critical path through the MPS"
<a href="freelist.html" title="5. Free list allocator"
accesskey="P">previous</a> |</li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
<li><a href="index.html" accesskey="U">Design</a> &raquo;</li>
@ -55,9 +55,9 @@
<div class="body">
<span class="target" id="design-guide-hex-trans"></span><div class="section" id="transliterating-the-alphabet-into-hexadecimal">
<span id="index-0"></span><h1>3. Transliterating the alphabet into hexadecimal<a class="headerlink" href="#transliterating-the-alphabet-into-hexadecimal" title="Permalink to this headline"></a></h1>
<span id="index-0"></span><h1>6. Transliterating the alphabet into hexadecimal<a class="headerlink" href="#transliterating-the-alphabet-into-hexadecimal" title="Permalink to this headline"></a></h1>
<div class="section" id="introduction">
<span id="guide.hex.trans"></span><h2>3.1. Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline"></a></h2>
<span id="guide.hex.trans"></span><h2>6.1. Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline"></a></h2>
<p><span class="target" id="guide.hex.trans.scope"></span><a class="mpstag reference internal" href="#guide.hex.trans.scope">.scope:</a> This document explains how to represent the alphabet as
hexadecimal digits.</p>
<p><span class="target" id="guide.hex.trans.readership"></span><a class="mpstag reference internal" href="#guide.hex.trans.readership">.readership:</a> This document is intended for anyone devising
@ -66,7 +66,7 @@ arbitrary constants which may appear in hex-dumps.</p>
mail.richardk.1997-04-07.13-44.</p>
</div>
<div class="section" id="transliteration">
<h2>3.2. Transliteration<a class="headerlink" href="#transliteration" title="Permalink to this headline"></a></h2>
<h2>6.2. Transliteration<a class="headerlink" href="#transliteration" title="Permalink to this headline"></a></h2>
<p><span class="target" id="guide.hex.trans.forward"></span><a class="mpstag reference internal" href="#guide.hex.trans.forward">.forward:</a> The chosen transliteration is as follows:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="n">ABCDEFGHIJKLMNOPQRSTUVWXYZ</span>
<span class="n">ABCDEF9811C7340BC6520F3812</span>
@ -98,7 +98,7 @@ context.</p>
suggested that you use 9 (as <a class="reference internal" href="#guide.hex.trans.pad">.pad</a>).</p>
</div>
<div class="section" id="justification">
<h2>3.3. Justification<a class="headerlink" href="#justification" title="Permalink to this headline"></a></h2>
<h2>6.3. Justification<a class="headerlink" href="#justification" title="Permalink to this headline"></a></h2>
<p><span class="target" id="guide.hex.trans.letters"></span><a class="mpstag reference internal" href="#guide.hex.trans.letters">.letters:</a> The hexadecimal letters (A-F) are all formed by
similarity of sound. B and P sound similar, as do F and V, and C, K, &amp;
Q can all sound similar.</p>
@ -109,7 +109,7 @@ sound.</p>
letter that it deserves it.</p>
</div>
<div class="section" id="notes">
<h2>3.4. Notes<a class="headerlink" href="#notes" title="Permalink to this headline"></a></h2>
<h2>6.4. Notes<a class="headerlink" href="#notes" title="Permalink to this headline"></a></h2>
<p><span class="target" id="guide.hex.trans.change"></span><a class="mpstag reference internal" href="#guide.hex.trans.change">.change:</a> This transliteration differs from the old transliteration
used for signatures (see design.mps.sig(0)), as follows: J:6-&gt;1;
L:1-&gt;7; N:9-&gt;4; R:4-&gt;6; W:8-&gt;3; X:5-&gt;8; Y:E-&gt;I.</p>
@ -143,21 +143,21 @@ selected (by capitalisation), e.g.:</p>
</a></p>
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">3. Transliterating the alphabet into hexadecimal</a><ul>
<li><a class="reference internal" href="#introduction">3.1. Introduction</a></li>
<li><a class="reference internal" href="#transliteration">3.2. Transliteration</a></li>
<li><a class="reference internal" href="#justification">3.3. Justification</a></li>
<li><a class="reference internal" href="#notes">3.4. Notes</a></li>
<li><a class="reference internal" href="#">6. Transliterating the alphabet into hexadecimal</a><ul>
<li><a class="reference internal" href="#introduction">6.1. Introduction</a></li>
<li><a class="reference internal" href="#transliteration">6.2. Transliteration</a></li>
<li><a class="reference internal" href="#justification">6.3. Justification</a></li>
<li><a class="reference internal" href="#notes">6.4. Notes</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="critical-path.html"
title="previous chapter">2. The critical path through the MPS</a></p>
<p class="topless"><a href="freelist.html"
title="previous chapter">5. Free list allocator</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="guide.impl.c.format.html"
title="next chapter">4. C Style &#8211; formatting</a></p><h4>Downloads</h4>
title="next chapter">7. C Style &#8211; formatting</a></p><h4>Downloads</h4>
<p class="topless">
<a href="http://www.ravenbrook.com/project/mps/release/1.111.0/">MPS Kit release 1.111.0</a><br>
@ -183,10 +183,10 @@ selected (by capitalisation), e.g.:</p>
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="guide.impl.c.format.html" title="4. C Style formatting"
<a href="guide.impl.c.format.html" title="7. C Style formatting"
>next</a> |</li>
<li class="right" >
<a href="critical-path.html" title="2. The critical path through the MPS"
<a href="freelist.html" title="5. Free list allocator"
>previous</a> |</li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
<li><a href="index.html" >Design</a> &raquo;</li>

View file

@ -8,7 +8,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>4. C Style formatting &mdash; Memory Pool System 1.111.0 documentation</title>
<title>7. C Style formatting &mdash; Memory Pool System 1.111.0 documentation</title>
<link rel="stylesheet" href="../_static/mps.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
@ -28,8 +28,8 @@
<link rel="copyright" title="Copyright" href="../copyright.html" />
<link rel="top" title="Memory Pool System 1.111.0 documentation" href="../index.html" />
<link rel="up" title="Design" href="index.html" />
<link rel="next" title="5. Keyword arguments in the MPS" href="keyword-arguments.html" />
<link rel="prev" title="3. Transliterating the alphabet into hexadecimal" href="guide.hex.trans.html" />
<link rel="next" title="8. Keyword arguments in the MPS" href="keyword-arguments.html" />
<link rel="prev" title="6. Transliterating the alphabet into hexadecimal" href="guide.hex.trans.html" />
</head>
<body>
<div class="related">
@ -39,10 +39,10 @@
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="keyword-arguments.html" title="5. Keyword arguments in the MPS"
<a href="keyword-arguments.html" title="8. Keyword arguments in the MPS"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="guide.hex.trans.html" title="3. Transliterating the alphabet into hexadecimal"
<a href="guide.hex.trans.html" title="6. Transliterating the alphabet into hexadecimal"
accesskey="P">previous</a> |</li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
<li><a href="index.html" accesskey="U">Design</a> &raquo;</li>
@ -55,18 +55,18 @@
<div class="body">
<span class="target" id="design-guide-impl-c-format"></span><div class="section" id="c-style-formatting">
<span id="index-0"></span><h1>4. C Style &#8211; formatting<a class="headerlink" href="#c-style-formatting" title="Permalink to this headline"></a></h1>
<span id="index-0"></span><h1>7. C Style &#8211; formatting<a class="headerlink" href="#c-style-formatting" title="Permalink to this headline"></a></h1>
<div class="section" id="introduction">
<span id="guide.impl.c.format"></span><h2>4.1. Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline"></a></h2>
<span id="guide.impl.c.format"></span><h2>7.1. Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline"></a></h2>
<p><span class="target" id="guide.impl.c.format.scope"></span><a class="mpstag reference internal" href="#guide.impl.c.format.scope">.scope:</a> This document describes the Ravenbrook conventions for the
general format of C source code in the MPS.</p>
<p><span class="target" id="guide.impl.c.format.readership"></span><a class="mpstag reference internal" href="#guide.impl.c.format.readership">.readership:</a> This document is intended for anyone working on or with the
C source code.</p>
</div>
<div class="section" id="general-formatting-conventions">
<h2>4.2. General Formatting Conventions<a class="headerlink" href="#general-formatting-conventions" title="Permalink to this headline"></a></h2>
<h2>7.2. General Formatting Conventions<a class="headerlink" href="#general-formatting-conventions" title="Permalink to this headline"></a></h2>
<div class="section" id="line-width">
<h3>4.2.1. Line Width<a class="headerlink" href="#line-width" title="Permalink to this headline"></a></h3>
<h3>7.2.1. Line Width<a class="headerlink" href="#line-width" title="Permalink to this headline"></a></h3>
<p><span class="target" id="guide.impl.c.format.width"></span><a class="mpstag reference internal" href="#guide.impl.c.format.width">.width:</a> Lines should be no wider than 72 characters. <span class="target" id="guide.impl.c.format.width.why"></span><a class="mpstag reference internal" href="#guide.impl.c.format.width.why">.width.why:</a> Many
people use 80 column terminal windows so that multiple windows can be
placed side by side. Restricting lines to 72 characters allows line
@ -74,7 +74,7 @@ numbering to be used (in vi for example) and also allows diffs to be
displayed without overflowing the terminal.</p>
</div>
<div class="section" id="white-space">
<h3>4.2.2. White Space<a class="headerlink" href="#white-space" title="Permalink to this headline"></a></h3>
<h3>7.2.2. White Space<a class="headerlink" href="#white-space" title="Permalink to this headline"></a></h3>
<p><span class="target" id="guide.impl.c.format.space.notab"></span><a class="mpstag reference internal" href="#guide.impl.c.format.space.notab">.space.notab:</a> No tab characters should appear in the source files.
Ordinary spaces should be used to indent and format the sources.
<span class="target" id="guide.impl.c.format.space.notab.why"></span><a class="mpstag reference internal" href="#guide.impl.c.format.space.notab.why">.space.notab.why:</a> Tab characters are displayed differently on different
@ -96,7 +96,7 @@ distinguish them visually and when searching with tools like grep.</p>
paren beginning its argument list.</p>
</div>
<div class="section" id="sections-and-paragraphs">
<h3>4.2.3. Sections and Paragraphs<a class="headerlink" href="#sections-and-paragraphs" title="Permalink to this headline"></a></h3>
<h3>7.2.3. Sections and Paragraphs<a class="headerlink" href="#sections-and-paragraphs" title="Permalink to this headline"></a></h3>
<p><span class="target" id="guide.impl.c.format.section"></span><a class="mpstag reference internal" href="#guide.impl.c.format.section">.section:</a> Source files can be thought of as breaking down into
&#8220;sections&#8221; and &#8220;paragraphs&#8221;. A section might be the leader comment of a
file, the imports, or a set of declarations which are related.</p>
@ -112,7 +112,7 @@ a structure, for example).</p>
<p><span class="target" id="guide.impl.c.format.para.space"></span><a class="mpstag reference internal" href="#guide.impl.c.format.para.space">.para.space:</a> Precede paragraphs by a single blank line.</p>
</div>
<div class="section" id="statements">
<h3>4.2.4. Statements<a class="headerlink" href="#statements" title="Permalink to this headline"></a></h3>
<h3>7.2.4. Statements<a class="headerlink" href="#statements" title="Permalink to this headline"></a></h3>
<p><span class="target" id="guide.impl.c.format.statement.one"></span><a class="mpstag reference internal" href="#guide.impl.c.format.statement.one">.statement.one:</a> Generally only have at most one statement per line. In
particular the following are deprecated:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">if</span> <span class="p">(</span><span class="n">thing</span><span class="p">)</span> <span class="k">return</span><span class="p">;</span>
@ -130,7 +130,7 @@ Annoying because <tt class="docutils literal"><span class="pre">if</span> <span
otherwise.</p>
</div>
<div class="section" id="indentation">
<h3>4.2.5. Indentation<a class="headerlink" href="#indentation" title="Permalink to this headline"></a></h3>
<h3>7.2.5. Indentation<a class="headerlink" href="#indentation" title="Permalink to this headline"></a></h3>
<p><span class="target" id="guide.impl.c.format.indent"></span><a class="mpstag reference internal" href="#guide.impl.c.format.indent">.indent:</a> Indent the body of a block by two spaces. For formatting
purposes, the &#8220;body of a block&#8221; means:</p>
<ul class="simple">
@ -221,7 +221,7 @@ two more spaces. The main exceptions are lines starting with a close
brace, goto-labels, and line-breaks between parentheses.</p>
</div>
<div class="section" id="positioning-of-braces">
<h3>4.2.6. Positioning of Braces<a class="headerlink" href="#positioning-of-braces" title="Permalink to this headline"></a></h3>
<h3>7.2.6. Positioning of Braces<a class="headerlink" href="#positioning-of-braces" title="Permalink to this headline"></a></h3>
<p><span class="target" id="guide.impl.c.format.brace.otb"></span><a class="mpstag reference internal" href="#guide.impl.c.format.brace.otb">.brace.otb:</a> Use the &#8220;One True Brace&#8221; (or OTB) style. This places the
open brace after the control word or expression, separated by a space,
and when there is an else, places that after the close brace. For
@ -256,7 +256,7 @@ this will be a <tt class="docutils literal"><span class="pre">goto</span></tt> o
paths.</p>
</div>
<div class="section" id="switch-statements">
<h3>4.2.7. Switch Statements<a class="headerlink" href="#switch-statements" title="Permalink to this headline"></a></h3>
<h3>7.2.7. Switch Statements<a class="headerlink" href="#switch-statements" title="Permalink to this headline"></a></h3>
<p><span class="target" id="guide.impl.c.format.switch"></span><a class="mpstag reference internal" href="#guide.impl.c.format.switch">.switch:</a> format switch statements like this:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">switch</span> <span class="p">(</span><span class="n">action</span><span class="p">)</span> <span class="p">{</span>
<span class="k">case</span> <span class="n">WIBBLE</span>:
@ -295,7 +295,7 @@ even if all it contains is <tt class="xref c c-macro docutils literal"><span cla
<tt class="xref c c-macro docutils literal"><span class="pre">NOTREACHED</span></tt> doesn&#8217;t stop the process in all build varieties.</p>
</div>
<div class="section" id="formatting-comments">
<h3>4.2.8. Formatting Comments<a class="headerlink" href="#formatting-comments" title="Permalink to this headline"></a></h3>
<h3>7.2.8. Formatting Comments<a class="headerlink" href="#formatting-comments" title="Permalink to this headline"></a></h3>
<p><span class="target" id="guide.impl.c.format.comment"></span><a class="mpstag reference internal" href="#guide.impl.c.format.comment">.comment:</a> There are three types of comments: banners, paragraph
comments, and columnar comments.</p>
<p><span class="target" id="guide.impl.c.format.comment.banner"></span><a class="mpstag reference internal" href="#guide.impl.c.format.comment.banner">.comment.banner:</a> Banner comments come at the start of sections. A banner
@ -349,7 +349,7 @@ comment clearer. Don&#8217;t write more than one line. Here&#8217;s an example:<
</div>
</div>
<div class="section" id="macros">
<h3>4.2.9. Macros<a class="headerlink" href="#macros" title="Permalink to this headline"></a></h3>
<h3>7.2.9. Macros<a class="headerlink" href="#macros" title="Permalink to this headline"></a></h3>
<p><span class="target" id="guide.impl.c.format.macro.careful"></span><a class="mpstag reference internal" href="#guide.impl.c.format.macro.careful">.macro.careful:</a> Macros in C are a real horror bag, be extra careful.
There&#8217;s lots that could go here, but proper coverage probably deserves a
separate document. Which isn&#8217;t written yet.</p>
@ -369,7 +369,7 @@ in the way. Example:</p>
</div>
</div>
<div class="section" id="history">
<h2>4.3. History<a class="headerlink" href="#history" title="Permalink to this headline"></a></h2>
<h2>7.3. History<a class="headerlink" href="#history" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li>2007-06-04 <a class="reference external" href="http://www.ravenbrook.com/consultants/drj">DRJ</a> Adopted from Harlequin MMinfo version and edited.</li>
<li>2007-06-04 <a class="reference external" href="http://www.ravenbrook.com/consultants/drj">DRJ</a> Changed .width from 80 to 72. Banned space between
@ -386,7 +386,7 @@ switch &#8220;law&#8221;.</li>
</ul>
</div>
<div class="section" id="copyright-and-license">
<h2>4.4. Copyright and License<a class="headerlink" href="#copyright-and-license" title="Permalink to this headline"></a></h2>
<h2>7.4. Copyright and License<a class="headerlink" href="#copyright-and-license" title="Permalink to this headline"></a></h2>
<p>This document is copyright © 2002-2012 [Ravenbrook
Limited](<a class="reference external" href="http://www.ravenbrook.com/">http://www.ravenbrook.com/</a>). All rights reserved. This is an
open source license. Contact Ravenbrook for commercial licensing
@ -437,32 +437,32 @@ possibility of such damage.</strong></p>
</a></p>
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">4. C Style &#8211; formatting</a><ul>
<li><a class="reference internal" href="#introduction">4.1. Introduction</a></li>
<li><a class="reference internal" href="#general-formatting-conventions">4.2. General Formatting Conventions</a><ul>
<li><a class="reference internal" href="#line-width">4.2.1. Line Width</a></li>
<li><a class="reference internal" href="#white-space">4.2.2. White Space</a></li>
<li><a class="reference internal" href="#sections-and-paragraphs">4.2.3. Sections and Paragraphs</a></li>
<li><a class="reference internal" href="#statements">4.2.4. Statements</a></li>
<li><a class="reference internal" href="#indentation">4.2.5. Indentation</a></li>
<li><a class="reference internal" href="#positioning-of-braces">4.2.6. Positioning of Braces</a></li>
<li><a class="reference internal" href="#switch-statements">4.2.7. Switch Statements</a></li>
<li><a class="reference internal" href="#formatting-comments">4.2.8. Formatting Comments</a></li>
<li><a class="reference internal" href="#macros">4.2.9. Macros</a></li>
<li><a class="reference internal" href="#">7. C Style &#8211; formatting</a><ul>
<li><a class="reference internal" href="#introduction">7.1. Introduction</a></li>
<li><a class="reference internal" href="#general-formatting-conventions">7.2. General Formatting Conventions</a><ul>
<li><a class="reference internal" href="#line-width">7.2.1. Line Width</a></li>
<li><a class="reference internal" href="#white-space">7.2.2. White Space</a></li>
<li><a class="reference internal" href="#sections-and-paragraphs">7.2.3. Sections and Paragraphs</a></li>
<li><a class="reference internal" href="#statements">7.2.4. Statements</a></li>
<li><a class="reference internal" href="#indentation">7.2.5. Indentation</a></li>
<li><a class="reference internal" href="#positioning-of-braces">7.2.6. Positioning of Braces</a></li>
<li><a class="reference internal" href="#switch-statements">7.2.7. Switch Statements</a></li>
<li><a class="reference internal" href="#formatting-comments">7.2.8. Formatting Comments</a></li>
<li><a class="reference internal" href="#macros">7.2.9. Macros</a></li>
</ul>
</li>
<li><a class="reference internal" href="#history">4.3. History</a></li>
<li><a class="reference internal" href="#copyright-and-license">4.4. Copyright and License</a></li>
<li><a class="reference internal" href="#history">7.3. History</a></li>
<li><a class="reference internal" href="#copyright-and-license">7.4. Copyright and License</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="guide.hex.trans.html"
title="previous chapter">3. Transliterating the alphabet into hexadecimal</a></p>
title="previous chapter">6. Transliterating the alphabet into hexadecimal</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="keyword-arguments.html"
title="next chapter">5. Keyword arguments in the MPS</a></p><h4>Downloads</h4>
title="next chapter">8. Keyword arguments in the MPS</a></p><h4>Downloads</h4>
<p class="topless">
<a href="http://www.ravenbrook.com/project/mps/release/1.111.0/">MPS Kit release 1.111.0</a><br>
@ -488,10 +488,10 @@ possibility of such damage.</strong></p>
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="keyword-arguments.html" title="5. Keyword arguments in the MPS"
<a href="keyword-arguments.html" title="8. Keyword arguments in the MPS"
>next</a> |</li>
<li class="right" >
<a href="guide.hex.trans.html" title="3. Transliterating the alphabet into hexadecimal"
<a href="guide.hex.trans.html" title="6. Transliterating the alphabet into hexadecimal"
>previous</a> |</li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
<li><a href="index.html" >Design</a> &raquo;</li>

View file

@ -27,7 +27,7 @@
<script type="text/javascript" src="../_static/doctools.js"></script>
<link rel="copyright" title="Copyright" href="../copyright.html" />
<link rel="top" title="Memory Pool System 1.111.0 documentation" href="../index.html" />
<link rel="next" title="1. MPS Configuration" href="config.html" />
<link rel="next" title="1. Queue design" href="abq.html" />
<link rel="prev" title="13. SNC (Stack No Checking)" href="../pool/snc.html" />
</head>
<body>
@ -38,7 +38,7 @@
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="config.html" title="1. MPS Configuration"
<a href="abq.html" title="1. Queue design"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="../pool/snc.html" title="13. SNC (Stack No Checking)"
@ -56,101 +56,147 @@
<span id="id1"></span><h1>Design<a class="headerlink" href="#design" title="Permalink to this headline"></a></h1>
<div class="toctree-wrapper compound">
<ul>
<li class="toctree-l1"><a class="reference internal" href="config.html">1. MPS Configuration</a><ul>
<li class="toctree-l2"><a class="reference internal" href="config.html#introduction">1.1. Introduction</a></li>
<li class="toctree-l2"><a class="reference internal" href="config.html#requirements">1.2. Requirements</a><ul>
<li class="toctree-l3"><a class="reference internal" href="config.html#retired-requirements">1.2.1. Retired requirements</a></li>
<li class="toctree-l1"><a class="reference internal" href="abq.html">1. Queue design</a><ul>
<li class="toctree-l2"><a class="reference internal" href="abq.html#introduction">1.1. Introduction</a></li>
<li class="toctree-l2"><a class="reference internal" href="abq.html#requirements">1.2. Requirements</a></li>
<li class="toctree-l2"><a class="reference internal" href="abq.html#interface">1.3. Interface</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="config.html#definitions">1.3. Definitions</a></li>
<li class="toctree-l2"><a class="reference internal" href="config.html#overview">1.4. Overview</a></li>
<li class="toctree-l2"><a class="reference internal" href="config.html#the-build-system">1.5. The build system</a><ul>
<li class="toctree-l3"><a class="reference internal" href="config.html#abstract-build-function">1.5.1. Abstract build function</a></li>
<li class="toctree-l3"><a class="reference internal" href="config.html#file-structure">1.5.2. File Structure</a></li>
<li class="toctree-l3"><a class="reference internal" href="config.html#modules-and-naming">1.5.3. Modules and naming</a></li>
<li class="toctree-l3"><a class="reference internal" href="config.html#build-system-rationale">1.5.4. Build system rationale</a></li>
<li class="toctree-l1"><a class="reference internal" href="cbs.html">2. Coalescing block structure</a><ul>
<li class="toctree-l2"><a class="reference internal" href="cbs.html#introduction">2.1. Introduction</a></li>
<li class="toctree-l2"><a class="reference internal" href="cbs.html#definitions">2.2. Definitions</a></li>
<li class="toctree-l2"><a class="reference internal" href="cbs.html#requirements">2.3. Requirements</a></li>
<li class="toctree-l2"><a class="reference internal" href="cbs.html#interface">2.4. Interface</a><ul>
<li class="toctree-l3"><a class="reference internal" href="cbs.html#external-types">2.4.1. External types</a></li>
<li class="toctree-l3"><a class="reference internal" href="cbs.html#external-functions">2.4.2. External functions</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="config.html#implementation">1.6. Implementation</a><ul>
<li class="toctree-l3"><a class="reference internal" href="config.html#target-platform-detection">1.6.1. Target platform detection</a></li>
<li class="toctree-l3"><a class="reference internal" href="config.html#target-varieties">1.6.2. Target varieties</a></li>
<li class="toctree-l2"><a class="reference internal" href="cbs.html#implementation">2.5. Implementation</a><ul>
<li class="toctree-l3"><a class="reference internal" href="cbs.html#splay-tree">2.5.1. Splay tree</a></li>
<li class="toctree-l3"><a class="reference internal" href="cbs.html#low-memory-behaviour">2.5.2. Low memory behaviour</a></li>
<li class="toctree-l3"><a class="reference internal" href="cbs.html#the-cbs-block">2.5.3. The CBS block</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="config.html#source-code-configuration">1.7. Source code configuration</a><ul>
<li class="toctree-l3"><a class="reference internal" href="config.html#configuration-parameters">1.7.1. Configuration Parameters</a></li>
<li class="toctree-l3"><a class="reference internal" href="config.html#abstract-and-concrete-module-interfaces">1.7.2. Abstract and Concrete Module Interfaces</a></li>
<li class="toctree-l2"><a class="reference internal" href="cbs.html#testing">2.6. Testing</a></li>
<li class="toctree-l2"><a class="reference internal" href="cbs.html#notes-for-future-development">2.7. Notes for future development</a></li>
<li class="toctree-l2"><a class="reference internal" href="cbs.html#risks">2.8. Risks</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="config.html#to-document">1.8. To document</a></li>
<li class="toctree-l2"><a class="reference internal" href="config.html#references">1.9. References</a></li>
<li class="toctree-l1"><a class="reference internal" href="config.html">3. MPS Configuration</a><ul>
<li class="toctree-l2"><a class="reference internal" href="config.html#introduction">3.1. Introduction</a></li>
<li class="toctree-l2"><a class="reference internal" href="config.html#requirements">3.2. Requirements</a><ul>
<li class="toctree-l3"><a class="reference internal" href="config.html#retired-requirements">3.2.1. Retired requirements</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="critical-path.html">2. The critical path through the MPS</a><ul>
<li class="toctree-l2"><a class="reference internal" href="critical-path.html#introduction">2.1. Introduction</a></li>
<li class="toctree-l2"><a class="reference internal" href="critical-path.html#what-makes-the-critical-path-critical">2.2. What makes the critical path critical</a></li>
<li class="toctree-l2"><a class="reference internal" href="critical-path.html#how-the-mps-avoids-scanning-and-fixing">2.3. How the MPS avoids scanning and fixing</a></li>
<li class="toctree-l2"><a class="reference internal" href="critical-path.html#where-to-find-the-critical-path">2.4. Where to find the critical path</a></li>
<li class="toctree-l2"><a class="reference internal" href="critical-path.html#the-format-scanner">2.5. The format scanner</a></li>
<li class="toctree-l2"><a class="reference internal" href="critical-path.html#the-second-stage-fix-in-the-mpm">2.6. The second stage fix in the MPM</a></li>
<li class="toctree-l2"><a class="reference internal" href="critical-path.html#the-third-stage-fix-in-the-pool-class">2.7. The third stage fix in the pool class</a></li>
<li class="toctree-l2"><a class="reference internal" href="critical-path.html#other-considerations">2.8. Other considerations</a></li>
<li class="toctree-l2"><a class="reference internal" href="critical-path.html#references">2.9. References</a></li>
<li class="toctree-l2"><a class="reference internal" href="config.html#definitions">3.3. Definitions</a></li>
<li class="toctree-l2"><a class="reference internal" href="config.html#overview">3.4. Overview</a></li>
<li class="toctree-l2"><a class="reference internal" href="config.html#the-build-system">3.5. The build system</a><ul>
<li class="toctree-l3"><a class="reference internal" href="config.html#abstract-build-function">3.5.1. Abstract build function</a></li>
<li class="toctree-l3"><a class="reference internal" href="config.html#file-structure">3.5.2. File Structure</a></li>
<li class="toctree-l3"><a class="reference internal" href="config.html#modules-and-naming">3.5.3. Modules and naming</a></li>
<li class="toctree-l3"><a class="reference internal" href="config.html#build-system-rationale">3.5.4. Build system rationale</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="guide.hex.trans.html">3. Transliterating the alphabet into hexadecimal</a><ul>
<li class="toctree-l2"><a class="reference internal" href="guide.hex.trans.html#introduction">3.1. Introduction</a></li>
<li class="toctree-l2"><a class="reference internal" href="guide.hex.trans.html#transliteration">3.2. Transliteration</a></li>
<li class="toctree-l2"><a class="reference internal" href="guide.hex.trans.html#justification">3.3. Justification</a></li>
<li class="toctree-l2"><a class="reference internal" href="guide.hex.trans.html#notes">3.4. Notes</a></li>
<li class="toctree-l2"><a class="reference internal" href="config.html#implementation">3.6. Implementation</a><ul>
<li class="toctree-l3"><a class="reference internal" href="config.html#target-platform-detection">3.6.1. Target platform detection</a></li>
<li class="toctree-l3"><a class="reference internal" href="config.html#target-varieties">3.6.2. Target varieties</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="guide.impl.c.format.html">4. C Style &#8211; formatting</a><ul>
<li class="toctree-l2"><a class="reference internal" href="guide.impl.c.format.html#introduction">4.1. Introduction</a></li>
<li class="toctree-l2"><a class="reference internal" href="guide.impl.c.format.html#general-formatting-conventions">4.2. General Formatting Conventions</a><ul>
<li class="toctree-l3"><a class="reference internal" href="guide.impl.c.format.html#line-width">4.2.1. Line Width</a></li>
<li class="toctree-l3"><a class="reference internal" href="guide.impl.c.format.html#white-space">4.2.2. White Space</a></li>
<li class="toctree-l3"><a class="reference internal" href="guide.impl.c.format.html#sections-and-paragraphs">4.2.3. Sections and Paragraphs</a></li>
<li class="toctree-l3"><a class="reference internal" href="guide.impl.c.format.html#statements">4.2.4. Statements</a></li>
<li class="toctree-l3"><a class="reference internal" href="guide.impl.c.format.html#indentation">4.2.5. Indentation</a></li>
<li class="toctree-l3"><a class="reference internal" href="guide.impl.c.format.html#positioning-of-braces">4.2.6. Positioning of Braces</a></li>
<li class="toctree-l3"><a class="reference internal" href="guide.impl.c.format.html#switch-statements">4.2.7. Switch Statements</a></li>
<li class="toctree-l3"><a class="reference internal" href="guide.impl.c.format.html#formatting-comments">4.2.8. Formatting Comments</a></li>
<li class="toctree-l3"><a class="reference internal" href="guide.impl.c.format.html#macros">4.2.9. Macros</a></li>
<li class="toctree-l2"><a class="reference internal" href="config.html#source-code-configuration">3.7. Source code configuration</a><ul>
<li class="toctree-l3"><a class="reference internal" href="config.html#configuration-parameters">3.7.1. Configuration Parameters</a></li>
<li class="toctree-l3"><a class="reference internal" href="config.html#abstract-and-concrete-module-interfaces">3.7.2. Abstract and Concrete Module Interfaces</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="guide.impl.c.format.html#history">4.3. History</a></li>
<li class="toctree-l2"><a class="reference internal" href="guide.impl.c.format.html#copyright-and-license">4.4. Copyright and License</a></li>
<li class="toctree-l2"><a class="reference internal" href="config.html#to-document">3.8. To document</a></li>
<li class="toctree-l2"><a class="reference internal" href="config.html#references">3.9. References</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="keyword-arguments.html">5. Keyword arguments in the MPS</a><ul>
<li class="toctree-l2"><a class="reference internal" href="keyword-arguments.html#introduction">5.1. Introduction</a></li>
<li class="toctree-l2"><a class="reference internal" href="keyword-arguments.html#overview">5.2. Overview</a></li>
<li class="toctree-l2"><a class="reference internal" href="keyword-arguments.html#internals">5.3. Internals</a></li>
<li class="toctree-l2"><a class="reference internal" href="keyword-arguments.html#the-varargs-legacy">5.4. The varargs legacy</a></li>
<li class="toctree-l2"><a class="reference internal" href="keyword-arguments.html#references">5.5. References</a></li>
<li class="toctree-l1"><a class="reference internal" href="critical-path.html">4. The critical path through the MPS</a><ul>
<li class="toctree-l2"><a class="reference internal" href="critical-path.html#introduction">4.1. Introduction</a></li>
<li class="toctree-l2"><a class="reference internal" href="critical-path.html#what-makes-the-critical-path-critical">4.2. What makes the critical path critical</a></li>
<li class="toctree-l2"><a class="reference internal" href="critical-path.html#how-the-mps-avoids-scanning-and-fixing">4.3. How the MPS avoids scanning and fixing</a></li>
<li class="toctree-l2"><a class="reference internal" href="critical-path.html#where-to-find-the-critical-path">4.4. Where to find the critical path</a></li>
<li class="toctree-l2"><a class="reference internal" href="critical-path.html#the-format-scanner">4.5. The format scanner</a></li>
<li class="toctree-l2"><a class="reference internal" href="critical-path.html#the-second-stage-fix-in-the-mpm">4.6. The second stage fix in the MPM</a></li>
<li class="toctree-l2"><a class="reference internal" href="critical-path.html#the-third-stage-fix-in-the-pool-class">4.7. The third stage fix in the pool class</a></li>
<li class="toctree-l2"><a class="reference internal" href="critical-path.html#other-considerations">4.8. Other considerations</a></li>
<li class="toctree-l2"><a class="reference internal" href="critical-path.html#references">4.9. References</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="ring.html">6. Ring data structure</a><ul>
<li class="toctree-l2"><a class="reference internal" href="ring.html#introduction">6.1. Introduction</a></li>
<li class="toctree-l2"><a class="reference internal" href="ring.html#description">6.2. Description</a></li>
<li class="toctree-l2"><a class="reference internal" href="ring.html#init-finish">6.3. Init / Finish</a></li>
<li class="toctree-l2"><a class="reference internal" href="ring.html#iteration">6.4. Iteration</a></li>
<li class="toctree-l2"><a class="reference internal" href="ring.html#subclass">6.5. Subclass</a></li>
<li class="toctree-l2"><a class="reference internal" href="ring.html#append-remove">6.6. Append / Remove</a></li>
<li class="toctree-l2"><a class="reference internal" href="ring.html#naming">6.7. Naming</a></li>
<li class="toctree-l2"><a class="reference internal" href="ring.html#deques">6.8. Deques</a></li>
<li class="toctree-l2"><a class="reference internal" href="ring.html#defects">6.9. Defects</a></li>
<li class="toctree-l1"><a class="reference internal" href="freelist.html">5. Free list allocator</a><ul>
<li class="toctree-l2"><a class="reference internal" href="freelist.html#introduction">5.1. Introduction</a></li>
<li class="toctree-l2"><a class="reference internal" href="freelist.html#overview">5.2. Overview</a></li>
<li class="toctree-l2"><a class="reference internal" href="freelist.html#definitions">5.3. Definitions</a></li>
<li class="toctree-l2"><a class="reference internal" href="freelist.html#requirements">5.4. Requirements</a></li>
<li class="toctree-l2"><a class="reference internal" href="freelist.html#interface">5.5. Interface</a><ul>
<li class="toctree-l3"><a class="reference internal" href="freelist.html#types">5.5.1. Types</a></li>
<li class="toctree-l3"><a class="reference internal" href="freelist.html#functions">5.5.2. Functions</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="sig.html">7. Signatures in the MPS</a><ul>
<li class="toctree-l2"><a class="reference internal" href="sig.html#introduction">7.1. Introduction</a></li>
<li class="toctree-l2"><a class="reference internal" href="sig.html#overview">7.2. Overview</a></li>
<li class="toctree-l2"><a class="reference internal" href="sig.html#definitions">7.3. Definitions</a></li>
<li class="toctree-l2"><a class="reference internal" href="sig.html#init-and-finish">7.4. Init and Finish</a></li>
<li class="toctree-l2"><a class="reference internal" href="sig.html#checking">7.5. Checking</a></li>
<li class="toctree-l2"><a class="reference internal" href="sig.html#rules">7.6. Rules</a></li>
<li class="toctree-l2"><a class="reference internal" href="sig.html#tools">7.7. Tools</a></li>
<li class="toctree-l2"><a class="reference internal" href="sig.html#references">7.8. References</a></li>
<li class="toctree-l2"><a class="reference internal" href="freelist.html#implementation">5.6. Implementation</a></li>
<li class="toctree-l2"><a class="reference internal" href="freelist.html#opportunities-for-improvement">5.7. Opportunities for improvement</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="guide.hex.trans.html">6. Transliterating the alphabet into hexadecimal</a><ul>
<li class="toctree-l2"><a class="reference internal" href="guide.hex.trans.html#introduction">6.1. Introduction</a></li>
<li class="toctree-l2"><a class="reference internal" href="guide.hex.trans.html#transliteration">6.2. Transliteration</a></li>
<li class="toctree-l2"><a class="reference internal" href="guide.hex.trans.html#justification">6.3. Justification</a></li>
<li class="toctree-l2"><a class="reference internal" href="guide.hex.trans.html#notes">6.4. Notes</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="guide.impl.c.format.html">7. C Style &#8211; formatting</a><ul>
<li class="toctree-l2"><a class="reference internal" href="guide.impl.c.format.html#introduction">7.1. Introduction</a></li>
<li class="toctree-l2"><a class="reference internal" href="guide.impl.c.format.html#general-formatting-conventions">7.2. General Formatting Conventions</a><ul>
<li class="toctree-l3"><a class="reference internal" href="guide.impl.c.format.html#line-width">7.2.1. Line Width</a></li>
<li class="toctree-l3"><a class="reference internal" href="guide.impl.c.format.html#white-space">7.2.2. White Space</a></li>
<li class="toctree-l3"><a class="reference internal" href="guide.impl.c.format.html#sections-and-paragraphs">7.2.3. Sections and Paragraphs</a></li>
<li class="toctree-l3"><a class="reference internal" href="guide.impl.c.format.html#statements">7.2.4. Statements</a></li>
<li class="toctree-l3"><a class="reference internal" href="guide.impl.c.format.html#indentation">7.2.5. Indentation</a></li>
<li class="toctree-l3"><a class="reference internal" href="guide.impl.c.format.html#positioning-of-braces">7.2.6. Positioning of Braces</a></li>
<li class="toctree-l3"><a class="reference internal" href="guide.impl.c.format.html#switch-statements">7.2.7. Switch Statements</a></li>
<li class="toctree-l3"><a class="reference internal" href="guide.impl.c.format.html#formatting-comments">7.2.8. Formatting Comments</a></li>
<li class="toctree-l3"><a class="reference internal" href="guide.impl.c.format.html#macros">7.2.9. Macros</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="guide.impl.c.format.html#history">7.3. History</a></li>
<li class="toctree-l2"><a class="reference internal" href="guide.impl.c.format.html#copyright-and-license">7.4. Copyright and License</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="keyword-arguments.html">8. Keyword arguments in the MPS</a><ul>
<li class="toctree-l2"><a class="reference internal" href="keyword-arguments.html#introduction">8.1. Introduction</a></li>
<li class="toctree-l2"><a class="reference internal" href="keyword-arguments.html#overview">8.2. Overview</a></li>
<li class="toctree-l2"><a class="reference internal" href="keyword-arguments.html#internals">8.3. Internals</a></li>
<li class="toctree-l2"><a class="reference internal" href="keyword-arguments.html#the-varargs-legacy">8.4. The varargs legacy</a></li>
<li class="toctree-l2"><a class="reference internal" href="keyword-arguments.html#references">8.5. References</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="range.html">9. Ranges</a><ul>
<li class="toctree-l2"><a class="reference internal" href="range.html#introduction">9.1. Introduction</a></li>
<li class="toctree-l2"><a class="reference internal" href="range.html#requirements">9.2. Requirements</a></li>
<li class="toctree-l2"><a class="reference internal" href="range.html#interface">9.3. Interface</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="ring.html">10. Ring data structure</a><ul>
<li class="toctree-l2"><a class="reference internal" href="ring.html#introduction">10.1. Introduction</a></li>
<li class="toctree-l2"><a class="reference internal" href="ring.html#description">10.2. Description</a></li>
<li class="toctree-l2"><a class="reference internal" href="ring.html#init-finish">10.3. Init / Finish</a></li>
<li class="toctree-l2"><a class="reference internal" href="ring.html#iteration">10.4. Iteration</a></li>
<li class="toctree-l2"><a class="reference internal" href="ring.html#subclass">10.5. Subclass</a></li>
<li class="toctree-l2"><a class="reference internal" href="ring.html#append-remove">10.6. Append / Remove</a></li>
<li class="toctree-l2"><a class="reference internal" href="ring.html#naming">10.7. Naming</a></li>
<li class="toctree-l2"><a class="reference internal" href="ring.html#deques">10.8. Deques</a></li>
<li class="toctree-l2"><a class="reference internal" href="ring.html#defects">10.9. Defects</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="sig.html">11. Signatures in the MPS</a><ul>
<li class="toctree-l2"><a class="reference internal" href="sig.html#introduction">11.1. Introduction</a></li>
<li class="toctree-l2"><a class="reference internal" href="sig.html#overview">11.2. Overview</a></li>
<li class="toctree-l2"><a class="reference internal" href="sig.html#definitions">11.3. Definitions</a></li>
<li class="toctree-l2"><a class="reference internal" href="sig.html#init-and-finish">11.4. Init and Finish</a></li>
<li class="toctree-l2"><a class="reference internal" href="sig.html#checking">11.5. Checking</a></li>
<li class="toctree-l2"><a class="reference internal" href="sig.html#rules">11.6. Rules</a></li>
<li class="toctree-l2"><a class="reference internal" href="sig.html#tools">11.7. Tools</a></li>
<li class="toctree-l2"><a class="reference internal" href="sig.html#references">11.8. References</a></li>
</ul>
</li>
</ul>
@ -170,8 +216,8 @@
<p class="topless"><a href="../pool/snc.html"
title="previous chapter">13. SNC (Stack No Checking)</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="config.html"
title="next chapter">1. MPS Configuration</a></p><h4>Downloads</h4>
<p class="topless"><a href="abq.html"
title="next chapter">1. Queue design</a></p><h4>Downloads</h4>
<p class="topless">
<a href="http://www.ravenbrook.com/project/mps/release/1.111.0/">MPS Kit release 1.111.0</a><br>
@ -197,7 +243,7 @@
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="config.html" title="1. MPS Configuration"
<a href="abq.html" title="1. Queue design"
>next</a> |</li>
<li class="right" >
<a href="../pool/snc.html" title="13. SNC (Stack No Checking)"

View file

@ -8,7 +8,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>5. Keyword arguments in the MPS &mdash; Memory Pool System 1.111.0 documentation</title>
<title>8. Keyword arguments in the MPS &mdash; Memory Pool System 1.111.0 documentation</title>
<link rel="stylesheet" href="../_static/mps.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
@ -28,8 +28,8 @@
<link rel="copyright" title="Copyright" href="../copyright.html" />
<link rel="top" title="Memory Pool System 1.111.0 documentation" href="../index.html" />
<link rel="up" title="Design" href="index.html" />
<link rel="next" title="6. Ring data structure" href="ring.html" />
<link rel="prev" title="4. C Style formatting" href="guide.impl.c.format.html" />
<link rel="next" title="9. Ranges" href="range.html" />
<link rel="prev" title="7. C Style formatting" href="guide.impl.c.format.html" />
</head>
<body>
<div class="related">
@ -39,10 +39,10 @@
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="ring.html" title="6. Ring data structure"
<a href="range.html" title="9. Ranges"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="guide.impl.c.format.html" title="4. C Style formatting"
<a href="guide.impl.c.format.html" title="7. C Style formatting"
accesskey="P">previous</a> |</li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
<li><a href="index.html" accesskey="U">Design</a> &raquo;</li>
@ -55,9 +55,9 @@
<div class="body">
<span class="target" id="design-keyword-arguments"></span><div class="section" id="keyword-arguments-in-the-mps">
<span id="index-0"></span><h1>5. Keyword arguments in the MPS<a class="headerlink" href="#keyword-arguments-in-the-mps" title="Permalink to this headline"></a></h1>
<span id="index-0"></span><h1>8. Keyword arguments in the MPS<a class="headerlink" href="#keyword-arguments-in-the-mps" title="Permalink to this headline"></a></h1>
<div class="section" id="introduction">
<h2>5.1. Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline"></a></h2>
<h2>8.1. Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline"></a></h2>
<p>Up to version 1.111, the <a class="reference external" href="http://www.ravenbrook.com/project/mps/">Memory Pool System</a> used varags to pass arguments
to arena and pool classes, because the general MPS interface can&#8217;t
specify what arguments those classes might need in C prototypes. This
@ -67,7 +67,7 @@ parameters.</p>
<p>Starting with version 1.112, the MPS uses an idiom for keyword arguments.</p>
</div>
<div class="section" id="overview">
<h2>5.2. Overview<a class="headerlink" href="#overview" title="Permalink to this headline"></a></h2>
<h2>8.2. Overview<a class="headerlink" href="#overview" title="Permalink to this headline"></a></h2>
<p>The basic design is not specific to the MPS. The keyword argument list is
passed as an array of argument structures which look like this:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">typedef</span> <span class="k">struct</span> <span class="n">mps_key_s</span> <span class="o">*</span><span class="kt">mps_key_t</span><span class="p">;</span>
@ -120,7 +120,7 @@ past MPS checking.</li>
</ul>
</div>
<div class="section" id="internals">
<h2>5.3. Internals<a class="headerlink" href="#internals" title="Permalink to this headline"></a></h2>
<h2>8.3. Internals<a class="headerlink" href="#internals" title="Permalink to this headline"></a></h2>
<p>Internally, keys are static constant structures which are signed and contain
a checking method for the argument, like this:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">typedef</span> <span class="k">struct</span> <span class="n">mps_arg_s</span> <span class="o">*</span><span class="n">Arg</span><span class="p">;</span>
@ -156,7 +156,7 @@ it, but instead uses the macro. This gives us adaptability to change the
design and replace keys with, say, magic numbers.</p>
</div>
<div class="section" id="the-varargs-legacy">
<h2>5.4. The varargs legacy<a class="headerlink" href="#the-varargs-legacy" title="Permalink to this headline"></a></h2>
<h2>8.4. The varargs legacy<a class="headerlink" href="#the-varargs-legacy" title="Permalink to this headline"></a></h2>
<p>For backward compatibility, varargs to arena and pool creation are
converted into keyword arguments by position, using a method in the
arena or pool class. For example:</p>
@ -179,7 +179,7 @@ handle keyword arguments only.</p>
methods can be deleted at some point in the future.</p>
</div>
<div class="section" id="references">
<h2>5.5. References<a class="headerlink" href="#references" title="Permalink to this headline"></a></h2>
<h2>8.5. References<a class="headerlink" href="#references" title="Permalink to this headline"></a></h2>
<table class="docutils citation" frame="void" id="rb-2012-05-24" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
@ -200,22 +200,22 @@ methods can be deleted at some point in the future.</p>
</a></p>
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">5. Keyword arguments in the MPS</a><ul>
<li><a class="reference internal" href="#introduction">5.1. Introduction</a></li>
<li><a class="reference internal" href="#overview">5.2. Overview</a></li>
<li><a class="reference internal" href="#internals">5.3. Internals</a></li>
<li><a class="reference internal" href="#the-varargs-legacy">5.4. The varargs legacy</a></li>
<li><a class="reference internal" href="#references">5.5. References</a></li>
<li><a class="reference internal" href="#">8. Keyword arguments in the MPS</a><ul>
<li><a class="reference internal" href="#introduction">8.1. Introduction</a></li>
<li><a class="reference internal" href="#overview">8.2. Overview</a></li>
<li><a class="reference internal" href="#internals">8.3. Internals</a></li>
<li><a class="reference internal" href="#the-varargs-legacy">8.4. The varargs legacy</a></li>
<li><a class="reference internal" href="#references">8.5. References</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="guide.impl.c.format.html"
title="previous chapter">4. C Style &#8211; formatting</a></p>
title="previous chapter">7. C Style &#8211; formatting</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="ring.html"
title="next chapter">6. Ring data structure</a></p><h4>Downloads</h4>
<p class="topless"><a href="range.html"
title="next chapter">9. Ranges</a></p><h4>Downloads</h4>
<p class="topless">
<a href="http://www.ravenbrook.com/project/mps/release/1.111.0/">MPS Kit release 1.111.0</a><br>
@ -241,10 +241,10 @@ methods can be deleted at some point in the future.</p>
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="ring.html" title="6. Ring data structure"
<a href="range.html" title="9. Ranges"
>next</a> |</li>
<li class="right" >
<a href="guide.impl.c.format.html" title="4. C Style formatting"
<a href="guide.impl.c.format.html" title="7. C Style formatting"
>previous</a> |</li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
<li><a href="index.html" >Design</a> &raquo;</li>

View file

@ -28,7 +28,7 @@
<link rel="copyright" title="Copyright" href="../copyright.html" />
<link rel="top" title="Memory Pool System 1.111.0 documentation" href="../index.html" />
<link rel="next" title="1. Allocation frame protocol" href="alloc-frame.html" />
<link rel="prev" title="7. Signatures in the MPS" href="sig.html" />
<link rel="prev" title="11. Signatures in the MPS" href="sig.html" />
</head>
<body>
<div class="related">
@ -41,7 +41,7 @@
<a href="alloc-frame.html" title="1. Allocation frame protocol"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="sig.html" title="7. Signatures in the MPS"
<a href="sig.html" title="11. Signatures in the MPS"
accesskey="P">previous</a> |</li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
</ul>
@ -781,7 +781,7 @@ date, they will be moved to the main <a class="reference internal" href="index.h
</a></p>
<h4>Previous topic</h4>
<p class="topless"><a href="sig.html"
title="previous chapter">7. Signatures in the MPS</a></p>
title="previous chapter">11. Signatures in the MPS</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="alloc-frame.html"
title="next chapter">1. Allocation frame protocol</a></p><h4>Downloads</h4>
@ -813,7 +813,7 @@ date, they will be moved to the main <a class="reference internal" href="index.h
<a href="alloc-frame.html" title="1. Allocation frame protocol"
>next</a> |</li>
<li class="right" >
<a href="sig.html" title="7. Signatures in the MPS"
<a href="sig.html" title="11. Signatures in the MPS"
>previous</a> |</li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
</ul>

View file

@ -159,9 +159,10 @@ the pool class, to be used in pool creation.</p>
<div class="section" id="implementation">
<h2>27.5. Implementation<a class="headerlink" href="#implementation" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.poolmvff.impl.free-list"></span><a class="mpstag reference internal" href="#design.mps.poolmvff.impl.free-list">.impl.free-list:</a> The pool stores its free list in a CBS (see
<a class="reference external" href="cbs/">design.mps.cbs</a>). It uses the CBS&#8217;s mayUseInline facility to
avoid running out of memory to store the free list. This is the reason
for the alignment restriction above.</p>
//gdr-peewit/info.ravenbrook.com/project/mps/branch/2013-05-17/emergency/design/poolmvff.txt
<a class="reference external" href="cbs/">design.mps.cbs</a>), failing over in emergencies to a Freelist
(see design.mps.freelist) when the CBS cannot allocate new control
structures. This is the reason for the alignment restriction above.</p>
</div>
<div class="section" id="details">
<h2>27.6. Details<a class="headerlink" href="#details" title="Permalink to this headline"></a></h2>

View file

@ -0,0 +1,850 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Manual Variable Temporal (MVT) pool design &mdash; Memory Pool System 1.111.0 documentation</title>
<link rel="stylesheet" href="../_static/mps.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../',
VERSION: '1.111.0',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<link rel="copyright" title="Copyright" href="../copyright.html" />
<link rel="top" title="Memory Pool System 1.111.0 documentation" href="../index.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="manual-variable-temporal-mvt-pool-design">
<span id="design-poolmvt"></span><h1>Manual Variable Temporal (MVT) pool design<a class="headerlink" href="#manual-variable-temporal-mvt-pool-design" title="Permalink to this headline"></a></h1>
<div class="section" id="introduction">
<span id="design.mps.poolmvt"></span><h2>Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.poolmvt.intro"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.intro">.intro:</a> This is a second-generation design for a pool that manually
manages variable-sized objects. It is intended as a replacement for
poolmv (except in its control pool role) and poolepdl, and it is
intended to satisfy the requirements of the Dylan &#8220;misc&#8221; pool and the
product malloc/new drop-in replacement.</p>
<p><span class="target" id="design.mps.poolmvt.readership"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.readership">.readership:</a> MM developers</p>
<p><span class="target" id="design.mps.poolmvt.source"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.source">.source:</a> req.dylan(6), req.epcore(16), req.product(2)</p>
<p><span class="target" id="design.mps.poolmvt.background"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.background">.background:</a> design.mps.poolmv(0), design.mps.poolepdl(0),
design.product.soft.drop(0), paper.wil95(1), paper.vo96(0),
paper.grun92(1), paper.beck82(0), mail.ptw.1998-02-25.22-18(0)</p>
</div>
<div class="section" id="definitions">
<h2>Definitions<a class="headerlink" href="#definitions" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.poolmvt.def.alignment"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.def.alignment">.def.alignment:</a> Alignment is a constraint on an object&#8217;s address,
typically to be a power of 2 (see also, glossary.alignment )</p>
<p><span class="target" id="design.mps.poolmvt.def.bit-map"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.def.bit-map">.def.bit-map:</a> A bitmap is a boolean-valued vector (see also,
glossary.bitmap ).</p>
<p><span class="target" id="design.mps.poolmvt.def.block"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.def.block">.def.block:</a> A block is a contiguous extent of memory. In this
document, block is used to mean a contiguous extent of memory managed
by the pool for the pool client, typically a subset of a segment
(compare with <a class="reference internal" href="#design.mps.poolmvt.def.segment">.def.segment</a>).</p>
<p><span class="target" id="design.mps.poolmvt.def.cartesian-tree"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.def.cartesian-tree">.def.cartesian-tree:</a> A cartesian tree is a binary tree ordered by
two keys (paper.stephenson83(0)).</p>
<p><span class="target" id="design.mps.poolmvt.def.crossing-map"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.def.crossing-map">.def.crossing-map:</a> A mechanism that supports finding the start of
an object from any address within the object, typically only required
on untagged architectures (see also, glossary.crossing.map ).</p>
<p><span class="target" id="design.mps.poolmvt.def.footer"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.def.footer">.def.footer:</a> A block of descriptive information describing and
immediately following another block of memory (see also
<a class="reference internal" href="#design.mps.poolmvt.def.header">.def.header</a>).</p>
<p><span class="target" id="design.mps.poolmvt.def.fragmentation"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.def.fragmentation">.def.fragmentation:</a> Fragmented memory is memory reserved to the
program but not usable by the program because of the arrangement of
memory already in use (see also, glossary.fragmentation ).</p>
<p><span class="target" id="design.mps.poolmvt.def.header"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.def.header">.def.header:</a> A block of descriptive information describing and
immediately preceding another block of memory (see also,
glossary.in-band.header ).</p>
<p><span class="target" id="design.mps.poolmvt.def.in-band"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.def.in-band">.def.in-band:</a> From &#8220;in band signalling&#8221;, when descriptive
information about a data structure is stored in the data structure
itself (see also, glossary.in-band.header ).</p>
<p><span class="target" id="design.mps.poolmvt.def.out-of-band"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.def.out-of-band">.def.out-of-band:</a> When descriptive information about a data
structure is stored separately from the structure itself (see also,
glossary.out-of-band.header ).</p>
<p><span class="target" id="design.mps.poolmvt.def.refcount"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.def.refcount">.def.refcount:</a> A refcount is a count of the number of users of an
object (see also, glossary.reference.count ).</p>
<p><span class="target" id="design.mps.poolmvt.def.segment"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.def.segment">.def.segment:</a> A segment is a contiguous extent of memory. In this
document, segment is used to mean a contiguous extent of memory
managed by the MPS arena (design.mps.arena(1)) and subdivided by the
pool to provide blocks (see <a class="reference internal" href="#design.mps.poolmvt.def.block">.def.block</a>) to its clients.</p>
<p><span class="target" id="design.mps.poolmvt.def.splay-tree"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.def.splay-tree">.def.splay-tree:</a> A splay tree is a self-adjusting binary tree
(paper.st85(0), paper.sleator96(0)).</p>
<p><span class="target" id="design.mps.poolmvt.def.splinter"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.def.splinter">.def.splinter:</a> A splinter is a fragment of memory that is too small
to be useful (see also, glossary.splinter )</p>
<p><span class="target" id="design.mps.poolmvt.def.subblock"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.def.subblock">.def.subblock:</a> A subblock is a contiguous extent of memory. In this
document, subblock is used to mean a contiguous extent of memory
manage by the client for its own use, typically a subset of a block
(compare with <a class="reference internal" href="#design.mps.poolmvt.def.block">.def.block</a>).</p>
</div>
<div class="section" id="abbreviations">
<h2>Abbreviations<a class="headerlink" href="#abbreviations" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.poolmvt.abbr.abq"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.abbr.abq">.abbr.abq:</a> ABQ = Available Block Queue</p>
<p><span class="target" id="design.mps.poolmvt.abbr.ap"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.abbr.ap">.abbr.ap:</a> AP = Allocation Point</p>
<p><span class="target" id="design.mps.poolmvt.abbr.cbs"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.abbr.cbs">.abbr.cbs:</a> CBS = Coalescing Block Structure</p>
<p><span class="target" id="design.mps.poolmvt.abbr.mps"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.abbr.mps">.abbr.mps:</a> MPS = Memory Pool System</p>
<p><span class="target" id="design.mps.poolmvt.abbr.mv"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.abbr.mv">.abbr.mv:</a> MV = Manual-Variable</p>
<p><span class="target" id="design.mps.poolmvt.abbr.ps"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.abbr.ps">.abbr.ps:</a> PS = PostScript</p>
</div>
<div class="section" id="overview">
<h2>Overview<a class="headerlink" href="#overview" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.poolmvt.overview"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.overview">.overview:</a> MVT is intended to satisfy the requirements of the
clients that need manual-variable pools, improving on the performance
of the existing manual-variable pool implementations, and reducing the
duplication of code that currently exists. The expected clients of MVT
are: Dylan (currently for its misc pool), EP (particularly the dl
pool, but all pools other than the PS object pool), and Product
(initially the malloc/new pool, but also other manual pool classes).</p>
</div>
<div class="section" id="requirements">
<h2>Requirements<a class="headerlink" href="#requirements" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.poolmvt.req.cat"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.req.cat">.req.cat:</a> Requirements are categorized per guide.req(2).</p>
<p><span class="target" id="design.mps.poolmvt.req.risk"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.req.risk">.req.risk:</a> req.epcore(16) is known to be obsolete, but the revised
document has not yet been accepted.</p>
<div class="section" id="critical-requirements">
<h3>Critical requirements<a class="headerlink" href="#critical-requirements" title="Permalink to this headline"></a></h3>
<p><span class="target" id="design.mps.poolmvt.req.fun.man-var"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.req.fun.man-var">.req.fun.man-var:</a> The pool class must support manual allocation and
freeing of variable-sized blocks (source: req.dylan.fun.misc.alloc,
req.epcore.fun.{dl,gen,tmp,stat,cache,trap}.{alloc,free},
req.product.fun.{malloc,new,man.man}).</p>
<p><span class="target" id="design.mps.poolmvt.non-req.fun.gc"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.non-req.fun.gc">.non-req.fun.gc:</a> There is not a requirement that the pool class
support formatted objects, scanning, or collection objects; but it
should not be arbitrarily precluded.</p>
<p><span class="target" id="design.mps.poolmvt.req.fun.align"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.req.fun.align">.req.fun.align:</a> The pool class must support aligned allocations to
client-specified alignments. An individual instance need only support
a single alignment; multiple instances may be used to support more
than one alignment (source: req.epcore.attr.align).</p>
<p><span class="target" id="design.mps.poolmvt.req.fun.reallocate"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.req.fun.reallocate">.req.fun.reallocate:</a> The pool class must support resizing of
allocated blocks (source req.epcore.fun.dl.promise.free,
req.product.dc.env.{ansi-c,cpp}).</p>
<p><span class="target" id="design.mps.poolmvt.non-req.fun.reallocate.in-place"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.non-req.fun.reallocate.in-place">.non-req.fun.reallocate.in-place:</a> There is not a requirement blocks
must be resized in place (where possible); but it seems like a good
idea.</p>
<p><span class="target" id="design.mps.poolmvt.req.fun.thread"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.req.fun.thread">.req.fun.thread:</a> Each instance of the pool class must support
multiple threads of allocation (source req.epcore.fun.dl.multi,
req.product.dc.env.{ansi-c,cpp}).</p>
<p><span class="target" id="design.mps.poolmvt.req.attr.performance"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.req.attr.performance">.req.attr.performance:</a> The pool class must meet or exceed
performance of &#8220;competitive&#8221; allocators (source:
rec.epcore.attr.{run-time,tp}, req.product.attr.{mkt.eval, perform}).
[Dylan does not seem to have any requirement that storage be allocated
with a particular response time or throughput, just so long as we
don&#8217;t block for too long. Clearly there is a missing requirement.]</p>
<p><span class="target" id="design.mps.poolmvt.req.attr.performance.time"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.req.attr.performance.time">.req.attr.performance.time:</a> By inference, the time overhead must be
competetive.</p>
<p><span class="target" id="design.mps.poolmvt.req.attr.performance.space"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.req.attr.performance.space">.req.attr.performance.space:</a> By inference, the space overhead must
be competetive.</p>
<p><span class="target" id="design.mps.poolmvt.req.attr.reliability"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.req.attr.reliability">.req.attr.reliability:</a> The pool class must have &#8220;rock-solid
reliability&#8221; (source: req.dylan.attr.rel.mtbf, req.epcore.attr.rel,
req.product.attr.rel).</p>
<p><span class="target" id="design.mps.poolmvt.req.fun.range"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.req.fun.range">.req.fun.range:</a> The pool class must be able to manage blocks
ranging in size from 1 byte to all of addressable memory
(req.epcore.attr.{dl,gen,tmp,stat,cache,trap}.obj.{min,max}. The range
requirement may be satisfied by multiple instances each managing a
particular client-specified subrange of sizes. [Dylan has requirements
req.dylan.attr.{capacity,obj.max}, but no requirement that such
objects reside in a manual pool.]</p>
<p><span class="target" id="design.mps.poolmvt.req.fun.debug"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.req.fun.debug">.req.fun.debug:</a> The pool class must support debugging erroneous
usage by client programs (source: req.epcore.fun.{dc.variety,
debug.support}, req.product.attr.{mkt.eval,perform}). Debugging is
permitted to incur additional overhead.</p>
<p><span class="target" id="design.mps.poolmvt.req.fun.debug.boundaries"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.req.fun.debug.boundaries">.req.fun.debug.boundaries:</a> The pool class must support checking for
accesses outside the boundaries of live objects.</p>
<p><span class="target" id="design.mps.poolmvt.req.fun.debug.log"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.req.fun.debug.log">.req.fun.debug.log:</a> The pool class must support logging of all
allocations and deallocations.</p>
<p><span class="target" id="design.mps.poolmvt.req.fun.debug.enumerate"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.req.fun.debug.enumerate">.req.fun.debug.enumerate:</a> The pool class must support examining all
allocated objects.</p>
<p><span class="target" id="design.mps.poolmvt.req.fun.debug.free"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.req.fun.debug.free">.req.fun.debug.free:</a> The pool class must support detecting
incorrect, overlapping, and double frees.</p>
<p><span class="target" id="design.mps.poolmvt.req.fun.tolerant"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.req.fun.tolerant">.req.fun.tolerant:</a> The pool class must support tolerance of
erroneous usage (source req.product.attr.use.level.1).</p>
</div>
<div class="section" id="essential-requirements">
<h3>Essential requirements<a class="headerlink" href="#essential-requirements" title="Permalink to this headline"></a></h3>
<p><span class="target" id="design.mps.poolmvt.req.fun.profile"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.req.fun.profile">.req.fun.profile:</a> The pool class should support memory usage
profiling (source: req.product.attr.{mkt.eval, perform}).</p>
<p><span class="target" id="design.mps.poolmvt.req.attr.flex"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.req.attr.flex">.req.attr.flex:</a> The pool class should be flexible so that it can be
tuned to specific allocation and freeing patterns (source:
req.product.attr.flex,req.epcore.attr.{dl,cache,trap}.typ). The
flexibility requirement may be satisfied by multiple instances each
optimizing a specific pattern.</p>
<p><span class="target" id="design.mps.poolmvt.req.attr.adapt"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.req.attr.adapt">.req.attr.adapt:</a> The pool class should be adaptive so that it can
accommodate changing allocation and freeing patterns (source:
req.epcore.fun.{tmp,stat}.policy,
req.product.attr.{mkt.eval,perform}).</p>
</div>
<div class="section" id="nice-requirements">
<h3>Nice requirements<a class="headerlink" href="#nice-requirements" title="Permalink to this headline"></a></h3>
<p><span class="target" id="design.mps.poolmvt.req.fun.suballocate"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.req.fun.suballocate">.req.fun.suballocate:</a> The pool class may support freeing of any
aligned, contiguous subset of an allocated block (source
req.epcore.fun.dl.free.any, req.product.attr.{mkt.eval,perform}).</p>
</div>
</div>
<div class="section" id="architecture">
<h2>Architecture<a class="headerlink" href="#architecture" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.poolmvt.arch.overview"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.overview">.arch.overview:</a> The pool has several layers: client allocation is
by Allocation Points (APs).</p>
<p><span class="target" id="design.mps.poolmvt.arch.overview.ap"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.overview.ap">.arch.overview.ap:</a> APs acquire storage from the pool
available-block queue (ABQ).</p>
<p><span class="target" id="design.mps.poolmvt.arch.overview.abq"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.overview.abq">.arch.overview.abq:</a> The ABQ holds blocks of a minimum configurable
size: &#8220;reuse size&#8221;.</p>
<p><span class="target" id="design.mps.poolmvt.arch.overview.storage"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.overview.storage">.arch.overview.storage:</a> The ABQ acquires storage from the arena,
and from its internal free block managers.</p>
<p><span class="target" id="design.mps.poolmvt.arch.overview.storage.contiguous"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.overview.storage.contiguous">.arch.overview.storage.contiguous:</a> The arena storage is requested
to be contiguous to maximize opportunities for coalescing (Loci will
be used when available).</p>
<p><span class="target" id="design.mps.poolmvt.arch.overview.cbs"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.overview.cbs">.arch.overview.cbs:</a> The free block managers hold blocks freed by
the client until, through coalescing, they have reached the reuse
size, at which point they are made available on the ABQ.</p>
<p><span class="target" id="design.mps.poolmvt.arch.ap"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.ap">.arch.ap:</a> The pool will use allocation points as the allocation
interface to the client.</p>
<p><span class="target" id="design.mps.poolmvt.arch.ap.two-phase"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.ap.two-phase">.arch.ap.two-phase:</a> Allocation points will request blocks from the
pool and suballocate those blocks (using the existing AP, compare and
increment, 2-phase mechanism) to satisfy client requests.</p>
<p><span class="target" id="design.mps.poolmvt.arch.ap.fill"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.ap.fill">.arch.ap.fill:</a> The pool will have a configurable &#8220;fill size&#8221; that
will be the preferred size block used to fill the allocation point.</p>
<p><span class="target" id="design.mps.poolmvt.arch.ap.fill.size"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.ap.fill.size">.arch.ap.fill.size:</a> The fill size should be chosen to amortize the
cost of refill over a number of typical reserve/commit operations, but
not so large as to exceed the typical object population of the pool.</p>
<p><span class="target" id="design.mps.poolmvt.arch.ap.no-fit"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.ap.no-fit">.arch.ap.no-fit:</a> When an allocation does not fit in the remaining
space of the allocation point, there may be a remaining fragment.</p>
<p><span class="target" id="design.mps.poolmvt.arch.ap.no-fit.sawdust"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.ap.no-fit.sawdust">.arch.ap.no-fit.sawdust:</a> If the fragment is below a configurable
threshold (minimum size), it will be left unused (but returned to the
free block managers so it will be reclaimed when adjacent objects are
freed).</p>
<p><span class="target" id="design.mps.poolmvt.arch.ap.no-fit.splinter"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.ap.no-fit.splinter">.arch.ap.no-fit.splinter:</a> otherwise, the remaining fragment will be
(effectively) returned to the head of the available-block queue, so
that it will be used as soon as possible (that is, by objects of similar
birthdate).</p>
<p><span class="target" id="design.mps.poolmvt.arch.ap.no-fit.oversize"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.ap.no-fit.oversize">.arch.ap.no-fit.oversize:</a> If the requested allocation exceeds the
fill size it is treated exceptionally (this may indicate the client
has either misconfigured or misused the pool and should either change
the pool configuration or create a separate pool for these exceptional
objects for best performance).</p>
<p><span class="target" id="design.mps.poolmvt.arch.ap.no-fit.oversize.policy"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.ap.no-fit.oversize.policy">.arch.ap.no-fit.oversize.policy:</a> Oversize blocks are assumed to
have exceptional lifetimes, hence are allocated to one side and do not
participate in the normal storage recycling of the pool.</p>
<p><span class="target" id="design.mps.poolmvt.arch.ap.refill.overhead"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.ap.refill.overhead">.arch.ap.refill.overhead:</a> If reuse size is small, or becomes small
due to <a class="reference internal" href="#design.mps.poolmvt.arch.adapt">.arch.adapt</a>, all allocations will effectively be treated
exceptionally (the AP will trip and a oldest-fit block will be chosen
on each allocation). This mode will be within a constant factor in
overhead of an unbuffered pool.</p>
<p><span class="target" id="design.mps.poolmvt.arch.abq"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.abq">.arch.abq:</a> The available block queue holds blocks that have
coalesced sufficiently to reach reuse size.</p>
<p><span class="target" id="design.mps.poolmvt.arch.abq.reuse.size"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.abq.reuse.size">.arch.abq.reuse.size:</a> A multiple of the quantum of virtual memory
is used as the reuse size (<a class="reference internal" href="#design.mps.poolmvt.anal.policy.size">.anal.policy.size</a>).</p>
<p><span class="target" id="design.mps.poolmvt.arch.abq.fifo"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.abq.fifo">.arch.abq.fifo:</a> It is a FIFO queue (recently coalesced blocks go to
the tail of the queue, blocks are taken from the head of the queue for
reuse).</p>
<p><span class="target" id="design.mps.poolmvt.arch.abq.delay-reuse"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.abq.delay-reuse">.arch.abq.delay-reuse:</a> By thus delaying reuse, coalescing
opportunities are greater.</p>
<p><span class="target" id="design.mps.poolmvt.arch.abq.high-water"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.abq.high-water">.arch.abq.high-water:</a> It has a configurable high water mark, which
when reached will cause blocks at the head of the queue to be returned
to the arena, rather than reused.</p>
<p><span class="target" id="design.mps.poolmvt.arch.abq.return"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.abq.return">.arch.abq.return:</a> When the MPS supports it, the pool will be able
to return free blocks from the ABQ to the arena on demand.</p>
<p><span class="target" id="design.mps.poolmvt.arch.return.segment"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.return.segment">.arch.return.segment:</a> arch.abq.return can be guaranteed to be able
to return a segment by setting reuse size to twice the size of the
segments the pool requests from the arena.</p>
<p><span class="target" id="design.mps.poolmvt.arch.cbs"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.cbs">.arch.cbs:</a> The coalescing block structure holds blocks that have
been freed by the client.</p>
<p><span class="target" id="design.mps.poolmvt.arch.cbs.optimize"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.cbs.optimize">.arch.cbs.optimize:</a> The data structure is optimized for coalescing.</p>
<p><span class="target" id="design.mps.poolmvt.arch.cbs.abq"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.cbs.abq">.arch.cbs.abq:</a> When a block reaches reuse size, it is added to the
ABQ.</p>
<p><span class="target" id="design.mps.poolmvt.arch.cbs.data-structure"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.cbs.data-structure">.arch.cbs.data-structure:</a> The data structures are organized so that
a block can be both in the free block managers and on the ABQ
simultaneously to permit additional coalescing, up until the time the
block is removed from the ABQ and assigned to an AP.</p>
<p><span class="target" id="design.mps.poolmvt.arch.fragmentation.internal"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.fragmentation.internal">.arch.fragmentation.internal:</a> Internal fragmentation results from
The pool will request large segments from the arena to minimize the
internal fragmentation due to objects not crossing segment boundaries.</p>
<p><span class="target" id="design.mps.poolmvt.arch.modular"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.modular">.arch.modular:</a> The architecture will be modular, to allow building
variations on the pool by assembling different parts.</p>
<p><span class="target" id="design.mps.poolmvt.arch.modular.example"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.modular.example">.arch.modular.example:</a> For example, it should be possible to build
pools with any of the freelist mechanisms, with in-band or out-of-band
storage (where applicable), that do or do not support derived object
descriptions, etc.</p>
<p><span class="target" id="design.mps.poolmvt.arch.modular.initial"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.modular.initial">.arch.modular.initial:</a> The initial architecture will use
<a class="reference internal" href="#design.mps.poolmvt.sol.mech.free-list">.sol.mech.free-list</a> for the free block managers,
<a class="reference internal" href="#design.mps.poolmvt.sol.mech.storage.out-of-band">.sol.mech.storage.out-of-band</a>, <a class="reference internal" href="#design.mps.poolmvt.sol.mech.desc.derived">.sol.mech.desc.derived</a>, and
<a class="reference internal" href="#design.mps.poolmvt.sol.mech.allocate.buffer">.sol.mech.allocate.buffer</a>.</p>
<p><span class="target" id="design.mps.poolmvt.arch.segregate"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.segregate">.arch.segregate:</a> The architecture will support segregated
allocation through the use of multiple allocation points. The client
will choose the appropriate allocation point either at run time, or
when possible, at compile time.</p>
<p><span class="target" id="design.mps.poolmvt.arch.segregate.initial"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.segregate.initial">.arch.segregate.initial:</a> The initial architecture will segregate
allocations into two classes: large and small. This will be
implemented by creating two pools with different parameters.</p>
<p><span class="target" id="design.mps.poolmvt.arch.segregate.initial.choice"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.segregate.initial.choice">.arch.segregate.initial.choice:</a> The initial architecture will
provide glue code to choose which pool to allocate from at run time.
If possible this glue code will be written in a way that a good
compiler can optimize the selection of pool at compile time.
Eventually this glue code should be subsumed by the client or
generated automatically by a tool.</p>
<p><span class="target" id="design.mps.poolmvt.arch.debug"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.debug">.arch.debug:</a> Debugging features such as tags, fenceposts, types,
creators will be implemented in a layer above the pool and APs. A
generic pool debugging interface will be developed to support
debugging in this outer layer.</p>
<p><span class="target" id="design.mps.poolmvt.arch.debug.initial"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.debug.initial">.arch.debug.initial:</a> The initial architecture will have counters
for objects/bytes allocated/freed and support for detecting
overlapping frees.</p>
<p><span class="target" id="design.mps.poolmvt.arch.dependency.loci"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.dependency.loci">.arch.dependency.loci:</a> The architecture depends on the arena being
able to efficiently provide segments of varying sizes without
excessive fragmentation. The locus mechanism should satisfy this
dependency. (See <a class="reference internal" href="#design.mps.poolmvt.anal.strategy.risk">.anal.strategy.risk</a>.)</p>
<p><span class="target" id="design.mps.poolmvt.arch.dependency.mfs"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.dependency.mfs">.arch.dependency.mfs:</a> The architecture internal data structures
depend on efficient manual management of small, fixed-sized objects (2
different sizes). The MFS pool should satisfy this dependency.</p>
<p><span class="target" id="design.mps.poolmvt.arch.contingency"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.contingency">.arch.contingency:</a> Since the strategy we propose is new, it may not
work.</p>
<p><span class="target" id="design.mps.poolmvt.arch.contingency.pathological"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.contingency.pathological">.arch.contingency.pathological:</a> In particular, pathological
allocation patterns could result in fragmentation such that no blocks
recycle from the free bock managers to the ABQ.</p>
<p><span class="target" id="design.mps.poolmvt.arch.contingency.fallback"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.contingency.fallback">.arch.contingency.fallback:</a> As a fallback, there will be a pool
creation parameter for a high water mark for the free space.</p>
<p><span class="target" id="design.mps.poolmvt.arch.contingency.fragmentation-limit"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.contingency.fragmentation-limit">.arch.contingency.fragmentation-limit:</a> When the free space as a
percentage of all the memory managed by the pool (a measure of
fragmentation) reaches that high water mark, the free block managers
will be searched oldest-fit before requesting additional segments from
the arena.</p>
<p><span class="target" id="design.mps.poolmvt.arch.contingency.alternative"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.contingency.alternative">.arch.contingency.alternative:</a> We also plan to implement
<a class="reference internal" href="#design.mps.poolmvt.mech.free-list.cartesian-tree">.mech.free-list.cartesian-tree</a> as an alternative free block manager,
which would permit more efficient searching of the free blocks.</p>
<p><span class="target" id="design.mps.poolmvt.arch.parameters"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.parameters">.arch.parameters:</a> The architecture supports several parameters so
that multiple pools may be instantiated and tuned to support different
object cohorts. The important parameters are: reuse size, minimum
size, fill size, ABQ high water mark, free block fragmentation limit
(see <a class="reference internal" href="#design.mps.poolmvt.arch.contingency.fragmentation-limit">.arch.contingency.fragmentation-limit</a>).</p>
<p><span class="target" id="design.mps.poolmvt.arch.parameters.client-visible"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.parameters.client-visible">.arch.parameters.client-visible:</a> The client-visible parameters of
the pool are the minimum object size, the mean object size, the
maximum object size, the reserve depth and fragmentation limit. The
minimum object size determines when a splinter is kept on the head of
the ABQ (<a class="reference internal" href="#design.mps.poolmvt.arch.ap.no-fit.splinter">.arch.ap.no-fit.splinter</a>). The maximum object size
determines the fill size (<a class="reference internal" href="#design.mps.poolmvt.arch.ap.fill-size">.arch.ap.fill-size</a>) and hence when a
block is allocated exceptionally (<a class="reference internal" href="#design.mps.poolmvt.arch.ap.no-fit.oversize">.arch.ap.no-fit.oversize</a>). The
mean object size is the most likely object size. The reserve depth is
a measure of the hysteresis of the object population. The mean object
size, reserve depth and, maximum object size are used to determine the
size of the ABQ (<a class="reference internal" href="#design.mps.poolmvt.arch.abq.high-water">.arch.abq.high-water</a>). The fragmentation limit is
used to determine when contingency mode is used to satisfy an
allocation request (<a class="reference internal" href="#design.mps.poolmvt.arch.contingency">.arch.contingency</a>).</p>
<p><span class="target" id="design.mps.poolmvt.arch.adapt"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.adapt">.arch.adapt:</a> We believe that an important adaptation to explore is
tying the reuse size inversely to the fragmentation (as measured in
<a class="reference internal" href="#design.mps.poolmvt.arch.contingency.fragmentation-limit">.arch.contingency.fragmentation-limit</a>).</p>
<p><span class="target" id="design.mps.poolmvt.arch.adapt.reuse"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.adapt.reuse">.arch.adapt.reuse:</a> By setting reuse size low when fragmentation is
high, smaller blocks will be available for reuse, so fragmentation
should diminish.</p>
<p><span class="target" id="design.mps.poolmvt.arch.adapt.overhead"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.adapt.overhead">.arch.adapt.overhead:</a> This will result in higher overhead as the AP
will need to be refilled more often, so reuse size should be raised
again as fragmentation diminishes.</p>
<p><span class="target" id="design.mps.poolmvt.arch.adapt.oldest-fit"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.adapt.oldest-fit">.arch.adapt.oldest-fit:</a> In the limit, if reuse size goes to zero,
the pool will implement a &#8220;oldest-fit&#8221; policy: the oldest free block
of sufficient size will be used for each allocation.</p>
<p><span class="target" id="design.mps.poolmvt.arch.adapt.risk"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.arch.adapt.risk">.arch.adapt.risk:</a> This adaptation is an experimental policy and
should not be delivered to clients until thoroughly tested.</p>
</div>
<div class="section" id="analysis">
<h2>Analysis<a class="headerlink" href="#analysis" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.poolmvt.anal.discard"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.anal.discard">.anal.discard:</a> We have discarded many traditional solutions based
on experience and analysis in paper.wil95(1). In particular, managing
the free list as a linear list arranged by address or size and basing
policy on searching such a linear list in a particular direction, from
a particular starting point, using fit and/or immediacy as criteria.
We believe that none of these solutions is derived from considering
the root of the problem to be solved (as described in
<a class="reference internal" href="#design.mps.poolmvt.anal.strategy">.anal.strategy</a>), although their behavior as analyzed by Wilson
gives several insights.</p>
<p><span class="target" id="design.mps.poolmvt.anal.strategy"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.anal.strategy">.anal.strategy:</a> For any program to run in the minimum required
memory (with minimal overhead &#8211; we discard solutions such as
compression for now), fragmentation must be eliminated. To eliminate
fragmentation, simply place blocks in memory so that they die &#8220;in
order&#8221; and can be immediately coalesced. This ideal is not achievable,
but we believe we can find object attributes that correlate with
deathtime and exploit them to approximate the ideal. Initially we
believe birth time and type (as approximated by size) will be useful
attributes to explore.</p>
<p><span class="target" id="design.mps.poolmvt.anal.strategy.perform"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.anal.strategy.perform">.anal.strategy.perform:</a> To meet <a class="reference internal" href="#design.mps.poolmvt.req.attr.performance">.req.attr.performance</a>, the
implementation of <a class="reference internal" href="#design.mps.poolmvt.sol.strategy">.sol.strategy</a> must be competitive in both time
and space.</p>
<p><span class="target" id="design.mps.poolmvt.anal.strategy.risk"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.anal.strategy.risk">.anal.strategy.risk:</a> The current MPS segment substrate can cause
internal fragmentation which an individual pool can do nothing about.
We expect that <a class="reference external" href="https://info.ravenbrook.com/project/mps/import/2001-11-05/mmprevol/request/epcore/170193/">request.epcore.170193.sugg.loci</a> will be implemented to
remove this risk.</p>
<p><span class="target" id="design.mps.poolmvt.anal.policy"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.anal.policy">.anal.policy:</a> Deferred coalescing, when taken to the extreme will
not minimize the memory consumption of a program, as no memory would
ever be reused. Eager reuse appears to lead to more fragmentation,
whereas delayed reuse appears to reduce fragmentation
(paper.wil95(1)). The systems studied by Wilson did not directly
address deferring reuse. Our proposed policy is to reuse blocks when
they reach a (configurable) size. We believe that this policy along
with the policy of segregating allocations by death time, will greatly
reduce fragmentation.</p>
<p><span class="target" id="design.mps.poolmvt.anal.policy.risk"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.anal.policy.risk">.anal.policy.risk:</a> This policy could lead to pathological behavior
if allocations cannot be successfully segregated.</p>
<p><span class="target" id="design.mps.poolmvt.anal.policy.allocate.segregate"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.anal.policy.allocate.segregate">.anal.policy.allocate.segregate:</a> This policy has some similarities
to CustomAlloc (paper.grun92(1)). CustomAlloc segregates objects by
size classes, and then within those classes chooses a different
allocator depending on whether that size class has a stable or
unstable population. Classes with stable population recycle storage
within the class, whereas classes with unstable populations return
their storage to the general allocation pool for possible reuse by
another class. CustomAlloc, however, requires profiling the
application and tuning the allocator according to those profiles.
Although we intend to support such tuning, we do not want to require
it.</p>
<p><span class="target" id="design.mps.poolmvt.anal.policy.reallocate"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.anal.policy.reallocate">.anal.policy.reallocate:</a> For reallocation, <a class="reference internal" href="#design.mps.poolmvt.fun.suballocate">.fun.suballocate</a> can
be used to free the remainder if a block is made smaller. Doing so
will cause the freed block to obey <a class="reference internal" href="#design.mps.poolmvt.sol.policy.allocate">.sol.policy.allocate</a> (that is,
the freed block will not be treated specially, it will be subject to
the normal policy on reuse). Copying can be used if a block is made
larger. paper.vo96(0) reports success in over-allocating a block the
first time it is resized larger, presumably because blocks that are
resized once tend to be resized again and over-allocating may avoid a
subsequent copy. If each object that will be reallocated can be given
its own allocation point until its final reallocation, the allocation
point can be used to hold released or spare storage.</p>
<p><span class="target" id="design.mps.poolmvt.anal.policy.size"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.anal.policy.size">.anal.policy.size:</a> We believe that this will take advantage of the
underlying virtual memory system&#8217;s ability to compact the physical
memory footprint of the program by discarding free fragments that
align with the virtual memory quantum. (In a VM system one can
approximate compaction by sparse mapping. If every other page of a
segment is unused, the unused pages can be unmapped, freeing up
physical memory that can be mapped to a new contiguous vm range.)</p>
<p><span class="target" id="design.mps.poolmvt.anal.mech.free-list"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.anal.mech.free-list">.anal.mech.free-list:</a> The literature (paper.grun92(1),
paper.vo96(0)) indicate that <a class="reference internal" href="#design.mps.poolmvt.sol.mech.free-list.cartesian-tree">.sol.mech.free-list.cartesian-tree</a>
provides a space-efficient implementation at some cost in speed.
<a class="reference internal" href="#design.mps.poolmvt.sol.mech.free-list.splay-tree">.sol.mech.free-list.splay-tree</a> is faster but less space-efficient.
<a class="reference internal" href="#design.mps.poolmvt.sol.mech.free-list.bitmap">.sol.mech.free-list.bitmap</a> is unstudied. Many of the faster
allocators maintain caches of free blocks by size to speed allocation
of &#8220;popular&#8221; sizes. We intend to initially explore not doing so, as we
believe that policy ultimately leads to fragmentation by mixing
objects of varying death times. Instead we intend to use a free list
mechanism to support fast coalescing, deferring reuse of blocks until
a minimum size has been reached.</p>
<p><span class="target" id="design.mps.poolmvt.anal.mech.allocate.optimize-small"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.anal.mech.allocate.optimize-small">.anal.mech.allocate.optimize-small:</a> Wilson (paper.wil95(1)) notes
that small blocks typically have short lifetimes and that overall
performance is improved if you optimize the management of small
blocks, e.g., <a class="reference internal" href="#design.mps.poolmvt.sol.mech.allocate.lookup-table">.sol.mech.allocate.lookup-table</a> for all small blocks.
We believe that <a class="reference internal" href="#design.mps.poolmvt.sol.mech.allocate.buffer">.sol.mech.allocate.buffer</a> does exactly that.</p>
<p><span class="target" id="design.mps.poolmvt.anal.mech.allocate.optimize-new"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.anal.mech.allocate.optimize-new">.anal.mech.allocate.optimize-new:</a> Wilson (paper.wil95(1)) reports
some benefit from &#8220;preserving wilderness&#8221;, that is, when a block of
memory must be requested from the system to satisfy an allocation,
only the minimum amount of that block is used, the remainder is
preserved (effectively by putting it at the tail of the free list).
This mechanism may or may not implement <a class="reference internal" href="#design.mps.poolmvt.sol.policy.allocate">.sol.policy.allocate</a>. We
believe a better mechanism is to choose to preserve or not, based on
<a class="reference internal" href="#design.mps.poolmvt.sol.policy.allocate">.sol.policy.allocate</a>.</p>
</div>
<div class="section" id="ideas">
<h2>Ideas<a class="headerlink" href="#ideas" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.poolmvt.sol"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol">.sol:</a> Many solution ideas for manual management of variable-sized
memory blocks are enumerated by paper.wil95(1). Here we list the most
promising, and some of our own.</p>
<div class="section" id="strategy">
<h3>Strategy<a class="headerlink" href="#strategy" title="Permalink to this headline"></a></h3>
<p><span class="target" id="design.mps.poolmvt.sol.strategy"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.strategy">.sol.strategy:</a> To run a program in the minimal required memory,
with minimal overhead, utilize memory efficiently. Memory becomes
unusable when fragmented. Strategy is to minimize fragmentation. So
place blocks where they won&#8217;t cause fragmentation later.</p>
<p><span class="target" id="design.mps.poolmvt.sol.strategy.death"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.strategy.death">.sol.strategy.death:</a> Objects that will die together (in time)
should be allocated together (in space); thus they will coalesce,
reducing fragmentation.</p>
<p><span class="target" id="design.mps.poolmvt.sol.strategy.death.birth"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.strategy.death.birth">.sol.strategy.death.birth:</a> Assume objects allocated near each other
in time will have similar deathtimes (paper.beck82(0)).</p>
<p><span class="target" id="design.mps.poolmvt.sol.strategy.death.type"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.strategy.death.type">.sol.strategy.death.type:</a> Assume objects of different type may have
different deathtimes, even if born together.</p>
<p><span class="target" id="design.mps.poolmvt.sol.strategy.death.predict"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.strategy.death.predict">.sol.strategy.death.predict:</a> Find and use program features to predict deathtimes.</p>
<p><span class="target" id="design.mps.poolmvt.sol.strategy.reallocate"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.strategy.reallocate">.sol.strategy.reallocate:</a> Reallocation implies rebirth, or at least
a change in lifetime</p>
<p><span class="target" id="design.mps.poolmvt.sol.strategy.debug"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.strategy.debug">.sol.strategy.debug:</a> As much of the debugging functionality as
possible should be implemented as a generally available MPS utility;
the pool will provide support for debugging that would be expensive or
impossible to allocate outside the pool.</p>
</div>
<div class="section" id="policy">
<h3>Policy<a class="headerlink" href="#policy" title="Permalink to this headline"></a></h3>
<p>Policy is an implementable decision procedure, hopefully approximating
the strategy.</p>
<p><span class="target" id="design.mps.poolmvt.sol.policy.reuse"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.policy.reuse">.sol.policy.reuse:</a> Defer reusing blocks, to encourage coalescing.</p>
<p><span class="target" id="design.mps.poolmvt.sol.policy.split"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.policy.split">.sol.policy.split:</a> When a block is split to satisfy an allocation,
use the remainder as soon as possible.</p>
<p><span class="target" id="design.mps.poolmvt.sol.policy.size"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.policy.size">.sol.policy.size:</a> Prevent <a class="reference internal" href="#design.mps.poolmvt.policy.reuse">.policy.reuse</a> from consuming all of
memory by choosing a (coalesced) block for reuse when it reaches a
minimum size.</p>
<p><span class="target" id="design.mps.poolmvt.sol.policy.size.fixed"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.policy.size.fixed">.sol.policy.size.fixed:</a> Use the quantum of virtual memory (e.g.,
one page) as minimum size.</p>
<p><span class="target" id="design.mps.poolmvt.sol.policy.size.tune"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.policy.size.tune">.sol.policy.size.tune:</a> Allow tuning minimum size.</p>
<p><span class="target" id="design.mps.poolmvt.sol.policy.size.adapt"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.policy.size.adapt">.sol.policy.size.adapt:</a> Adaptively change minimum size.</p>
<p><span class="target" id="design.mps.poolmvt.sol.policy.allocate"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.policy.allocate">.sol.policy.allocate:</a> Allocate objects with similar birthdate and
lifetime together.</p>
<p><span class="target" id="design.mps.poolmvt.sol.policy.allocate.segregate"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.policy.allocate.segregate">.sol.policy.allocate.segregate:</a> Segregate allocations by type.</p>
<p><span class="target" id="design.mps.poolmvt.sol.policy.allocate.segregate.size"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.policy.allocate.segregate.size">.sol.policy.allocate.segregate.size:</a> Use size as a substitute for type.</p>
<p><span class="target" id="design.mps.poolmvt.sol.policy.allocate.segregate.tune"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.policy.allocate.segregate.tune">.sol.policy.allocate.segregate.tune:</a> Permit tuning of segregation.</p>
<p><span class="target" id="design.mps.poolmvt.sol.policy.allocate.segregate.adapt"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.policy.allocate.segregate.adapt">.sol.policy.allocate.segregate.adapt:</a> Adaptively segregate allocations.</p>
<p><span class="target" id="design.mps.poolmvt.sol.policy.reallocate"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.policy.reallocate">.sol.policy.reallocate:</a> Implement reallocation in a central
mechanism outside of the pool, create a generic pool interface in
support of same.</p>
<p><span class="target" id="design.mps.poolmvt.sol.policy.debug"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.policy.debug">.sol.policy.debug:</a> Implement a pool debugging interface.</p>
<p><span class="target" id="design.mps.poolmvt.sol.policy.debug.counters"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.policy.debug.counters">.sol.policy.debug.counters:</a> Implement debugging counters in the
pool that are queried with a generic interface.</p>
<p><span class="target" id="design.mps.poolmvt.sol.policy.debug.verify"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.policy.debug.verify">.sol.policy.debug.verify:</a> Implement debugging error returns on
overlapping frees.</p>
</div>
<div class="section" id="mechanism">
<h3>Mechanism<a class="headerlink" href="#mechanism" title="Permalink to this headline"></a></h3>
<p>Mechanisms are algorithms or data structures used to implement policy.</p>
<p><span class="target" id="design.mps.poolmvt.sol.mech.free-list"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.mech.free-list">.sol.mech.free-list:</a> Mechanisms that can be used to describe the
free list.</p>
<p><span class="target" id="design.mps.poolmvt.sol.mech.free-list.cartesian-tree"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.mech.free-list.cartesian-tree">.sol.mech.free-list.cartesian-tree:</a> Using address and size as keys
supports fast coalescing of adjacent blocks and fast searching for
optimal-sized blocks. Unfortunately, because the shape of the tree is
constrained by the second key, it can become unbalanced. This data
structure is used in the SunOS 4.1 malloc (paper.grun92(1)).</p>
<p><span class="target" id="design.mps.poolmvt.sol.mech.free-list.splay-tree"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.mech.free-list.splay-tree">.sol.mech.free-list.splay-tree:</a> The amortized cost of a splay tree
is competitive with balanced binary trees in the worst case, but can
be significantly better for regular patterns of access because
recently-accessed keys are moved to the root of the tree and hence can
be re-accessed quickly. This data structure is used in the System Vr4
malloc (paper.vo96(0)). (For a complete analysis of the splay tree
algorithm time bounds see paper.st85(0).)</p>
<p><span class="target" id="design.mps.poolmvt.sol.mech.free-list.bit-map"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.mech.free-list.bit-map">.sol.mech.free-list.bit-map:</a> Using address as an index and
fix-sized blocks, the booleans can represent whether a block is free
or not. Adjacent blocks can be used to construct larger blocks.
Efficient algorithms for searching for runs in a vector are known.
This data structure is used in many file system disk block managers.</p>
<p><span class="target" id="design.mps.poolmvt.sol.mech.free-list.refcount"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.mech.free-list.refcount">.sol.mech.free-list.refcount:</a> A count of the number of allocated
but not freed subblocks of a block can be used to determine when a
block is available for reuse. This is an extremely compact data
structure, but does not support subblock reuse.</p>
<p><span class="target" id="design.mps.poolmvt.sol.mech.free-list.hybrid"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.mech.free-list.hybrid">.sol.mech.free-list.hybrid:</a> Bitmaps appear suited particularly to
managing small, contiguous blocks. The tree structures appear suited
particularly to managing varying-sized, discontiguous blocks. A
refcount can be very efficient if objects can be placed accurately
according to death time. A hybrid mechanism may offer better
performance for a wider range of situations.</p>
<p><span class="target" id="design.mps.poolmvt.sol.mech.free-list.linked"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.mech.free-list.linked">.sol.mech.free-list.linked:</a> An address-ordered singly linked free
list using space in each free block to store the block&#8217;s size and a
pointer to the next block.</p>
<p><span class="target" id="design.mps.poolmvt.sol.mech.storage"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.mech.storage">.sol.mech.storage:</a> Methods that can be used to store the free list description.</p>
<p><span class="target" id="design.mps.poolmvt.sol.mech.storage.in-band"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.mech.storage.in-band">.sol.mech.storage.in-band:</a> The tree data structures (and
<a class="reference internal" href="#design.mps.poolmvt.sol.mech.free-list.linked">.sol.mech.free-list.linked</a>) are amenable to being stored in the
free blocks themselves, minimizing the space overhead of management.
To do so imposes a minimum size on free blocks and reduces the
locality of the data structure.</p>
<p><span class="target" id="design.mps.poolmvt.sol.mech.storage.out-of-band"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.mech.storage.out-of-band">.sol.mech.storage.out-of-band:</a> The bit-map data structure must be
stored separately.</p>
<p><span class="target" id="design.mps.poolmvt.sol.mech.desc"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.mech.desc">.sol.mech.desc:</a> for an allocated block to be freed, its base and
bound must be known</p>
<p><span class="target" id="design.mps.poolmvt.sol.mech.desc.derived"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.mech.desc.derived">.sol.mech.desc.derived:</a> Most clients can supply the base of the
block. Some clients can supply the bound.</p>
<p><span class="target" id="design.mps.poolmvt.sol.mech.desc.in-band"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.mech.desc.in-band">.sol.mech.desc.in-band:</a> When the bound cannot be supplied, it can
be stored as an in-band &#8220;header&#8221;. If neither the base nor bound can be
supplied (e.g., the client may only have an interior pointer to the
block), a header and footer may be required.</p>
<p><span class="target" id="design.mps.poolmvt.sol.mech.desc.out-of-band"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.mech.desc.out-of-band">.sol.mech.desc.out-of-band:</a> In un-tagged architectures, it may be
necessary to store the header and footer out-of-band to distinguish
them from client data. Out-of-band storage can improve locality and
reliability. Any of the free-list structures can also be used to
describe allocated blocks out-of-band.</p>
<p><span class="target" id="design.mps.poolmvt.sol.mech.desc.crossing-map"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.mech.desc.crossing-map">.sol.mech.desc.crossing-map:</a> An alternative for untagged
architectures is to store a &#8220;crossing map&#8221; which records an encoding
of the start of objects and then store the descriptive information
in-band.</p>
<p><span class="target" id="design.mps.poolmvt.sol.mech.allocate"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.mech.allocate">.sol.mech.allocate:</a> Mechanisms that can be used to allocate blocks
(these typically sit on top of a more general free-list manager).</p>
<p><span class="target" id="design.mps.poolmvt.sol.mech.allocate.lookup-table"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.mech.allocate.lookup-table">.sol.mech.allocate.lookup-table:</a> Use a table of popular sizes to
cache free blocks of those sizes.</p>
<p><span class="target" id="design.mps.poolmvt.sol.mech.allocate.buffer"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.mech.allocate.buffer">.sol.mech.allocate.buffer:</a> Allocate from contiguous blocks using
compare and increment.</p>
<p><span class="target" id="design.mps.poolmvt.sol.mech.allocate.optimize-small"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.mech.allocate.optimize-small">.sol.mech.allocate.optimize-small:</a> Use a combination of techniques
to ensure the time spent managing a block is small relative to the
block&#8217;s lifetime; assume small blocks typically have short lifetimes.</p>
<p><span class="target" id="design.mps.poolmvt.sol.mech.allocate.optimize-new"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.mech.allocate.optimize-new">.sol.mech.allocate.optimize-new:</a> When &#8220;virgin&#8221; memory is acquired
from the operating system to satisfy a request, try to preserve it
(that is, use only what is necessary).</p>
<p><span class="target" id="design.mps.poolmvt.sol.mech.allocate.segregate.size"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.mech.allocate.segregate.size">.sol.mech.allocate.segregate.size:</a> Use size as a substitute for
type.</p>
<p><span class="target" id="design.mps.poolmvt.sol.mech.reallocate"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.sol.mech.reallocate">.sol.mech.reallocate:</a> use <a class="reference internal" href="#design.mps.poolmvt.req.fun.suballocate">.req.fun.suballocate</a> to return unused
memory when a block shrinks, but differentiate this from an erroneous
overlapping free by using separate interfaces.</p>
</div>
</div>
<div class="section" id="implementation">
<h2>Implementation<a class="headerlink" href="#implementation" title="Permalink to this headline"></a></h2>
<p>The implementation consists of the following separable modules:</p>
<div class="section" id="coalescing-block-structure">
<h3>Coalescing Block Structure<a class="headerlink" href="#coalescing-block-structure" title="Permalink to this headline"></a></h3>
<p><span class="target" id="design.mps.poolmvt.impl.c.cbs"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.impl.c.cbs">.impl.c.cbs:</a> The initial implementation will use
<a class="reference internal" href="#design.mps.poolmvt.sol.mech.free-list.splay-tree">.sol.mech.free-list.splay-tree</a> and
<a class="reference internal" href="#design.mps.poolmvt.sol.mech.storage.out-of-band">.sol.mech.storage.out-of-band</a>. For locality, this storage should be
managed as a linked free list of splay nodes suballocated from blocks
acquired from a pool shared by all CBS&#8217;s. Must support creation and
destruction of an empty tree. Must support search, insert and delete
by key of type Addr. Must support finding left and right neighbors of
a failed search for a key. Must support iterating over the elements of
the tree with reasonable efficiency. Must support storing and
retrieving a value of type Size associated with the key. Standard
checking and description should be provided. See design.mps.splay(0)
and design.mps.cbs(0).</p>
</div>
<div class="section" id="fail-over-to-address-ordered-free-list">
<h3>Fail-over to address-ordered free list<a class="headerlink" href="#fail-over-to-address-ordered-free-list" title="Permalink to this headline"></a></h3>
<p><span class="target" id="design.mps.poolmvt.impl.c.freelist"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.impl.c.freelist">.impl.c.freelist:</a> Because the CBS uses out-of-band storage, it may
be unable to handle insert (design.mps.cbs.function.cbs.insert.fail)
and delete (design.mps.cbs.function.cbs.delete.fail) operations. When
this happen MVT fails over to an address-ordered singly linked free
list. This uses in-band storage and so cannot run out of memory, but
it has much worse performance than the CBS. Therefore MVT eagerly
attempts to flush blocks from the free list back to the CBS. See
design.mps.freelist for the design and implementation of the free
list.</p>
</div>
<div class="section" id="available-block-queue">
<h3>Available Block Queue<a class="headerlink" href="#available-block-queue" title="Permalink to this headline"></a></h3>
<p><span class="target" id="design.mps.poolmvt.impl.c.abq"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.impl.c.abq">.impl.c.abq:</a> The initial implementation will be a queue of fixed
size (determined at pool creation time from the high water mark). Must
support creation and destruction of an empty queue. Must support
insertion at the head or tail of the queue (failing if full), peeking
at the head of the queue, and removal of the head (failing if empty)
or any element of the queue (found by a search). Standard checking and
description should be provided. See design.mps.abq.</p>
</div>
<div class="section" id="pool-implementation">
<h3>Pool implementation<a class="headerlink" href="#pool-implementation" title="Permalink to this headline"></a></h3>
<p><span class="target" id="design.mps.poolmvt.impl.c"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.impl.c">.impl.c:</a> The initial implementation will use the above modules to
implement a buffered pool. Must support creation and destruction of
the pool. Creation takes parameters: minimum size, mean size, maximum
size, reserve depth and fragmentation limit. Minimum, mean, and
maximum size are used to calculate the internal fill and reuse sizes.
Reserve depth and mean size are used to calculate the ABQ high water
mark. Fragmentation limit is used to set the contingency mode. Must
support buffer initialization, filling and emptying. Must support
freeing. Standard checking and description should be provided.
[Eventually, it should support scanning, so it can be used with
collected pools, but no manual pool currently does.]</p>
<p><span class="target" id="design.mps.poolmvt.impl.c.future"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.impl.c.future">.impl.c.future:</a> The implementation should not preclude &#8220;buffered
free&#8221; (mail.ptw.1997-12-05.19-07(0), ff.) being added in the future.</p>
<p><span class="target" id="design.mps.poolmvt.impl.c.parameters"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.impl.c.parameters">.impl.c.parameters:</a> The pool parameters are calculated as follows
from the input parameters: minimum, mean, and maximum size are taked
directly from the parameters.</p>
<p><span class="target" id="design.mps.poolmvt.impl.c.parameter.fill-size"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.impl.c.parameter.fill-size">.impl.c.parameter.fill-size:</a> The fill size is set to the maximum
size times the reciprocal of the fragmentation limit, aligned to the
arena alignment.</p>
<p><span class="target" id="design.mps.poolmvt.imple.c.parameter.reuse-size"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.imple.c.parameter.reuse-size">.imple.c.parameter.reuse-size:</a> The reuse size is set to twice the
fill size (see <a class="reference internal" href="#design.mps.poolmvt.arch.abq.return.segment">.arch.abq.return.segment</a>,
<a class="reference internal" href="#design.mps.poolmvt.impl.c.free.merge.segment">.impl.c.free.merge.segment</a>).</p>
<p><span class="target" id="design.mps.poolmvt.impl.c.parameter.abq-limit"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.impl.c.parameter.abq-limit">.impl.c.parameter.abq-limit:</a> The ABQ high-water limit is set to the
reserve depth times the mean size (that is, the queue should hold as
many reuse blocks as would take to cover the population hysteresis if
the population consisted solely of mean-sized blocks, see
<a class="reference internal" href="#design.mps.poolmvt.arch.abq.high-water">.arch.abq.high-water</a>).</p>
<p><span class="target" id="design.mps.poolmvt.impl.c.parameter.avail-limit"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.impl.c.parameter.avail-limit">.impl.c.parameter.avail-limit:</a> The free block high-water limit is
implemented by comparing the available free space to an &#8220;available
limit&#8221;. The available limit is updated each time a segment is
allocated from or returned to the arena by setting it to the total
size of the pool times the fragmentation limit divide vy 100 (see
<a class="reference internal" href="#design.mps.poolmvt.arch.contingency.fallback">.arch.contingency.fallback</a>).</p>
<p><span class="target" id="design.mps.poolmvt.impl.c.ap.fill"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.impl.c.ap.fill">.impl.c.ap.fill:</a> An AP fill request will be handled as follows:</p>
<ul class="simple">
<li>If the request is larger than fill size, attempt to request a
segment from the arena sufficient to satisfy the request.</li>
<li>Use any previously returned splinter (from <a class="reference internal" href="#design.mps.poolmvt.impl.c.ap.empty">.impl.c.ap.empty</a>), if
large enough.</li>
<li>Attempt to retrieve a free block from the head of the ABQ (removing
it from ABQ and the free block managers if found).</li>
<li>If above fragmentation limit, attempt to find a block in the free
block managers, using oldest-fit search.</li>
<li>Attempt to request a segment of fill size from the arena.</li>
<li>Attempt to find a block in the free block managers, using oldest-fit
search.</li>
<li>Otherwise, fail.</li>
</ul>
<p><span class="target" id="design.mps.poolmvt.impl.c.ap.empty"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.impl.c.ap.empty">.impl.c.ap.empty:</a> An AP empty request will be handled as follows:</p>
<ul class="simple">
<li>If remaining free is less than min size, return it to the free block
managers.</li>
<li>If the remaining free is larger than any previous splinter, return
that splinter to the free block managers and save this one for use
by a subsequent fill.</li>
<li>Otherwise return the remaining block to the free block managers.</li>
</ul>
<p><span class="target" id="design.mps.poolmvt.impl.c.free"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.impl.c.free">.impl.c.free:</a> When blocks are returned to the free block managers
they may be merged with adjacent blocks. If a merge occurs with a
block on the ABQ, the ABQ must be adjusted to reflect the merge.</p>
<p><span class="target" id="design.mps.poolmvt.impl.c.free.exception"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.impl.c.free.exception">.impl.c.free.exception:</a> Exceptional blocks are returned directly to
the arena.</p>
<p><span class="target" id="design.mps.poolmvt.impl.c.free.merge"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.impl.c.free.merge">.impl.c.free.merge:</a> If a merge occurs and the merged block is
larger than reuse size:</p>
<ul class="simple">
<li>If the ABQ is full, remove the block at the head of the ABQ from the
ABQ and the free block managers and return it to the arena(*).</li>
<li>Insert the newly merged block at the tail of the ABQ, leaving it in
the free block managers for further merging.</li>
</ul>
<p><span class="target" id="design.mps.poolmvt.impl.c.free.merge.segment"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.impl.c.free.merge.segment">.impl.c.free.merge.segment:</a> (*) Merged blocks may not align with
arena segments. If necessary, return the interior segments of a block
to the arena and return the splinters to the free block managers.</p>
<p><span class="target" id="design.mps.poolmvt.impl.c.free.merge.segment.reuse"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.impl.c.free.merge.segment.reuse">.impl.c.free.merge.segment.reuse:</a> If the reuse size (the size at
which blocks recycle from the free block managers to the ABQ) is at
least twice the fill size (the size of segments the pool allocates
from the arena), we can guarantee that there will always be a
returnable segment in every ABQ block.</p>
<p><span class="target" id="design.mps.poolmvt.impl.c.free.merge.segment.overflow"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.impl.c.free.merge.segment.overflow">.impl.c.free.merge.segment.overflow:</a> If the reuse size is set
smaller (see <a class="reference internal" href="#design.mps.poolmvt.arch.adapt">.arch.adapt</a>), there may not be a returnable segment in
an ABQ block, in which case the ABQ has &#8220;overflowed&#8221;. Whenever this
occurs, the ABQ will be refilled by searching the free block managers
for dropped reusable blocks when needed.</p>
<p><span class="target" id="design.mps.poolmvt.impl.c.free.merge.segment.risk"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.impl.c.free.merge.segment.risk">.impl.c.free.merge.segment.risk:</a> The current segment structure does
not really support what we would like to do. Loci should do better:
support reserving contiguous address space and mapping/unmapping any
portion of that address space.</p>
<p><span class="target" id="design.mps.poolmvt.impl.c.free.merge.alternative"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.impl.c.free.merge.alternative">.impl.c.free.merge.alternative:</a> Alternatively, if the MPS segment
substrate permitted mapping/unmapping of pages, the pool could use
very large segments and map/unmap pages as needed.</p>
</div>
<div class="section" id="ap-dispatch">
<h3>AP Dispatch<a class="headerlink" href="#ap-dispatch" title="Permalink to this headline"></a></h3>
<p><span class="target" id="design.mps.poolmvt.impl.c.multiap"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.impl.c.multiap">.impl.c.multiap:</a> The initial implementation will be a glue layer
that selects among several AP&#8217;s for allocation according to the
predicted deathtime (as approximated by size) of the requested
allocation. Each AP will be filled from a pool instance tuned to the
range of object sizes expected to be allocated from that AP. [For
bonus points provide an interface that creates a batch of pools and
AP&#8217;s according to some set of expected object sizes. Eventually expand
to understand object lifetimes and general lifetime prediction keys.]</p>
<p><span class="target" id="design.mps.poolmvt.impl.c.multiap.sample-code"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.impl.c.multiap.sample-code">.impl.c.multiap.sample-code:</a> This glue code is not properly part of
the pool or MPS interface. It is a layer on top of the MPS interface,
intended as sample code for unsophisticated clients. Sophisticated
clients will likely want to choose among multiple AP&#8217;s more directly.</p>
</div>
</div>
<div class="section" id="testing">
<h2>Testing<a class="headerlink" href="#testing" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.poolmvt.test.component"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.test.component">.test.component:</a> Components <a class="reference internal" href="#design.mps.poolmvt.impl.c.splay">.impl.c.splay</a>, <a class="reference internal" href="#design.mps.poolmvt.impl.c.cbs">.impl.c.cbs</a>, and
<a class="reference internal" href="#design.mps.poolmvt.impl.c.abq">.impl.c.abq</a> will be subjected to individual component tests to
verify their functionality.</p>
<p><span class="target" id="design.mps.poolmvt.test.regression"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.test.regression">.test.regression:</a> All tests applied to poolmv
(design.mps.poolmv(0)) and poolepdl (design.mps.poolepdl(0)) will be
applied to poolmvt to ensure that mvt is at least as functional as the
pools it is replacing.</p>
<p><span class="target" id="design.mps.poolmvt.test.qa"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.test.qa">.test.qa:</a> Once poolmvt is integrated into the MPS, the standard MPS
QA tests will be applied to poolmvt prior to each release.</p>
<p><span class="target" id="design.mps.poolmvt.test.customer"></span><a class="mpstag reference internal" href="#design.mps.poolmvt.test.customer">.test.customer:</a> Customer acceptance tests will be performed on a
per-customer basis before release to that customer (cf.
proc.release.epcore(2).test)</p>
</div>
<div class="section" id="text">
<h2>Text<a class="headerlink" href="#text" title="Permalink to this headline"></a></h2>
<p>Possible tweaks (from mail.pekka.1998-04-15.13-10(0)):</p>
<ul class="simple">
<li>Try to coalesce splinters returned from AP&#8217;s with the front (or any)
block on the ABQ.</li>
<li>Sort ABQ in some other way to minimize splitting/splinters. For
example, proximity to recently allocated blocks.</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../index.html">
<img class="logo" src="../_static/logo.png" alt="Logo"/>
</a></p>
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Manual Variable Temporal (MVT) pool design</a><ul>
<li><a class="reference internal" href="#introduction">Introduction</a></li>
<li><a class="reference internal" href="#definitions">Definitions</a></li>
<li><a class="reference internal" href="#abbreviations">Abbreviations</a></li>
<li><a class="reference internal" href="#overview">Overview</a></li>
<li><a class="reference internal" href="#requirements">Requirements</a><ul>
<li><a class="reference internal" href="#critical-requirements">Critical requirements</a></li>
<li><a class="reference internal" href="#essential-requirements">Essential requirements</a></li>
<li><a class="reference internal" href="#nice-requirements">Nice requirements</a></li>
</ul>
</li>
<li><a class="reference internal" href="#architecture">Architecture</a></li>
<li><a class="reference internal" href="#analysis">Analysis</a></li>
<li><a class="reference internal" href="#ideas">Ideas</a><ul>
<li><a class="reference internal" href="#strategy">Strategy</a></li>
<li><a class="reference internal" href="#policy">Policy</a></li>
<li><a class="reference internal" href="#mechanism">Mechanism</a></li>
</ul>
</li>
<li><a class="reference internal" href="#implementation">Implementation</a><ul>
<li><a class="reference internal" href="#coalescing-block-structure">Coalescing Block Structure</a></li>
<li><a class="reference internal" href="#fail-over-to-address-ordered-free-list">Fail-over to address-ordered free list</a></li>
<li><a class="reference internal" href="#available-block-queue">Available Block Queue</a></li>
<li><a class="reference internal" href="#pool-implementation">Pool implementation</a></li>
<li><a class="reference internal" href="#ap-dispatch">AP Dispatch</a></li>
</ul>
</li>
<li><a class="reference internal" href="#testing">Testing</a></li>
<li><a class="reference internal" href="#text">Text</a></li>
</ul>
</li>
</ul>
<h4>Downloads</h4>
<p class="topless">
<a href="http://www.ravenbrook.com/project/mps/release/1.111.0/">MPS Kit release 1.111.0</a><br>
<a href="http://www.ravenbrook.com/project/mps/release/">All MPS Kit releases</a>
</p>
<h4>Issues</h4>
<p class="topless">
<a href="http://www.ravenbrook.com/project/mps/issue/?action=list&amp;view=status%3dopen&amp;display=Job:Priority:Title&amp;sort=Priority">Known issues</a><br>
<a href="http://www.ravenbrook.com/project/mps/issue/?action=fixed&release_fixed=1.111.0">Issues fixed in release 1.111.0</a>
</p><h4>Contact us</h4>
<p class="topless"><a href="mailto:mps-questions@ravenbrook.com">mps-questions@ravenbrook.com</a></p>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; <a href="../copyright.html">Copyright</a> 2013, Ravenbrook Limited.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

View file

@ -0,0 +1,213 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>9. Ranges &mdash; Memory Pool System 1.111.0 documentation</title>
<link rel="stylesheet" href="../_static/mps.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../',
VERSION: '1.111.0',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<link rel="copyright" title="Copyright" href="../copyright.html" />
<link rel="top" title="Memory Pool System 1.111.0 documentation" href="../index.html" />
<link rel="up" title="Design" href="index.html" />
<link rel="next" title="10. Ring data structure" href="ring.html" />
<link rel="prev" title="8. Keyword arguments in the MPS" href="keyword-arguments.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="ring.html" title="10. Ring data structure"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="keyword-arguments.html" title="8. Keyword arguments in the MPS"
accesskey="P">previous</a> |</li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
<li><a href="index.html" accesskey="U">Design</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="ranges">
<span id="design-range"></span><h1>9. Ranges<a class="headerlink" href="#ranges" title="Permalink to this headline"></a></h1>
<div class="section" id="introduction">
<span id="design.mps.range"></span><h2>9.1. Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.range.intro"></span><a class="mpstag reference internal" href="#design.mps.range.intro">.intro:</a> This is the design of the Range module, which implements
objects representing address ranges.</p>
<p><span class="target" id="readership">readership</span>: This document is intended for any MPS developer.</p>
</div>
<div class="section" id="requirements">
<h2>9.2. Requirements<a class="headerlink" href="#requirements" title="Permalink to this headline"></a></h2>
<p><span class="target" id="req-range">.req.range</span> A range object must be able to represent an arbitrary
range of addresses that does not include the top grain of the address
space.</p>
<p><span class="target" id="req-empty">.req.empty</span> A range object must be able to represent the empty
range.</p>
<p><span class="target" id="req-stack-alloc">.req.stack-alloc</span> It must be possible to allocate range objects on
the stack: that is, they do not require any heap resource.</p>
</div>
<div class="section" id="interface">
<h2>9.3. Interface<a class="headerlink" href="#interface" title="Permalink to this headline"></a></h2>
<dl class="type">
<dt id="Range">
RangeStruct *<tt class="descname">Range</tt><a class="headerlink" href="#Range" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p><tt class="docutils literal"><span class="pre">Range</span></tt> is the type of a range. It is an alias for <tt class="docutils literal"><span class="pre">RangeStruct&nbsp;*</span></tt>. <tt class="xref c c-type docutils literal"><span class="pre">RangeStruct</span></tt> is defined in the header so that it can be
inlined in client structures or allocated on the stack. Clients must
not depend on its implementation details.</p>
<dl class="function">
<dt id="RangeInit">
void <tt class="descname">RangeInit</tt><big>(</big><a class="reference internal" href="#Range" title="Range">Range</a><em>&nbsp;range</em>, <a class="reference internal" href="type.html#Addr" title="Addr">Addr</a><em>&nbsp;base</em>, <a class="reference internal" href="type.html#Addr" title="Addr">Addr</a><em>&nbsp;limit</em><big>)</big><a class="headerlink" href="#RangeInit" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p>Initialize a range object to represent the half-open address range
between <tt class="docutils literal"><span class="pre">base</span></tt> (inclusive) and <tt class="docutils literal"><span class="pre">limit</span></tt> (exclusive). It must be the
case that <tt class="docutils literal"><span class="pre">base</span> <span class="pre">&lt;=</span> <span class="pre">limit</span></tt>. If <tt class="docutils literal"><span class="pre">base</span> <span class="pre">==</span> <span class="pre">limit</span></tt> then the range is
empty.</p>
<dl class="function">
<dt id="RangeFinish">
void <tt class="descname">RangeFinish</tt><big>(</big><a class="reference internal" href="#Range" title="Range">Range</a><em>&nbsp;range</em><big>)</big><a class="headerlink" href="#RangeFinish" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p>Finish a range object. Because a range object uses no heap resources
(<a class="reference internal" href="#design.mps.range.req.stack-alloc">.req.stack-alloc</a>) it is not necessary to call this. However,
clients may wish to do so in order to ensure that the range object is
invalid.</p>
<dl class="function">
<dt id="RangeBase">
<a class="reference internal" href="type.html#Addr" title="Addr">Addr</a> <tt class="descname">RangeBase</tt><big>(</big><a class="reference internal" href="#Range" title="Range">Range</a><em>&nbsp;range</em><big>)</big><a class="headerlink" href="#RangeBase" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p>Return the base of the range. (This is implemented as a macro, but
there is a function too.)</p>
<dl class="function">
<dt id="RangeLimit">
<a class="reference internal" href="type.html#Addr" title="Addr">Addr</a> <tt class="descname">RangeLimit</tt><big>(</big><a class="reference internal" href="#Range" title="Range">Range</a><em>&nbsp;range</em><big>)</big><a class="headerlink" href="#RangeLimit" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p>Return the limit of the range. (This is implemented as a macro, but
there is a function too.)</p>
<dl class="function">
<dt id="RangeSize">
<a class="reference internal" href="type.html#Size" title="Size">Size</a> <tt class="descname">RangeSize</tt><big>(</big><a class="reference internal" href="#Range" title="Range">Range</a><em>&nbsp;range</em><big>)</big><a class="headerlink" href="#RangeSize" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p>Return the size of the range. (This is implemented as a macro, but
there is a function too. The macro evaluates its argument twice.)</p>
<dl class="function">
<dt id="RangeIsAligned">
<a class="reference internal" href="type.html#Bool" title="Bool">Bool</a> <tt class="descname">RangeIsAligned</tt><big>(</big><a class="reference internal" href="#Range" title="Range">Range</a><em>&nbsp;range</em>, <a class="reference internal" href="type.html#Align" title="Align">Align</a><em>&nbsp;alignment</em><big>)</big><a class="headerlink" href="#RangeIsAligned" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p>Return <tt class="xref c c-macro docutils literal"><span class="pre">TRUE</span></tt> if the base and limit of the range are both aligned to
the given alignment, or <tt class="xref c c-macro docutils literal"><span class="pre">FALSE</span></tt> if either is not.</p>
<dl class="function">
<dt id="RangesOverlap">
<a class="reference internal" href="type.html#Bool" title="Bool">Bool</a> <tt class="descname">RangesOverlap</tt><big>(</big><a class="reference internal" href="#Range" title="Range">Range</a><em>&nbsp;range1</em>, <a class="reference internal" href="#Range" title="Range">Range</a><em>&nbsp;range2</em><big>)</big><a class="headerlink" href="#RangesOverlap" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p>Return <tt class="xref c c-macro docutils literal"><span class="pre">TRUE</span></tt> if the two ranges overlap (have at least one address
in common), or <tt class="xref c c-macro docutils literal"><span class="pre">FALSE</span></tt> if they do not. Note that ranges [<em>A</em>, <em>B</em>) and
[<em>B</em>, <em>C</em>) do not overlap.</p>
<dl class="function">
<dt id="RangesNest">
<a class="reference internal" href="type.html#Bool" title="Bool">Bool</a> <tt class="descname">RangesNest</tt><big>(</big><a class="reference internal" href="#Range" title="Range">Range</a><em>&nbsp;outer</em>, <a class="reference internal" href="#Range" title="Range">Range</a><em>&nbsp;inner</em><big>)</big><a class="headerlink" href="#RangesNest" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p>Return <tt class="xref c c-macro docutils literal"><span class="pre">TRUE</span></tt> if all addresses in <tt class="docutils literal"><span class="pre">inner</span></tt> are also in <tt class="docutils literal"><span class="pre">outer</span></tt>,
or <tt class="xref c c-macro docutils literal"><span class="pre">FALSE</span></tt> otherwise.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../index.html">
<img class="logo" src="../_static/logo.png" alt="Logo"/>
</a></p>
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">9. Ranges</a><ul>
<li><a class="reference internal" href="#introduction">9.1. Introduction</a></li>
<li><a class="reference internal" href="#requirements">9.2. Requirements</a></li>
<li><a class="reference internal" href="#interface">9.3. Interface</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="keyword-arguments.html"
title="previous chapter">8. Keyword arguments in the MPS</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="ring.html"
title="next chapter">10. Ring data structure</a></p><h4>Downloads</h4>
<p class="topless">
<a href="http://www.ravenbrook.com/project/mps/release/1.111.0/">MPS Kit release 1.111.0</a><br>
<a href="http://www.ravenbrook.com/project/mps/release/">All MPS Kit releases</a>
</p>
<h4>Issues</h4>
<p class="topless">
<a href="http://www.ravenbrook.com/project/mps/issue/?action=list&amp;view=status%3dopen&amp;display=Job:Priority:Title&amp;sort=Priority">Known issues</a><br>
<a href="http://www.ravenbrook.com/project/mps/issue/?action=fixed&release_fixed=1.111.0">Issues fixed in release 1.111.0</a>
</p><h4>Contact us</h4>
<p class="topless"><a href="mailto:mps-questions@ravenbrook.com">mps-questions@ravenbrook.com</a></p>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="ring.html" title="10. Ring data structure"
>next</a> |</li>
<li class="right" >
<a href="keyword-arguments.html" title="8. Keyword arguments in the MPS"
>previous</a> |</li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
<li><a href="index.html" >Design</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; <a href="../copyright.html">Copyright</a> 2013, Ravenbrook Limited.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

View file

@ -8,7 +8,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>6. Ring data structure &mdash; Memory Pool System 1.111.0 documentation</title>
<title>10. Ring data structure &mdash; Memory Pool System 1.111.0 documentation</title>
<link rel="stylesheet" href="../_static/mps.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
@ -28,8 +28,8 @@
<link rel="copyright" title="Copyright" href="../copyright.html" />
<link rel="top" title="Memory Pool System 1.111.0 documentation" href="../index.html" />
<link rel="up" title="Design" href="index.html" />
<link rel="next" title="7. Signatures in the MPS" href="sig.html" />
<link rel="prev" title="5. Keyword arguments in the MPS" href="keyword-arguments.html" />
<link rel="next" title="11. Signatures in the MPS" href="sig.html" />
<link rel="prev" title="9. Ranges" href="range.html" />
</head>
<body>
<div class="related">
@ -39,10 +39,10 @@
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="sig.html" title="7. Signatures in the MPS"
<a href="sig.html" title="11. Signatures in the MPS"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="keyword-arguments.html" title="5. Keyword arguments in the MPS"
<a href="range.html" title="9. Ranges"
accesskey="P">previous</a> |</li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
<li><a href="index.html" accesskey="U">Design</a> &raquo;</li>
@ -55,14 +55,14 @@
<div class="body">
<span class="target" id="design-ring"></span><div class="section" id="ring-data-structure">
<span id="index-0"></span><h1>6. Ring data structure<a class="headerlink" href="#ring-data-structure" title="Permalink to this headline"></a></h1>
<span id="index-0"></span><h1>10. Ring data structure<a class="headerlink" href="#ring-data-structure" title="Permalink to this headline"></a></h1>
<div class="section" id="introduction">
<span id="design.mps.ring"></span><h2>6.1. Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline"></a></h2>
<span id="design.mps.ring"></span><h2>10.1. Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.ring.source"></span><a class="mpstag reference internal" href="#design.mps.ring.source">.source:</a> rings are derived from the earlier use of Deques. See
design.mps.deque.</p>
</div>
<div class="section" id="description">
<h2>6.2. Description<a class="headerlink" href="#description" title="Permalink to this headline"></a></h2>
<h2>10.2. Description<a class="headerlink" href="#description" title="Permalink to this headline"></a></h2>
<dl class="type">
<dt id="Ring">
RingStruct *<tt class="descname">Ring</tt><a class="headerlink" href="#Ring" title="Permalink to this definition"></a></dt>
@ -102,7 +102,7 @@ whose previous and next nodes are itself (see <a class="reference internal" href
<p>[missing figure]</p>
</div>
<div class="section" id="init-finish">
<h2>6.3. Init / Finish<a class="headerlink" href="#init-finish" title="Permalink to this headline"></a></h2>
<h2>10.3. Init / Finish<a class="headerlink" href="#init-finish" title="Permalink to this headline"></a></h2>
<dl class="function">
<dt id="RingInit">
void <tt class="descname">RingInit</tt><big>(</big><a class="reference internal" href="#Ring" title="Ring">Ring</a><em>&nbsp;ring</em><big>)</big><a class="headerlink" href="#RingInit" title="Permalink to this definition"></a></dt>
@ -120,7 +120,7 @@ ring must be a singleton ring before it can be finished (it is an
error to attempt to finish a non-singleton ring).</p>
</div>
<div class="section" id="iteration">
<h2>6.4. Iteration<a class="headerlink" href="#iteration" title="Permalink to this headline"></a></h2>
<h2>10.4. Iteration<a class="headerlink" href="#iteration" title="Permalink to this headline"></a></h2>
<dl class="function">
<dt id="RING_FOR">
<tt class="descname">RING_FOR</tt><big>(</big><a class="reference internal" href="#Ring" title="Ring">Ring</a><em>&nbsp;node</em>, <a class="reference internal" href="#Ring" title="Ring">Ring</a><em>&nbsp;ring</em>, <a class="reference internal" href="#Ring" title="Ring">Ring</a><em>&nbsp;next</em><big>)</big><a class="headerlink" href="#RING_FOR" title="Permalink to this definition"></a></dt>
@ -155,7 +155,7 @@ iteration.</p>
almost universal when using <a class="reference internal" href="#RING_FOR" title="RING_FOR"><tt class="xref c c-func docutils literal"><span class="pre">RING_FOR()</span></tt></a>.</p>
</div>
<div class="section" id="subclass">
<h2>6.5. Subclass<a class="headerlink" href="#subclass" title="Permalink to this headline"></a></h2>
<h2>10.5. Subclass<a class="headerlink" href="#subclass" title="Permalink to this headline"></a></h2>
<dl class="function">
<dt id="RING_ELT">
<tt class="descname">RING_ELT</tt><big>(</big>type, field, <a class="reference internal" href="#Ring" title="Ring">Ring</a><em>&nbsp;node</em><big>)</big><a class="headerlink" href="#RING_ELT" title="Permalink to this definition"></a></dt>
@ -173,7 +173,7 @@ result is a pointer to the enclosing structure.</p>
</div>
</div>
<div class="section" id="append-remove">
<h2>6.6. Append / Remove<a class="headerlink" href="#append-remove" title="Permalink to this headline"></a></h2>
<h2>10.6. Append / Remove<a class="headerlink" href="#append-remove" title="Permalink to this headline"></a></h2>
<dl class="function">
<dt id="RingAppend">
void <tt class="descname">RingAppend</tt><big>(</big><a class="reference internal" href="#Ring" title="Ring">Ring</a><em>&nbsp;ring</em>, <a class="reference internal" href="#Ring" title="Ring">Ring</a><em>&nbsp;new</em><big>)</big><a class="headerlink" href="#RingAppend" title="Permalink to this definition"></a></dt>
@ -200,7 +200,7 @@ element to already be a singleton.</p>
that joined two rings. This is not done as it is not required.</p>
</div>
<div class="section" id="naming">
<h2>6.7. Naming<a class="headerlink" href="#naming" title="Permalink to this headline"></a></h2>
<h2>10.7. Naming<a class="headerlink" href="#naming" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.ring.naming"></span><a class="mpstag reference internal" href="#design.mps.ring.naming">.naming:</a> By convention, when one structure <tt class="docutils literal"><span class="pre">Foo</span></tt> contains one
ring of <tt class="docutils literal"><span class="pre">Bar</span></tt> structures, the field in <tt class="docutils literal"><span class="pre">Foo</span></tt> is usually known as
<tt class="docutils literal"><span class="pre">barRing</span></tt>, and the field in <tt class="docutils literal"><span class="pre">Bar</span></tt> is known as <tt class="docutils literal"><span class="pre">fooRing</span></tt>. If the
@ -208,14 +208,14 @@ ring of <tt class="docutils literal"><span class="pre">Bar</span></tt> structure
then they will have names such as <tt class="docutils literal"><span class="pre">spongRing</span></tt> and <tt class="docutils literal"><span class="pre">frobRing</span></tt>.</p>
</div>
<div class="section" id="deques">
<h2>6.8. Deques<a class="headerlink" href="#deques" title="Permalink to this headline"></a></h2>
<h2>10.8. Deques<a class="headerlink" href="#deques" title="Permalink to this headline"></a></h2>
<p>This section documents where rings differ significantly from deques.</p>
<p><span class="target" id="design.mps.ring.head"></span><a class="mpstag reference internal" href="#design.mps.ring.head">.head:</a> Deques used a distinguished head structure for the head of
the ring. Rings still have a separate head structure, but it is not
distinguished by type.</p>
</div>
<div class="section" id="defects">
<h2>6.9. Defects<a class="headerlink" href="#defects" title="Permalink to this headline"></a></h2>
<h2>10.9. Defects<a class="headerlink" href="#defects" title="Permalink to this headline"></a></h2>
<p>This section documents known defects with the current design.</p>
<p><span class="target" id="design.mps.ring.app_for.misuse"></span><a class="mpstag reference internal" href="#design.mps.ring.app_for.misuse">.app_for.misuse:</a> It is easy to pass <a class="reference internal" href="#RingAppend" title="RingAppend"><tt class="xref c c-func docutils literal"><span class="pre">RingAppend()</span></tt></a> and
<a class="reference internal" href="#RING_FOR" title="RING_FOR"><tt class="xref c c-func docutils literal"><span class="pre">RING_FOR()</span></tt></a> the arguments in the wrong order as all the arguments
@ -236,26 +236,26 @@ check. This could be added.</p>
</a></p>
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">6. Ring data structure</a><ul>
<li><a class="reference internal" href="#introduction">6.1. Introduction</a></li>
<li><a class="reference internal" href="#description">6.2. Description</a></li>
<li><a class="reference internal" href="#init-finish">6.3. Init / Finish</a></li>
<li><a class="reference internal" href="#iteration">6.4. Iteration</a></li>
<li><a class="reference internal" href="#subclass">6.5. Subclass</a></li>
<li><a class="reference internal" href="#append-remove">6.6. Append / Remove</a></li>
<li><a class="reference internal" href="#naming">6.7. Naming</a></li>
<li><a class="reference internal" href="#deques">6.8. Deques</a></li>
<li><a class="reference internal" href="#defects">6.9. Defects</a></li>
<li><a class="reference internal" href="#">10. Ring data structure</a><ul>
<li><a class="reference internal" href="#introduction">10.1. Introduction</a></li>
<li><a class="reference internal" href="#description">10.2. Description</a></li>
<li><a class="reference internal" href="#init-finish">10.3. Init / Finish</a></li>
<li><a class="reference internal" href="#iteration">10.4. Iteration</a></li>
<li><a class="reference internal" href="#subclass">10.5. Subclass</a></li>
<li><a class="reference internal" href="#append-remove">10.6. Append / Remove</a></li>
<li><a class="reference internal" href="#naming">10.7. Naming</a></li>
<li><a class="reference internal" href="#deques">10.8. Deques</a></li>
<li><a class="reference internal" href="#defects">10.9. Defects</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="keyword-arguments.html"
title="previous chapter">5. Keyword arguments in the MPS</a></p>
<p class="topless"><a href="range.html"
title="previous chapter">9. Ranges</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="sig.html"
title="next chapter">7. Signatures in the MPS</a></p><h4>Downloads</h4>
title="next chapter">11. Signatures in the MPS</a></p><h4>Downloads</h4>
<p class="topless">
<a href="http://www.ravenbrook.com/project/mps/release/1.111.0/">MPS Kit release 1.111.0</a><br>
@ -281,10 +281,10 @@ check. This could be added.</p>
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="sig.html" title="7. Signatures in the MPS"
<a href="sig.html" title="11. Signatures in the MPS"
>next</a> |</li>
<li class="right" >
<a href="keyword-arguments.html" title="5. Keyword arguments in the MPS"
<a href="range.html" title="9. Ranges"
>previous</a> |</li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
<li><a href="index.html" >Design</a> &raquo;</li>

View file

@ -8,7 +8,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>7. Signatures in the MPS &mdash; Memory Pool System 1.111.0 documentation</title>
<title>11. Signatures in the MPS &mdash; Memory Pool System 1.111.0 documentation</title>
<link rel="stylesheet" href="../_static/mps.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
@ -29,7 +29,7 @@
<link rel="top" title="Memory Pool System 1.111.0 documentation" href="../index.html" />
<link rel="up" title="Design" href="index.html" />
<link rel="next" title="Old design" href="old.html" />
<link rel="prev" title="6. Ring data structure" href="ring.html" />
<link rel="prev" title="10. Ring data structure" href="ring.html" />
</head>
<body>
<div class="related">
@ -42,7 +42,7 @@
<a href="old.html" title="Old design"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="ring.html" title="6. Ring data structure"
<a href="ring.html" title="10. Ring data structure"
accesskey="P">previous</a> |</li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
<li><a href="index.html" accesskey="U">Design</a> &raquo;</li>
@ -55,9 +55,9 @@
<div class="body">
<span class="target" id="design-sig"></span><div class="section" id="signatures-in-the-mps">
<span id="index-0"></span><h1>7. Signatures in the MPS<a class="headerlink" href="#signatures-in-the-mps" title="Permalink to this headline"></a></h1>
<span id="index-0"></span><h1>11. Signatures in the MPS<a class="headerlink" href="#signatures-in-the-mps" title="Permalink to this headline"></a></h1>
<div class="section" id="introduction">
<span id="design.mps.sig"></span><h2>7.1. Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline"></a></h2>
<span id="design.mps.sig"></span><h2>11.1. Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline"></a></h2>
<p>Integrity of data structures is absolutely critical to the cost of
deploying the Memory Pool System. Memory corruption and memory
management bugs are incredibly hard to detect and debug, often
@ -67,7 +67,7 @@ ways the MPS detects corruption or the passing of illegal data is using
defects early.</p>
</div>
<div class="section" id="overview">
<h2>7.2. Overview<a class="headerlink" href="#overview" title="Permalink to this headline"></a></h2>
<h2>11.2. Overview<a class="headerlink" href="#overview" title="Permalink to this headline"></a></h2>
<p>Signatures are <a class="reference external" href="http://en.wikipedia.org/wiki/Magic_number_(programming)">magic numbers</a> which are written into structures when
they are created and invalidated (by overwriting with <tt class="docutils literal"><span class="pre">SigInvalid</span></tt>)
when they are destroyed. They provide a limited form of run-time type
@ -76,7 +76,7 @@ checking and dynamic scope checking. They are a simplified form of
<a class="reference internal" href="#thvv-1995">[THVV_1995]</a>.</p>
</div>
<div class="section" id="definitions">
<h2>7.3. Definitions<a class="headerlink" href="#definitions" title="Permalink to this headline"></a></h2>
<h2>11.3. Definitions<a class="headerlink" href="#definitions" title="Permalink to this headline"></a></h2>
<p>Nearly every structure should start with a field of type <tt class="xref c c-type docutils literal"><span class="pre">Sig</span></tt> with the name
<tt class="docutils literal"><span class="pre">sig</span></tt>. For example:</p>
<div class="highlight-c"><div class="highlight"><pre><span class="k">typedef</span> <span class="k">struct</span> <span class="n">mps_message_s</span> <span class="p">{</span>
@ -101,7 +101,7 @@ checking and dynamic scope checking. They are a simplified form of
dump or memory window, or found using memory searches.</p>
</div>
<div class="section" id="init-and-finish">
<h2>7.4. Init and Finish<a class="headerlink" href="#init-and-finish" title="Permalink to this headline"></a></h2>
<h2>11.4. Init and Finish<a class="headerlink" href="#init-and-finish" title="Permalink to this headline"></a></h2>
<p>When the structure is initialised, the signature is initialised as the
<em>last</em> action, just before validating it. (Think of it as putting your
signature at the bottom of a document to say it&#8217;s done.) This ensures
@ -134,7 +134,7 @@ being torn down. For example:</p>
<p>Do not do anything else with signatures. See <a class="reference internal" href="#design.mps.sig.rule.purpose">.rule.purpose</a>.</p>
</div>
<div class="section" id="checking">
<h2>7.5. Checking<a class="headerlink" href="#checking" title="Permalink to this headline"></a></h2>
<h2>11.5. Checking<a class="headerlink" href="#checking" title="Permalink to this headline"></a></h2>
<p>The signature is checked in various ways. Every function that takes a
(pointer to) a signed structure should check its argument using the
<tt class="xref c c-macro docutils literal"><span class="pre">AVERT</span></tt> macro. This macro has different definitions depending on how
@ -157,7 +157,7 @@ wrong type, an uninitialized object, or a dead object, or a random
pointer into a function.</p>
</div>
<div class="section" id="rules">
<h2>7.6. Rules<a class="headerlink" href="#rules" title="Permalink to this headline"></a></h2>
<h2>11.6. Rules<a class="headerlink" href="#rules" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.sig.rule.purpose"></span><a class="mpstag reference internal" href="#design.mps.sig.rule.purpose">.rule.purpose:</a> <strong>Do not</strong> use signatures for any other purpose. For
example, don&#8217;t use them to make any actual decisions within the code.
They must not be used to discriminate between structure variants (or
@ -167,7 +167,7 @@ double-check whether these facts are true. They lose their value as a
consistency check if the code uses them as well.</p>
</div>
<div class="section" id="tools">
<h2>7.7. Tools<a class="headerlink" href="#tools" title="Permalink to this headline"></a></h2>
<h2>11.7. Tools<a class="headerlink" href="#tools" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.sig.test.uniq"></span><a class="mpstag reference internal" href="#design.mps.sig.test.uniq">.test.uniq:</a> The Unix command:</p>
<div class="highlight-c"><pre>sed -n '/^#define [a-zA-Z]*Sig/s/[^(]*(/(/p' code/*.[ch] | sort | uniq -c</pre>
</div>
@ -177,7 +177,7 @@ same signature value is being used for different signatures. This is
undesirable and the problem should be investigated.</p>
</div>
<div class="section" id="references">
<h2>7.8. References<a class="headerlink" href="#references" title="Permalink to this headline"></a></h2>
<h2>11.8. References<a class="headerlink" href="#references" title="Permalink to this headline"></a></h2>
<table class="docutils citation" frame="void" id="rb-1995-08-25" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
@ -204,22 +204,22 @@ undesirable and the problem should be investigated.</p>
</a></p>
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">7. Signatures in the MPS</a><ul>
<li><a class="reference internal" href="#introduction">7.1. Introduction</a></li>
<li><a class="reference internal" href="#overview">7.2. Overview</a></li>
<li><a class="reference internal" href="#definitions">7.3. Definitions</a></li>
<li><a class="reference internal" href="#init-and-finish">7.4. Init and Finish</a></li>
<li><a class="reference internal" href="#checking">7.5. Checking</a></li>
<li><a class="reference internal" href="#rules">7.6. Rules</a></li>
<li><a class="reference internal" href="#tools">7.7. Tools</a></li>
<li><a class="reference internal" href="#references">7.8. References</a></li>
<li><a class="reference internal" href="#">11. Signatures in the MPS</a><ul>
<li><a class="reference internal" href="#introduction">11.1. Introduction</a></li>
<li><a class="reference internal" href="#overview">11.2. Overview</a></li>
<li><a class="reference internal" href="#definitions">11.3. Definitions</a></li>
<li><a class="reference internal" href="#init-and-finish">11.4. Init and Finish</a></li>
<li><a class="reference internal" href="#checking">11.5. Checking</a></li>
<li><a class="reference internal" href="#rules">11.6. Rules</a></li>
<li><a class="reference internal" href="#tools">11.7. Tools</a></li>
<li><a class="reference internal" href="#references">11.8. References</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="ring.html"
title="previous chapter">6. Ring data structure</a></p>
title="previous chapter">10. Ring data structure</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="old.html"
title="next chapter">Old design</a></p><h4>Downloads</h4>
@ -251,7 +251,7 @@ undesirable and the problem should be investigated.</p>
<a href="old.html" title="Old design"
>next</a> |</li>
<li class="right" >
<a href="ring.html" title="6. Ring data structure"
<a href="ring.html" title="10. Ring data structure"
>previous</a> |</li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
<li><a href="index.html" >Design</a> &raquo;</li>

View file

@ -230,6 +230,50 @@
</dt>
<dt><a href="design/abq.html#ABQ">ABQ (C type)</a>
</dt>
<dt><a href="design/abq.html#ABQDepth">ABQDepth (C function)</a>
</dt>
<dt><a href="design/abq.html#ABQFinish">ABQFinish (C function)</a>
</dt>
<dt><a href="design/abq.html#ABQInit">ABQInit (C function)</a>
</dt>
<dt><a href="design/abq.html#ABQIsEmpty">ABQIsEmpty (C function)</a>
</dt>
<dt><a href="design/abq.html#ABQIsFull">ABQIsFull (C function)</a>
</dt>
<dt><a href="design/abq.html#ABQIterate">ABQIterate (C function)</a>
</dt>
<dt><a href="design/abq.html#ABQIterateMethod">ABQIterateMethod (C type)</a>
</dt>
<dt><a href="design/abq.html#ABQPeek">ABQPeek (C function)</a>
</dt>
<dt><a href="design/abq.html#ABQPop">ABQPop (C function)</a>
</dt>
<dt><a href="design/abq.html#ABQPush">ABQPush (C function)</a>
</dt>
<dt><a href="glossary/a.html#term-absolute-address"><strong>absolute address</strong></a>
</dt>
@ -451,6 +495,8 @@
</dt>
</dl></dd>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="glossary/a.html#term-ambiguous-root"><strong>ambiguous root</strong></a>
</dt>
@ -492,8 +538,6 @@
<dt><a href="design/poolamc.html#AMCBufferFill">AMCBufferFill (C function)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="design/poolamc.html#AMCFinish">AMCFinish (C function)</a>
</dt>
@ -1324,6 +1368,50 @@
</dl></dd>
<dt><a href="design/cbs.html#CBS">CBS (C type)</a>
</dt>
<dt><a href="design/cbs.html#CBSDelete">CBSDelete (C function)</a>
</dt>
<dt><a href="design/cbs.html#CBSDescribe">CBSDescribe (C function)</a>
</dt>
<dt><a href="design/cbs.html#CBSFindFirst">CBSFindFirst (C function)</a>
</dt>
<dt><a href="design/cbs.html#CBSFindLargest">CBSFindLargest (C function)</a>
</dt>
<dt><a href="design/cbs.html#CBSFindLast">CBSFindLast (C function)</a>
</dt>
<dt><a href="design/cbs.html#CBSFinish">CBSFinish (C function)</a>
</dt>
<dt><a href="design/cbs.html#CBSInit">CBSInit (C function)</a>
</dt>
<dt><a href="design/cbs.html#CBSInsert">CBSInsert (C function)</a>
</dt>
<dt><a href="design/cbs.html#CBSIterate">CBSIterate (C function)</a>
</dt>
<dt><a href="design/cbs.html#CBSIterateMethod">CBSIterateMethod (C type)</a>
</dt>
<dt><a href="glossary/c.html#term-cell"><strong>cell</strong></a>
</dt>
@ -1424,6 +1512,8 @@
<dt><a href="mmref/lang.html#term-cobol"><strong>COBOL</strong></a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt>
code
@ -1468,8 +1558,6 @@
</dt>
</dl></dd>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="glossary/c.html#term-collector-1"><strong>collector (1)</strong></a>
</dt>
@ -2392,8 +2480,6 @@
</dt>
</dl></dd>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="mmref/lang.html#term-fortran"><strong>Fortran</strong></a>
</dt>
@ -2418,6 +2504,8 @@
<dt><a href="glossary/f.html#term-fragmentation"><strong>fragmentation</strong></a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="glossary/f.html#term-frame"><strong>frame</strong></a>
</dt>
@ -2473,6 +2561,54 @@
</dt>
<dt><a href="design/freelist.html#Freelist">Freelist (C type)</a>
</dt>
<dt><a href="design/freelist.html#FreelistDelete">FreelistDelete (C function)</a>
</dt>
<dt><a href="design/freelist.html#FreelistDescribe">FreelistDescribe (C function)</a>
</dt>
<dt><a href="design/freelist.html#FreelistFindFirst">FreelistFindFirst (C function)</a>
</dt>
<dt><a href="design/freelist.html#FreelistFindLargest">FreelistFindLargest (C function)</a>
</dt>
<dt><a href="design/freelist.html#FreelistFindLast">FreelistFindLast (C function)</a>
</dt>
<dt><a href="design/freelist.html#FreelistFinish">FreelistFinish (C function)</a>
</dt>
<dt><a href="design/freelist.html#FreelistFlushToCBS">FreelistFlushToCBS (C function)</a>
</dt>
<dt><a href="design/freelist.html#FreelistInit">FreelistInit (C function)</a>
</dt>
<dt><a href="design/freelist.html#FreelistInsert">FreelistInsert (C function)</a>
</dt>
<dt><a href="design/freelist.html#FreelistIterate">FreelistIterate (C function)</a>
</dt>
<dt><a href="design/freelist.html#FreelistIterateMethod">FreelistIterateMethod (C type)</a>
</dt>
<dt><a href="topic/plinth.html#index-0">freestanding environment</a>
</dt>
@ -5717,6 +5853,42 @@
</dt>
<dt><a href="design/range.html#Range">Range (C type)</a>
</dt>
<dt><a href="design/range.html#RangeBase">RangeBase (C function)</a>
</dt>
<dt><a href="design/range.html#RangeFinish">RangeFinish (C function)</a>
</dt>
<dt><a href="design/range.html#RangeInit">RangeInit (C function)</a>
</dt>
<dt><a href="design/range.html#RangeIsAligned">RangeIsAligned (C function)</a>
</dt>
<dt><a href="design/range.html#RangeLimit">RangeLimit (C function)</a>
</dt>
<dt><a href="design/range.html#RangeSize">RangeSize (C function)</a>
</dt>
<dt><a href="design/range.html#RangesNest">RangesNest (C function)</a>
</dt>
<dt><a href="design/range.html#RangesOverlap">RangesOverlap (C function)</a>
</dt>
<dt><a href="glossary/r.html#term-rank"><strong>rank</strong></a>
</dt>
@ -5816,6 +5988,8 @@
<dt><a href="glossary/r.html#term-relocation"><strong>relocation</strong></a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="glossary/r.html#term-remembered-set"><strong>remembered set</strong></a>
</dt>
@ -5836,8 +6010,6 @@
<dt><a href="glossary/r.html#term-reserved"><strong>reserved</strong></a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt>
reservoir

View file

@ -1,145 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Memory Management Glossary &mdash; Memory Pool System 1.111.0 documentation</title>
<link rel="stylesheet" href="../_static/mps.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../',
VERSION: '1.111.0',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<link rel="copyright" title="Copyright" href="../copyright.html" />
<link rel="top" title="Memory Pool System 1.111.0 documentation" href="../index.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="memory-management-glossary">
<span id="glossary"></span><h1>Memory Management Glossary<a class="headerlink" href="#memory-management-glossary" title="Permalink to this headline"></a></h1>
<p class="glossary-alphabet"><a class="reference internal" href="a.html#glossary-a"><em>A</em></a>
| <a class="reference internal" href="b.html#glossary-b"><em>B</em></a>
| <a class="reference internal" href="c.html#glossary-c"><em>C</em></a>
| <a class="reference internal" href="d.html#glossary-d"><em>D</em></a>
| <a class="reference internal" href="e.html#glossary-e"><em>E</em></a>
| <a class="reference internal" href="f.html#glossary-f"><em>F</em></a>
| <a class="reference internal" href="g.html#glossary-g"><em>G</em></a>
| <a class="reference internal" href="h.html#glossary-h"><em>H</em></a>
| <a class="reference internal" href="i.html#glossary-i"><em>I</em></a>
| J
| <a class="reference internal" href="k.html#glossary-k"><em>K</em></a>
| <a class="reference internal" href="l.html#glossary-l"><em>L</em></a>
| <a class="reference internal" href="m.html#glossary-m"><em>M</em></a>
| <a class="reference internal" href="n.html#glossary-n"><em>N</em></a>
| <a class="reference internal" href="o.html#glossary-o"><em>O</em></a>
| <a class="reference internal" href="p.html#glossary-p"><em>P</em></a>
| <a class="reference internal" href="q.html#glossary-q"><em>Q</em></a>
| <a class="reference internal" href="r.html#glossary-r"><em>R</em></a>
| <a class="reference internal" href="s.html#glossary-s"><em>S</em></a>
| <a class="reference internal" href="t.html#glossary-t"><em>T</em></a>
| <a class="reference internal" href="u.html#glossary-u"><em>U</em></a>
| <a class="reference internal" href="v.html#glossary-v"><em>V</em></a>
| <a class="reference internal" href="w.html#glossary-w"><em>W</em></a>
| X
| Y
| <a class="reference internal" href="z.html#glossary-z"><em>Z</em></a></p>
<div class="toctree-wrapper compound">
<ul>
<li class="toctree-l1"><a class="reference internal" href="a.html">Memory Management Glossary: A</a></li>
<li class="toctree-l1"><a class="reference internal" href="b.html">Memory Management Glossary: B</a></li>
<li class="toctree-l1"><a class="reference internal" href="c.html">Memory Management Glossary: C</a></li>
<li class="toctree-l1"><a class="reference internal" href="d.html">Memory Management Glossary: D</a></li>
<li class="toctree-l1"><a class="reference internal" href="e.html">Memory Management Glossary: E</a></li>
<li class="toctree-l1"><a class="reference internal" href="f.html">Memory Management Glossary: F</a></li>
<li class="toctree-l1"><a class="reference internal" href="g.html">Memory Management Glossary: G</a></li>
<li class="toctree-l1"><a class="reference internal" href="h.html">Memory Management Glossary: H</a></li>
<li class="toctree-l1"><a class="reference internal" href="i.html">Memory Management Glossary: I</a></li>
<li class="toctree-l1"><a class="reference internal" href="k.html">Memory Management Glossary: K</a></li>
<li class="toctree-l1"><a class="reference internal" href="l.html">Memory Management Glossary: L</a></li>
<li class="toctree-l1"><a class="reference internal" href="m.html">Memory Management Glossary: M</a></li>
<li class="toctree-l1"><a class="reference internal" href="n.html">Memory Management Glossary: N</a></li>
<li class="toctree-l1"><a class="reference internal" href="o.html">Memory Management Glossary: O</a></li>
<li class="toctree-l1"><a class="reference internal" href="p.html">Memory Management Glossary: P</a></li>
<li class="toctree-l1"><a class="reference internal" href="q.html">Memory Management Glossary: Q</a></li>
<li class="toctree-l1"><a class="reference internal" href="r.html">Memory Management Glossary: R</a></li>
<li class="toctree-l1"><a class="reference internal" href="s.html">Memory Management Glossary: S</a></li>
<li class="toctree-l1"><a class="reference internal" href="t.html">Memory Management Glossary: T</a></li>
<li class="toctree-l1"><a class="reference internal" href="u.html">Memory Management Glossary: U</a></li>
<li class="toctree-l1"><a class="reference internal" href="v.html">Memory Management Glossary: V</a></li>
<li class="toctree-l1"><a class="reference internal" href="w.html">Memory Management Glossary: W</a></li>
<li class="toctree-l1"><a class="reference internal" href="z.html">Memory Management Glossary: Z</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../index.html">
<img class="logo" src="../_static/logo.png" alt="Logo"/>
</a></p><h4>Downloads</h4>
<p class="topless">
<a href="http://www.ravenbrook.com/project/mps/release/1.111.0/">MPS Kit release 1.111.0</a><br>
<a href="http://www.ravenbrook.com/project/mps/release/">All MPS Kit releases</a>
</p>
<h4>Issues</h4>
<p class="topless">
<a href="http://www.ravenbrook.com/project/mps/issue/?action=list&amp;view=status%3dopen&amp;display=Job:Priority:Title&amp;sort=Priority">Known issues</a><br>
<a href="http://www.ravenbrook.com/project/mps/issue/?action=fixed&release_fixed=1.111.0">Issues fixed in release 1.111.0</a>
</p><h4>Contact us</h4>
<p class="topless"><a href="mailto:mps-questions@ravenbrook.com">mps-questions@ravenbrook.com</a></p>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; <a href="../copyright.html">Copyright</a> 2013, Ravenbrook Limited.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>

View file

@ -103,13 +103,17 @@
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="design/index.html">Design</a><ul>
<li class="toctree-l2"><a class="reference internal" href="design/config.html">1. MPS Configuration</a></li>
<li class="toctree-l2"><a class="reference internal" href="design/critical-path.html">2. The critical path through the MPS</a></li>
<li class="toctree-l2"><a class="reference internal" href="design/guide.hex.trans.html">3. Transliterating the alphabet into hexadecimal</a></li>
<li class="toctree-l2"><a class="reference internal" href="design/guide.impl.c.format.html">4. C Style &#8211; formatting</a></li>
<li class="toctree-l2"><a class="reference internal" href="design/keyword-arguments.html">5. Keyword arguments in the MPS</a></li>
<li class="toctree-l2"><a class="reference internal" href="design/ring.html">6. Ring data structure</a></li>
<li class="toctree-l2"><a class="reference internal" href="design/sig.html">7. Signatures in the MPS</a></li>
<li class="toctree-l2"><a class="reference internal" href="design/abq.html">1. Queue design</a></li>
<li class="toctree-l2"><a class="reference internal" href="design/cbs.html">2. Coalescing block structure</a></li>
<li class="toctree-l2"><a class="reference internal" href="design/config.html">3. MPS Configuration</a></li>
<li class="toctree-l2"><a class="reference internal" href="design/critical-path.html">4. The critical path through the MPS</a></li>
<li class="toctree-l2"><a class="reference internal" href="design/freelist.html">5. Free list allocator</a></li>
<li class="toctree-l2"><a class="reference internal" href="design/guide.hex.trans.html">6. Transliterating the alphabet into hexadecimal</a></li>
<li class="toctree-l2"><a class="reference internal" href="design/guide.impl.c.format.html">7. C Style &#8211; formatting</a></li>
<li class="toctree-l2"><a class="reference internal" href="design/keyword-arguments.html">8. Keyword arguments in the MPS</a></li>
<li class="toctree-l2"><a class="reference internal" href="design/range.html">9. Ranges</a></li>
<li class="toctree-l2"><a class="reference internal" href="design/ring.html">10. Ring data structure</a></li>
<li class="toctree-l2"><a class="reference internal" href="design/sig.html">11. Signatures in the MPS</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="design/old.html">Old design</a><ul>

Binary file not shown.

View file

@ -353,7 +353,7 @@ references<sup>(1)</sup></em></a>.</p>
<td><a class="footnote-reference" href="#id27" id="id11">[6]</a></td>
<td><a class="footnote-reference" href="#id27" id="id12">[6]</a></td>
<td><a class="footnote-reference" href="#id28" id="id13">[7]</a></td>
<td><a class="footnote-reference" href="#id27" id="id14">[6]</a></td>
<td><a class="footnote-reference" href="#id28" id="id14">[7]</a></td>
<td>conf</td>
</tr>
<tr class="row-even"><td>Dependent objects? <a class="footnote-reference" href="#id29" id="id15">[8]</a></td>
@ -539,16 +539,17 @@ indicated <a class="reference internal" href="../glossary/r.html#term-rank"><em
<table class="docutils footnote" frame="void" id="id27" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label">[6]</td><td><em>(<a class="fn-backref" href="#id11">1</a>, <a class="fn-backref" href="#id12">2</a>, <a class="fn-backref" href="#id14">3</a>)</em> The alignment of blocks allocated from <a class="reference internal" href="mv.html#pool-mv"><em>MV (Manual Variable)</em></a> and
<a class="reference internal" href="mvt.html#pool-mvt"><em>MVT (Manual Variable Temporal)</em></a> pools is platform-dependent.</td></tr>
<tr><td class="label">[6]</td><td><em>(<a class="fn-backref" href="#id11">1</a>, <a class="fn-backref" href="#id12">2</a>)</em> The alignment of blocks allocated from <a class="reference internal" href="mv.html#pool-mv"><em>MV (Manual Variable)</em></a> pools
is platform-dependent.</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="id28" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id13">[7]</a></td><td><a class="reference internal" href="mvff.html#pool-mvff"><em>MVFF (Manual Variable First Fit)</em></a> pools have configurable alignment, but it
may not be smaller than the <a class="reference internal" href="../glossary/n.html#term-natural-alignment"><em class="xref std std-term">natural alignment</em></a> for
the <a class="reference internal" href="../glossary/p.html#term-platform"><em class="xref std std-term">platform</em></a> (see <a class="reference internal" href="../topic/platform.html#MPS_PF_ALIGN" title="MPS_PF_ALIGN"><tt class="xref c c-macro docutils literal"><span class="pre">MPS_PF_ALIGN</span></tt></a>).</td></tr>
<tr><td class="label">[7]</td><td><em>(<a class="fn-backref" href="#id13">1</a>, <a class="fn-backref" href="#id14">2</a>)</em> <a class="reference internal" href="mvt.html#pool-mvt"><em>MVT (Manual Variable Temporal)</em></a> and <a class="reference internal" href="mvff.html#pool-mvff"><em>MVFF (Manual Variable First Fit)</em></a> pools have
configurable alignment, but it may not be smaller than the
<a class="reference internal" href="../glossary/n.html#term-natural-alignment"><em class="xref std std-term">natural alignment</em></a> for the <a class="reference internal" href="../glossary/p.html#term-platform"><em class="xref std std-term">platform</em></a> (see
<a class="reference internal" href="../topic/platform.html#MPS_PF_ALIGN" title="MPS_PF_ALIGN"><tt class="xref c c-macro docutils literal"><span class="pre">MPS_PF_ALIGN</span></tt></a>).</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="id29" rules="none">

View file

@ -123,8 +123,15 @@ managed pools (unless these are registered as <a class="reference internal" href
<dd><p>Return the <a class="reference internal" href="../glossary/p.html#term-pool-class"><em class="xref std std-term">pool class</em></a> for an MVT (Manual Variable
Temporal) <a class="reference internal" href="../glossary/p.html#term-pool"><em class="xref std std-term">pool</em></a>.</p>
<p>When creating an MVT pool, <a class="reference internal" href="../topic/pool.html#mps_pool_create_k" title="mps_pool_create_k"><tt class="xref c c-func docutils literal"><span class="pre">mps_pool_create_k()</span></tt></a> may take
five <a class="reference internal" href="../glossary/k.html#term-keyword-argument"><em class="xref std std-term">keyword arguments</em></a>:</p>
six <a class="reference internal" href="../glossary/k.html#term-keyword-argument"><em class="xref std std-term">keyword arguments</em></a>:</p>
<ul class="simple">
<li><tt class="xref c c-macro docutils literal"><span class="pre">MPS_KEY_ALIGN</span></tt> (type <a class="reference internal" href="../topic/interface.html#mps_align_t" title="mps_align_t"><tt class="xref c c-type docutils literal"><span class="pre">mps_align_t</span></tt></a>, default is
smallest general purpose alignment for the architecture) is the
<a class="reference internal" href="../glossary/a.html#term-alignment"><em class="xref std std-term">alignment</em></a> of addresses for allocation (and freeing) in
the pool. If an unaligned size is passed to <a class="reference internal" href="../topic/allocation.html#mps_alloc" title="mps_alloc"><tt class="xref c c-func docutils literal"><span class="pre">mps_alloc()</span></tt></a> or
<a class="reference internal" href="../topic/allocation.html#mps_free" title="mps_free"><tt class="xref c c-func docutils literal"><span class="pre">mps_free()</span></tt></a>, it will be rounded up to the pool&#8217;s alignment.
The minimum alignment supported by pools of this class is
<tt class="docutils literal"><span class="pre">sizeof(void</span> <span class="pre">*)</span></tt>.</li>
<li><tt class="xref c c-macro docutils literal"><span class="pre">MPS_KEY_MIN_SIZE</span></tt> (type <tt class="xref c c-type docutils literal"><span class="pre">size_t</span></tt>, default is
smallest general purpose alignment for the architecture) is the
predicted minimum size of blocks that will be allocated from the
@ -138,9 +145,9 @@ pool. Partial freeing is not supported for blocks larger than
this; doing so will result in the storage of the block never
being reused.</li>
</ul>
<p>These three arguments are <em>hints</em> to the MPS: the pool will be
less efficient if they are wrong, but the only thing that will
break is the partial freeing of large blocks.</p>
<p>The three <tt class="docutils literal"><span class="pre">SIZE</span></tt> arguments above are <em>hints</em> to the MPS: the
pool will be less efficient if they are wrong, but the only thing
that will break is the partial freeing of large blocks.</p>
<ul>
<li><p class="first"><tt class="xref c c-macro docutils literal"><span class="pre">MPS_KEY_MVT_RESERVE_DEPTH</span></tt> (type
<tt class="xref c c-type docutils literal"><span class="pre">mps_count_t</span></tt>) is the expected hysteresis of the

File diff suppressed because one or more lines are too long