From eaad4493d48f015c98331b92ff73434e100bcf09 Mon Sep 17 00:00:00 2001
From: Gareth Rees
Date: Sat, 11 May 2013 20:07:28 +0100
Subject: [PATCH] Bring html up to date.
Copied from Perforce
Change: 181731
ServerID: perforce.ravenbrook.com
---
mps/manual/html/_downloads/scheme-advanced.c | 46 +-
mps/manual/html/_downloads/scheme.c | 17 +-
mps/manual/html/_sources/design/cbs.txt | 695 ------------------
mps/manual/html/_sources/design/check.txt | 106 ---
mps/manual/html/_sources/glossary/c.txt | 33 +
mps/manual/html/_sources/glossary/k.txt | 11 +
mps/manual/html/_sources/guide/advanced.txt | 29 +-
mps/manual/html/_sources/guide/lang.txt | 41 +-
mps/manual/html/_sources/mmref/bib.txt | 8 +
mps/manual/html/_sources/mmref/lang.txt | 2 +-
mps/manual/html/_sources/pool/amc.txt | 38 +-
mps/manual/html/_sources/pool/amcz.txt | 37 +-
mps/manual/html/_sources/pool/ams.txt | 59 +-
mps/manual/html/_sources/pool/awl.txt | 69 +-
mps/manual/html/_sources/pool/lo.txt | 28 +-
mps/manual/html/_sources/pool/mfs.txt | 42 +-
mps/manual/html/_sources/pool/mv.txt | 72 +-
mps/manual/html/_sources/pool/mvff.txt | 108 ++-
mps/manual/html/_sources/pool/mvt.txt | 137 ++--
mps/manual/html/_sources/pool/snc.txt | 54 +-
mps/manual/html/_sources/topic/allocation.txt | 33 +-
mps/manual/html/_sources/topic/arena.txt | 149 ++--
mps/manual/html/_sources/topic/debugging.txt | 13 +-
mps/manual/html/_sources/topic/error.txt | 2 +-
mps/manual/html/_sources/topic/format.txt | 4 +-
mps/manual/html/_sources/topic/index.txt | 1 +
mps/manual/html/_sources/topic/interface.txt | 47 +-
mps/manual/html/_sources/topic/keyword.txt | 190 +++++
mps/manual/html/_sources/topic/pool.txt | 30 +-
mps/manual/html/_static/pygments.css | 4 +-
mps/manual/html/design/arena.html | 2 +-
mps/manual/html/design/bt.html | 2 +-
mps/manual/html/design/config.html | 10 +-
mps/manual/html/genindex.html | 84 ++-
mps/manual/html/glossary/c.html | 39 +
mps/manual/html/glossary/k.html | 10 +
mps/manual/html/guide/advanced.html | 135 ++--
mps/manual/html/guide/debug.html | 8 +-
mps/manual/html/guide/lang.html | 151 ++--
mps/manual/html/index.html | 37 +-
mps/manual/html/mmref/bib.html | 4 +
mps/manual/html/mmref/lang.html | 2 +-
mps/manual/html/objects.inv | Bin 21989 -> 22212 bytes
mps/manual/html/pool/amc.html | 41 +-
mps/manual/html/pool/amcz.html | 40 +-
mps/manual/html/pool/ams.html | 63 +-
mps/manual/html/pool/awl.html | 95 ++-
mps/manual/html/pool/index.html | 8 +-
mps/manual/html/pool/lo.html | 31 +-
mps/manual/html/pool/mfs.html | 45 +-
mps/manual/html/pool/mv.html | 74 +-
mps/manual/html/pool/mvff.html | 113 ++-
mps/manual/html/pool/mvt.html | 119 +--
mps/manual/html/pool/snc.html | 60 +-
mps/manual/html/searchindex.js | 2 +-
mps/manual/html/topic/allocation.html | 132 ++--
mps/manual/html/topic/arena.html | 185 +++--
mps/manual/html/topic/cache.html | 36 +-
mps/manual/html/topic/collection.html | 42 +-
mps/manual/html/topic/critical.html | 12 +-
mps/manual/html/topic/debugging.html | 37 +-
mps/manual/html/topic/error.html | 42 +-
mps/manual/html/topic/finalization.html | 40 +-
mps/manual/html/topic/format.html | 90 +--
mps/manual/html/topic/frame.html | 20 +-
mps/manual/html/topic/index.html | 187 ++---
mps/manual/html/topic/interface.html | 21 +-
mps/manual/html/topic/keyword.html | 369 ++++++++++
mps/manual/html/topic/location.html | 64 +-
mps/manual/html/topic/message.html | 48 +-
mps/manual/html/topic/pattern.html | 26 +-
mps/manual/html/topic/plinth.html | 4 +-
mps/manual/html/topic/pool.html | 65 +-
mps/manual/html/topic/root.html | 66 +-
mps/manual/html/topic/scanning.html | 72 +-
mps/manual/html/topic/telemetry.html | 58 +-
mps/manual/html/topic/thread.html | 38 +-
mps/manual/html/topic/weak.html | 20 +-
78 files changed, 2746 insertions(+), 2208 deletions(-)
delete mode 100644 mps/manual/html/_sources/design/cbs.txt
delete mode 100644 mps/manual/html/_sources/design/check.txt
create mode 100644 mps/manual/html/_sources/topic/keyword.txt
create mode 100644 mps/manual/html/topic/keyword.html
diff --git a/mps/manual/html/_downloads/scheme-advanced.c b/mps/manual/html/_downloads/scheme-advanced.c
index 7e6754be1d0..2c86aade2dd 100644
--- a/mps/manual/html/_downloads/scheme-advanced.c
+++ b/mps/manual/html/_downloads/scheme-advanced.c
@@ -4470,9 +4470,9 @@ int main(int argc, char *argv[])
/* Create an MPS arena. There is usually only one of these in a process.
It holds all the MPS "global" state and is where everything happens. */
- res = mps_arena_create(&arena,
- mps_arena_class_vm(),
- (size_t)(32ul * 1024 * 1024));
+ res = mps_arena_create_k(&arena, mps_arena_class_vm(),
+ (mps_arg_s[]){{MPS_KEY_ARENA_SIZE, .val.size = 32 * 1024 * 1024},
+ {MPS_KEY_ARGS_END}});
if (res != MPS_RES_OK) error("Couldn't create arena");
/* Create the object format. */
@@ -4488,31 +4488,29 @@ int main(int argc, char *argv[])
/* Create an Automatic Mostly-Copying (AMC) pool to manage the Scheme
objects. This is a kind of copying garbage collector. */
- res = mps_pool_create(&obj_pool,
- arena,
- mps_class_amc(),
- obj_fmt,
- obj_chain);
+ res = mps_pool_create_k(&obj_pool, arena, mps_class_amc(),
+ (mps_arg_s[]){{MPS_KEY_CHAIN, .val.chain = obj_chain},
+ {MPS_KEY_FORMAT, .val.format = obj_fmt},
+ {MPS_KEY_ARGS_END}});
if (res != MPS_RES_OK) error("Couldn't create obj pool");
/* Create an allocation point for fast in-line allocation of objects
from the `obj_pool`. You'd usually want one of these per thread
for your primary pools. This interpreter is single threaded, though,
so we just have it in a global. See topic/allocation. */
- res = mps_ap_create(&obj_ap, obj_pool);
+ res = mps_ap_create_k(&obj_ap, obj_pool, mps_args_none);
if (res != MPS_RES_OK) error("Couldn't create obj allocation point");
/* Create an Automatic Mostly-Copying Zero-rank (AMCZ) pool to
manage the leaf objects. */
- res = mps_pool_create(&leaf_pool,
- arena,
- mps_class_amcz(),
- obj_fmt,
- obj_chain);
+ res = mps_pool_create_k(&leaf_pool, arena, mps_class_amcz(),
+ (mps_arg_s[]){{MPS_KEY_CHAIN, .val.chain = obj_chain},
+ {MPS_KEY_FORMAT, .val.format = obj_fmt},
+ {MPS_KEY_ARGS_END}});
if (res != MPS_RES_OK) error("Couldn't create leaf pool");
/* Create allocation point for leaf objects. */
- res = mps_ap_create(&leaf_ap, leaf_pool);
+ res = mps_ap_create_k(&leaf_ap, leaf_pool, mps_args_none);
if (res != MPS_RES_OK) error("Couldn't create leaf objects allocation point");
/* Create the buckets format. */
@@ -4521,17 +4519,21 @@ int main(int argc, char *argv[])
/* Create an Automatic Weak Linked (AWL) pool to manage the hash table
buckets. */
- res = mps_pool_create(&buckets_pool,
- arena,
- mps_class_awl(),
- buckets_fmt,
- buckets_find_dependent);
+ res = mps_pool_create_k(&buckets_pool, arena, mps_class_awl(),
+ (mps_arg_s[]){{MPS_KEY_FORMAT, .val.format = buckets_fmt},
+ {MPS_KEY_AWL_FIND_DEPENDENT,
+ .val.addr_method = buckets_find_dependent},
+ {MPS_KEY_ARGS_END}});
if (res != MPS_RES_OK) error("Couldn't create buckets pool");
/* Create allocation points for weak and strong buckets. */
- res = mps_ap_create(&strong_buckets_ap, buckets_pool, mps_rank_exact());
+ res = mps_ap_create_k(&strong_buckets_ap, buckets_pool,
+ (mps_arg_s[]){{MPS_KEY_RANK, .val.rank = mps_rank_exact()},
+ {MPS_KEY_ARGS_END}});
if (res != MPS_RES_OK) error("Couldn't create strong buckets allocation point");
- res = mps_ap_create(&weak_buckets_ap, buckets_pool, mps_rank_weak());
+ res = mps_ap_create_k(&weak_buckets_ap, buckets_pool,
+ (mps_arg_s[]){{MPS_KEY_RANK, .val.rank = mps_rank_weak()},
+ {MPS_KEY_ARGS_END}});
if (res != MPS_RES_OK) error("Couldn't create weak buckets allocation point");
/* Register the current thread with the MPS. The MPS must sometimes
diff --git a/mps/manual/html/_downloads/scheme.c b/mps/manual/html/_downloads/scheme.c
index 3d595e0f641..2bac9c0042d 100644
--- a/mps/manual/html/_downloads/scheme.c
+++ b/mps/manual/html/_downloads/scheme.c
@@ -4391,9 +4391,9 @@ int main(int argc, char *argv[])
/* Create an MPS arena. There is usually only one of these in a process.
It holds all the MPS "global" state and is where everything happens. */
- res = mps_arena_create(&arena,
- mps_arena_class_vm(),
- (size_t)(32 * 1024 * 1024));
+ res = mps_arena_create_k(&arena, mps_arena_class_vm(),
+ (mps_arg_s[]){{MPS_KEY_ARENA_SIZE, .val.size = 32 * 1024 * 1024},
+ {MPS_KEY_ARGS_END}});
if (res != MPS_RES_OK) error("Couldn't create arena");
/* Create the object format. */
@@ -4409,18 +4409,17 @@ int main(int argc, char *argv[])
/* Create an Automatic Mostly-Copying (AMC) pool to manage the Scheme
objects. This is a kind of copying garbage collector. */
- res = mps_pool_create(&obj_pool,
- arena,
- mps_class_amc(),
- obj_fmt,
- obj_chain);
+ res = mps_pool_create_k(&obj_pool, arena, mps_class_amc(),
+ (mps_arg_s[]){{MPS_KEY_CHAIN, .val.chain = obj_chain},
+ {MPS_KEY_FORMAT, .val.format = obj_fmt},
+ {MPS_KEY_ARGS_END}});
if (res != MPS_RES_OK) error("Couldn't create obj pool");
/* Create an allocation point for fast in-line allocation of objects
from the `obj_pool`. You'd usually want one of these per thread
for your primary pools. This interpreter is single threaded, though,
so we just have it in a global. See topic/allocation. */
- res = mps_ap_create(&obj_ap, obj_pool);
+ res = mps_ap_create_k(&obj_ap, obj_pool, mps_args_none);
if (res != MPS_RES_OK) error("Couldn't create obj allocation point");
/* Register the current thread with the MPS. The MPS must sometimes
diff --git a/mps/manual/html/_sources/design/cbs.txt b/mps/manual/html/_sources/design/cbs.txt
deleted file mode 100644
index 0956be703a0..00000000000
--- a/mps/manual/html/_sources/design/cbs.txt
+++ /dev/null
@@ -1,695 +0,0 @@
-.. sources:
-
- ``_
-
-
-.. mps:prefix:: design.mps.cbs
-
-Coalescing block structure
-==========================
-
-
-Introduction
-------------
-
-:mps:tag:`intro` This is the design for :mps:ref:`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` :mps:ref:`design.mps.poolmv2`, :mps:ref:`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.
-
-
-History
--------
-
-:mps:tag:`hist.0` This document was derived from the outline in
-:mps:ref:`design.mps.poolmv2(2)`. Written by Gavin Matthews
-1998-05-01.
-
-:mps:tag:`hist.1` Updated by Gavin Matthews 1998-07-22 in response to
-approval comments in :mps:ref:`change.epcore.anchovy.160040` There is
-too much fragmentation in trapping memory.
-
-:mps:tag:`hist.2` Updated by Gavin Matthews (as part of
-:mps:ref:`change.epcore.brisling.160158`: MVFF cannot be instantiated
-with 4-byte alignment) to document new alignment restrictions.
-
-:mps:tag:`hist.3` Converted from MMInfo database design document.
-Richard Brooksby, 2002-06-07.
-
-:mps:tag:`hist.4` Converted to reStructuredText. Gareth Rees,
-2013-04-14.
-
-
-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.
-
-:mps:tag:`def.interesting` A block is interesting if it is of at least
-the minimum interesting size specified by the client.
-
-
-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 :mps:ref:`impl.h.cbs`.
-
-
-External types
-..............
-
-.. c:type:: typedef struct CBSStruct CBSStruct, *CBS;
-
-:mps:tag:`type.cbs` :c:type:`CBS` is the main datastructure 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:: typedef struct CBSBlockStruct CBSBlockStruct, *CBSBlock;
-
-:mps:tag:`type.cbs.block` :c:type:`CBSBlock` is the data-structure
-that represents an isolated contiguous range held by the CBS. It is
-returned by the new and delete methods described below.
-
-:mps:tag:`type.cbs.method` The following methods are provided as
-callbacks to advise the client of certain events. The implementation
-of these functions should not cause any CBS function to be called on
-the same CBS. In this respect, the CBS module is not re-entrant.
-
-.. c:type:: typedef void (*CBSChangeSizeMethod)(CBS cbs, CBSBlock block, Size oldSize, SizeNewSize);
-
-:mps:tag:`type.cbs.change.size.method` :c:type:`CBSChangeSizeMethod`
-is the function pointer type, four instances of which are optionally
-registered via CBSInit.
-
-These callbacks are invoked under :c:func:`CBSInsert`,
-:c:func:`CBSDelete`, or :c:func:`CBSSetMinSize` in certain
-circumstances. Unless otherwise stated, ``oldSize`` and ``newSize``
-will both be non-zero, and different. The accessors
-:c:func:`CBSBlockBase`, :c:func:`CBSBlockLimit`, and
-:c:func:`CBSBlockSize` may be called from within these callbacks,
-except within the delete callback when ``newSize`` is zero. See
-:mps:ref:`.impl.callback` for implementation details.
-
-.. c:type:: typedef Bool (*CBSIterateMethod)(CBS cbs, CBSBlock block, void *closureP, unsigned long closureS);
-
-:mps:tag:`type.cbs.iterate.method` :c:type:`CBSIterateMethod` is a
-function pointer type for a client method invoked by the CBS module
-for every isolated contiguous range in address order, when passed to
-the :c:func:`CBSIterate` or :c:func:`CBSIterateLarge` functions. The
-function returns a boolean indicating whether to continue with the
-iteration.
-
-
-External functions
-..................
-
-.. c:function:: Res CBSInit(Arena arena, CBS cbs, CBSChangeSizeMethod new, CBSChangeSizeMethod delete, CBSChangeSizeMethod grow, CBSChangeSizeMethod shrink, Size minSize, Align alignment, Bool mayUseInline)
-
-:mps:tag:`function.cbs.init` :c:func:`CBSInit` is the function that
-initialises the CBS structure. It performs allocation in the supplied
-arena. Four methods are passed in as function pointers (see
-:mps:ref:`.type.*` above), any of which may be ``NULL``. It receives a
-minimum size, which is used when determining whether to call the
-optional methods. The ``mayUseInline`` Boolean indicates whether the
-CBS may use the memory in the ranges as a low-memory fallback (see
-:mps:ref:`.impl.low-mem`). The alignment indicates the alignment of
-ranges to be maintained. An initialised CBS contains no ranges.
-
-:mps:tag:`function.cbs.init.may-use-inline` If ``mayUseInline`` is
-set, then ``alignment`` must be at least ``sizeof(void *)``. In this
-mode, the CBS will never fail to insert or delete ranges, even if
-memory for control structures becomes short. Note that, in such cases,
-the CBS may defer notification of new/grow events, but will report
-available blocks in :c:func:`CBSFindFirst` and :c:func:`CBSFindLast`.
-Such low memory conditions will be rare and transitory. See
-:mps:ref:`.align` for more details.
-
-.. 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(CBS cbs, Addr base, Addr limit)
-
-:mps:tag:`function.cbs.insert` :c:func:`CBSInsert` is the function
-used to add a contiguous range specified by ``[base,limit)`` to the
-CBS. If any part of the range is already in the CBS, then
-:c:macro:`ResFAIL` is returned, and the CBS is unchanged. This
-function may cause allocation; if this allocation fails, and any
-contingency mechanism fails, then :c:macro:`ResMEMORY` is returned,
-and the CBS is unchanged.
-
-:mps:tag:`function.cbs.insert.callback` :c:func:`CBSInsert` will invoke callbacks as follows:
-
-* ``new``: when a new block is created that is interesting. ``oldSize == 0; newSize >= minSize``.
-
-* ``new``: when an uninteresting block coalesces to become interesting. ``0 < oldSize < minSize <= newSize``.
-
-* ``delete``: when two interesting blocks are coalesced. ``grow`` will also be invoked in this case on the larger of the two blocks. ``newSize == 0; oldSize >= minSize``.
-
-* ``grow``: when an interesting block grows in size. ``minSize <= oldSize < newSize``.
-
-.. c:function:: Res CBSDelete(CBS cbs, Addr base, Addr limit)
-
-:mps:tag:`function.cbs.delete` :c:func:`CBSDelete` is the function
-used to remove a contiguous range specified by ``[base,limit)`` from
-the CBS. If any part of the range is not in the CBS, then
-:c:macro:`ResFAIL` is returned, and the CBS is unchanged. This
-function may cause allocation; if this allocation fails, and any
-contingency mechanism fails, then :c:macro:`ResMEMORY` is returned,
-and the CBS is unchanged.
-
-:mps:tag:`function.cbs.delete.callback` :c:func:`CBSDelete` will
-invoke callbacks as follows:
-
-* ``delete``: when an interesting block is entirely removed. ``newSize == 0; oldSize >= minSize``.
-* ``delete``: when an interesting block becomes uninteresting. ``0 < newSize < minSize <= oldSize``.
-* ``new``: when a block is split into two blocks, both of which are interesting. ``shrink`` will also be invoked in this case on the larger of the two blocks. ``oldSize == 0; newSize >= minSize``.
-* ``shrink``: when an interesting block shrinks in size, but remains interesting. ``minSize <= newSize < oldSize``.
-
-.. c:function:: void CBSIterate(CBS cbs, CBSIterateMethod iterate, void *closureP, unsigned long 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, unsigned long 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 ``FALSE``, then the iteration is
-terminated.
-
-.. c:function:: void CBSIterateLarge(CBS cbs, CBSIterateMethod iterate, void *closureP, unsigned long closureS)
-
-:mps:tag:`function.cbs.iterate.large` :c:func:`CBSIterateLarge` is the
-function used to iterate all isolated contiguous ranges of size
-greater than or equal to the client indicated minimum size in a CBS.
-It receives a pointer, unsigned long closure pair to pass on to the
-iterator method, and an iterator method to invoke on every large range
-in address order. If the iterator method returns ``FALSE``, then the
-iteration is terminated.
-
-.. c:function:: void CBSSetMinSize(CBS cbs, Size minSize)
-
-:mps:tag:`function.cbs.set.min-size` :c:func:`CBSSetMinSize` is the
-function used to change the minimum size of interest in a CBS. This
-minimum size is used to determine whether to invoke the client
-callbacks from :c:func:`CBSInsert` and :c:func:`CBSDelete`. This
-function will invoke either the ``new`` or ``delete`` callback for all
-blocks that are (in the semi-open interval) between the old and new
-values. ``oldSize`` and ``newSize`` will be the same in these cases.
-
-.. 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:: Addr CBSBlockBase(CBSBlock block)
-
-:mps:tag:`function.cbs.block.base` The :c:func:`CBSBlockBase` function
-returns the base of the range represented by the :c:type:`CBSBlock`.
-This function may not be called from the delete callback when the
-block is being deleted entirely.
-
-.. note::
-
- The value of the base of a particular :c:type:`CBSBlock` is not
- guaranteed to remain constant across calls to :c:func:`CBSDelete`
- and :c:func:`CBSInsert`, regardless of whether a callback is
- invoked.
-
-.. c:function:: Addr CBSBlockLimit(CBSBlock block)
-
-:mps:tag:`function.cbs.block.limit` The :c:func:`CBSBlockLimit`
-function returns the limit of the range represented by the
-:c:type:`CBSBlock`. This function may not be called from the delete
-callback when the block is being deleted entirely.
-
-.. note::
-
- The value of the limit of a particular :c:type:`CBSBlock` is not
- guaranteed to remain constant across calls to :c:func:`CBSDelete`
- and :c:func:`CBSInsert`, regardless of whether a callback is
- invoked.
-
-.. c:function:: Size CBSBlockSize(CBSBlock block)
-
-:mps:tag:`function.cbs.block.size` The :c:func:`CBSBlockSize` function
-returns the size of the range represented by the :c:type:`CBSBlock`.
-This function may not be called from the ``delete`` callback when the
-block is being deleted entirely.
-
-.. note::
-
- The value of the size of a particular :c:type:`CBSBlock` is not
- guaranteed to remain constant across calls to :c:func:`CBSDelete`
- and :c:func:`CBSInsert`, regardless of whether a callback is
- invoked.
-
-.. c:function:: Res CBSBlockDescribe(CBSBlock block, mps_lib_FILE *stream)
-
-:mps:tag:`function.cbs.block.describe` The :c:func:`CBSBlockDescribe`
-function prints a textual representation of the :c:type:`CBSBlock` to
-the given stream. It is provided for debugging purposes only.
-
-.. c:function:: Bool CBSFindFirst(Addr *baseReturn, Addr *limitReturn, CBS cbs, Size size, CBSFindDelete findDelete)
-
-:mps:tag:`function.cbs.find.first` The :c:func:`CBSFindFirst` function
-locates the first block (in address order) within the CBS of at least
-the specified size, and returns its range. If there are no such
-blocks, it returns ``FALSE``. It optionally deletes 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), which must come from
-this enumeration::
-
- enum {
- CBSFindDeleteNONE, /* don't delete after finding */
- CBSFindDeleteLOW, /* delete precise size from low end */
- CBSFindDeleteHIGH, /* delete precise size from high end */
- CBSFindDeleteENTIRE /* delete entire range */
- };
-
-.. c:function:: Bool CBSFindLast(Addr *baseReturn, Addr *limitReturn, CBS cbs, Size size, CBSFindDelete findDelete)
-
-:mps:tag:`function.cbs.find.last` The :c:func:`CBSFindLast` function
-locates the last block (in address order) within the CBS of at least
-the specified size, and returns its range. If there are no such
-blocks, it returns ``FALSE``. Like :c:func:`CBSFindFirst`, it
-optionally deletes the range.
-
-.. c:function:: Bool CBSFindLargest(Addr *baseReturn, Addr *limitReturn, CBS cbs, CBSFindDelete findDelete)
-
-:mps:tag:`function.cbs.find.largest` The :c:func:`CBSFindLargest`
-function locates the largest block within the CBS, and returns its
-range. If there are no blocks, it returns ``FALSE``. Like
-:c:func:`CBSFindFirst`, it optionally deletes the range (specifying
-``CBSFindDeleteLOW`` or ``CBSFindDeleteHIGH`` has the same effect as
-``CBSFindDeleteENTIRE``).
-
-
-Alignment
----------
-
-:mps:tag:`align` When ``mayUseInline`` is specified to permit inline
-data structures and hence avoid losing memory in low memory
-situations, the alignments that the CBS supports are constrained by
-three requirements:
-
-- The smallest possible range (namely one that is the alignment in
- size) must be large enough to contain a single ``void *`` pointer (see
- :mps:ref:`.impl.low-mem.inline.grain`);
-
-- Any larger range (namely one that is at least twice the alignment in
- size) must be large enough to contain two ``void *`` pointers (see
- :mps:ref:`.impl.low-mem.inline.block`);
-
-- It must be valid on all platforms to access a ``void *`` pointer
- stored at the start of an aligned range.
-
-All alignments that meet these requirements are aligned to
-``sizeof(void *)``, so we take that as the minimum alignment.
-
-
-Implementation
---------------
-
-:mps:tag:`impl` Note that this section is concerned with describing
-various aspects of the implementation. It does not form part of the
-interface definition.
-
-
-Size change callback protocol
-.............................
-
-:mps:tag:`impl.callback` The size change callback protocol concerns
-the mechanism for informing the client of the appearance and
-disappearance of interesting ranges. The intention is that each range
-has an identity (represented by the :c:type:`CBSBlock`). When blocks
-are split, the larger fragment retains the identity. When blocks are
-merged, the new block has the identity of the larger fragment.
-
-:mps:tag:`impl.callback.delete` Consider the case when the minimum
-size is ``minSize``, and :c:func:`CBSDelete` is called to remove a
-range of size ``middle``. The two (possibly non-existant) neighbouring
-ranges have (possibly zero) sizes ``left`` and ``right``. ``middle`` is part
-of the :c:type:`CBSBlock` ``middleBlock``.
-
-:mps:tag:`impl.callback.delete.delete` The ``delete`` callback will be
-called in this case if and only if::
-
- left + middle + right >= minSize && left < minSize && right < minSize
-
-That is, the combined range is interesting, but neither remaining
-fragment is. It will be called with the following parameters:
-
-* ``block``: ``middleBlock``
-* ``oldSize``: ``left + middle + right``
-* ``newSize``: ``left >= right ? left : right``
-
-:mps:tag:`impl.callback.delete.new` The ``new`` callback will be
-called in this case if and only if::
-
- left >= minSize && right >= minSize
-
-That is, both remaining fragments are interesting. It will be called
-with the following parameters:
-
-* ``block``: a new block
-* ``oldSize``: ``0``
-* ``newSize``: ``left >= right ? right : left``
-
-:mps:tag:`impl.callback.delete.shrink` The shrink callback will be
-called in this case if and only if::
-
- left + middle + right >= minSize && (left >= minSize || right >= minSize)
-
-That is, at least one of the remaining fragments is still interesting. It will be called with the following parameters:
-
-* ``block``: ``middleBlock``
-* ``oldSize``: ``left + middle + right``
-* ``newSize``: ``left >= right ? left : right``
-
-:mps:tag:`impl.callback.insert` Consider the case when the minimum
-size is ``minSize``, and :c:func:`CBSInsert` is called to add a range
-of size ``middle``. The two (possibly non-existant) neighbouring
-blocks are ``leftBlock`` and ``rightBlock``, and have (possibly zero)
-sizes ``left`` and ``right``.
-
-:mps:tag:`impl.callback.insert.delete` The ``delete`` callback will be
-called in this case if and only if:
-
- left >= minSize && right >= minSize
-
-That is, both neighbours were interesting. It will be called with the
-following parameters:
-
-* ``block``: ``left >= right ? rightBlock : leftBlock``
-* ``oldSize``: ``left >= right ? right : left``
-* ``newSize``: ``0``
-
-:mps:tag:`impl.callback.insert.new` The ``new`` callback will be
-called in this case if and only if:
-
- left + middle + right >= minSize && left < minSize && right < minSize
-
-That is, the combined block is interesting, but neither neighbour was.
-It will be called with the following parameters:
-
-* ``block``: ``left >= right ? leftBlock : rightBlock``
-* ``oldSize``: ``left >= right ? left : right``
-* ``newSize``: ``left + middle + right``
-
-:mps:tag:`impl.callback.insert.grow` The ``grow`` callback will be
-called in this case if and only if::
-
- left + middle + right >= minSize && (left >= minSize || right >= minSize)
-
-That is, at least one of the neighbours was interesting. It will be
-called with the following parameters:
-
-* ``block``: ``left >= right ? leftBlock : rightBlock``
-* ``oldSize``: ``left >= right ? left : right``
-* ``newSize``: ``left + middle + right``
-
-
-Splay tree
-..........
-
-:mps:tag:`impl.splay` The CBS is principally implemented using a splay
-tree (see :mps:ref:`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.
-
-: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 :c:type:`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`. Except when the
-emergency lists (see :mps:ref:`.impl.low-mem`) are in use, they are
-also searched.
-
-
-Low memory behaviour
-....................
-
-:mps:tag:`impl.low-mem` Low memory situations cause problems when the
-CBS tries to allocate a new :c:type:`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 :c:type:`CBSBlock` structure:
-
-:mps:tag:`impl.low-mem.no-inline` If ``mayUseInline`` is ``FALSE``,
-then the range is not added to the CBS, and the call to
-:c:func:`CBSInsert` or :c:func:`CBSDelete` returns ``ResMEMORY``.
-
-:mps:tag:`impl.low-mem.inline` If ``mayUseInline`` is ``TRUE``:
-
-:mps:tag:`impl.low-mem.inline.block` If the range is large enough to
-contain an inline block descriptor consisting of two pointers, then it
-is kept on an emergency block list. The CBS will eagerly attempt to
-add this block back into the splay tree during subsequent calls to
-:c:func:`CBSInsert` and :c:func:`CBSDelete`. The CBS will also keep
-its emergency block list in address order, and will coalesce this list
-eagerly. Some performance degradation will be seen when the emergency
-block list is in use. Ranges on this emergency block list will not be
-made available to the CBS's client via callbacks. :c:func:`CBSIterate`
-and :c:func:`CBSIterateLarge` will not iterate over ranges on this
-list.
-
-:mps:tag:`impl.low-mem.inline.block.structure` The two pointers stored
-are to the next such block (or ``NULL``), and to the limit of the
-block, in that order.
-
-:mps:tag:`impl.low-mem.inline.grain` Otherwise, the range must be
-large enough to contain an inline grain descriptor consisting of one
-pointer, then it is kept on an emergency grain list. The CBS will
-eagerly attempt to add this grain back into either the splay tree or
-the emergency block list during subsequent calls to
-:c:func:`CBSInsert` and :c:func:`CBSDelete`. The CBS will also keep
-its emergency grain list in address order. Some performance
-degradation will be seen when the emergency grain list is in use.
-Ranges on this emergency grain list will not be made available to the
-CBS's client via callbacks. :c:func:`CBSIterate` and
-:c:func:`CBSIterateLarge` will not iterate over ranges on this list.
-
-:mps:tag:`impl.low-mem.inline.grain.structure` The pointer stored is
-to the next such grain, or ``NULL``.
-
-
-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
-:mps:ref:`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:type:`CBS` and a :c:type:`BT`. It makes both
-valid and invalid requests, and compares the :c:type:`CBS` response to
-the correct behaviour as determined by the :c:type:`BT`. It also
-iterates the ranges in the :c:type:`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 :ref:`pool-mvt` and
-:ref:`pool-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.
-
-
-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.] See
-:mps:ref:`.future.hybrid` for a suggestion to solve this problem. An
-alternative solution is to use CBSs only for managing long ranges.
-
-
-Proposed hybrid implementation
-------------------------------
-
-.. note::
-
- The following relates to a pending re-design and does not yet
- relate to any working source version. GavinM 1998-09-25
-
-The CBS system provides its services by combining the services
-provided by three subsidiary CBS modules:
-
-- ``CBSST`` -- Splay Tree: Based on out-of-line splay trees; must
- allocate to insert isolated, which may therefore fail.
-
-- ``CBSBL`` -- Block List: Based on a singly-linked list of variable
- sized ranges with inline descriptors; ranges must be at least large
- enough to store the inline descriptor.
-
-- ``CBSGL`` -- Grain List: Based on a singly-linked list of fixed size
- ranges with inline descriptors; the ranges must be the alignment of
- the CBS.
-
-The three sub-modules have a lot in common. Although their methods are
-not invoked via a dispatcher, they have been given consistent
-interfaces, and consistent internal appearance, to aid maintenance.
-
-Methods supported by sub-modules (not all sub-modules support all
-methods):
-
-- ``MergeRange`` -- Finds any ranges in the specific CBS adjacent to
- the supplied one. If there are any, it extends the ranges, possibly
- deleting one of them. This cannot fail, but should return ``FALSE``
- if there is an intersection between the supplied range and a range
- in the specific CBS.
-
-- ``InsertIsolatedRange`` -- Adds a range to the specific CBS that is
- not adjacent to any range already in there. Depending on the
- specific CBS, this may be able to fail for allocation reasons, in
- which case it should return ``FALSE``. It should :c:func:`AVER` if
- the range is adjacent to or intersects with a range already there.
-
-- ``RemoveAdjacentRanges`` -- Finds and removes from the specific CBS
- any ranges that are adjacent to the supplied range. Should return
- ``FALSE`` if the supplied range intersects with any ranges already
- there.
-
-- ``DeleteRange`` -- Finds and deletes the supplied range from the
- specific CBS. Returns a tri-state result:
-
- - ``Success`` -- The range was successfully deleted. This may have
- involved the creation of a new range, which should be done via
- ``CBSInsertIsolatedRange``.
-
- - ``ProtocolError`` -- Either some non-trivial strict subset of the
- supplied range was in the specific CBS, or a range adjacent to the
- supplied range was in the specific CBS. Either of these indicates
- a protocol error.
-
- - ``NoIntersection`` -- The supplied range was not found in the CBS.
- This may or not be a protocol error, depending on the invocation
- context.
-
-- ``FindFirst`` -- Returns the first (in address order) range in the
- specific CBS that is at least as large as the supplied size, or
- ``FALSE`` if there is no such range.
-
-- ``FindFirstBefore`` -- As ``FindFirst``, but only finds ranges prior
- to the supplied address.
-
-- ``FindLast`` -- As ``FindFirst``, but finds the last such range in
- address order.
-
-- ``FindLastAfter`` -- ``FindLast`` equivalent of ``FindFirstBefore``.
-
-- ``Init`` -- Initialise the control structure embedded in the CBS.
-
-- ``Finish`` -- Finish the control structure embedded in the CBS.
-
-- ``InlineDescriptorSize`` -- Returns the aligned size of the inline descriptor.
-
-- ``Check`` -- Checks the control structure embedded in the CBS.
-
-The CBS supplies the following utilities:
-
-- ``CBSAlignment`` -- Returns the alignment of the CBS.
-
-- ``CBSMayUseInline`` -- Returns whether the CBS may use the memory in
- the ranges stored.
-
-- ``CBSInsertIsolatedRange`` -- Wrapper for ``CBS*InsertIsolatedRange``.
-
-Internally, the ``CBS*`` sub-modules each have an internal structure
-``CBS*Block`` that represents an isolated range within the module. It
-supports the following methods (for sub-module internal use):
-
-- ``BlockBase`` -- Returns the base of the associated range;
-- ``BlockLimit``
-- ``BlockRange``
-- ``BlockSize``
diff --git a/mps/manual/html/_sources/design/check.txt b/mps/manual/html/_sources/design/check.txt
deleted file mode 100644
index 5483e0329e3..00000000000
--- a/mps/manual/html/_sources/design/check.txt
+++ /dev/null
@@ -1,106 +0,0 @@
-.. sources:
-
- ``_
-
-.. mps:prefix:: design.mps.check
-
-Checking
-========
-
-
-Introduction
-------------
-
-This documents the design of structure checking within the MPS.
-
-
-History
--------
-
-:mps:tag:`hist.0` Incomplete design. Gavin Matthews, 1996-08-05.
-
-:mps:tag:`hist.1` Converted from MMInfo database design document.
-Richard Brooksby, 2002-06-07.
-
-:mps:tag:`hist.2` Converted to reStructuredText. Gareth Rees,
-2013-03-12.
-
-
-Implementation
---------------
-
-:mps:tag:`level` There are three levels of checking:
-
-1. :mps:tag:`level.sig` The lowest level checks only that the
- structure has a valid :c:type:`Signature` (see
- :mps:ref:`design.mps.sig`).
-
-2. :mps:tag:`level.shallow` Shallow checking checks all local fields
- (including signature) and also checks the signatures of any parent
- or child structures.
-
-3. :mps:tag:`level.deep` Deep checking checks all local fields
- (including signatures), the signatures of any parent structures,
- and does full recursive checking on any child structures.
-
-:mps:tag:`level.control` Control over the levels of checking is via
-the definition of at most one of the macros
-:c:macro:`TARGET_CHECK_SHALLOW` (which if defined gives
-:mps:ref:`.level.shallow`), :c:macro:`TARGET_CHECK_DEEP` (which if
-defined gives :mps:ref:`.level.deep`). If neither macro is defined
-then :mps:ref:`.level.sig` is used. These macros are not intended to
-be manipulated directly by developers, they should use the interface
-in :mps:ref:`impl.h.target`.
-
-:mps:tag:`order` Because deep checking (:mps:ref:`.level.deep`) uses
-unchecked recursion, it is important that child relationships are
-acyclic (:mps:ref:`.macro.down`).
-
-:mps:tag:`fun` Every abstract data type which is a structure pointer
-should have a function ``Check`` which takes a pointer of type
-```` and returns a :c:type:`Bool`. It should check all fields in
-order, using one of the macros in :mps:ref:`.macro`, or document why
-not.
-
-:mps:tag:`fun.omit` The only fields which should be omitted from a
-check function are those for which there is no meaningful check (for
-example, an unlimited unsigned integer with no relation to other fields).
-
-:mps:tag:`fun.return` Although the function returns a :c:type:`Bool`,
-if the assert handler returns (or there is no assert handler), then
-this is taken to mean "ignore and continue", and the check function
-hence returns ``TRUE``.
-
-:mps:tag:`macro` Checking is implemented by invoking four macros in :mps:ref:`impl.h.assert`:
-
-* :mps:tag:`macro.sig` ``CHECKS(type, val)`` checks the signature
- only, and should be called precisely on ``type`` and the received
- object pointer.
-
-* :mps:tag:`macro.local` ``CHECKL(cond)`` checks a local field
- (depending on level; see :mps:ref:`.level`), and should be called on
- each local field that is not an abstract data type structure pointer
- itself (apart from the signature), with an appropriate normally-true
- test condition.
-
-* :mps:tag:`macro.up` ``CHECKU(type, val)`` checks a parent abstract
- data type structure pointer, performing at most signature checks
- (depending on level; see :mps:ref:`.level`). It should be called
- with the parent type and pointer.
-
-* :mps:tag:`macro.down` ``CHECKD(type, val)`` checks a child abstract
- data type structure pointer, possibly invoking ``Check``
- (depending on level; see :mps:ref:`.level`). It should be called
- with the child type and pointer.
-
-:mps:tag:`full-type` ``CHECKS``, ``CHECKD``, ``CHECKU``, all operate
-only on fully fledged types. This means the type has to provide a
-function ``Bool TypeCheck(Type type)`` where ``Type`` is substituted
-for the name of the type (for example, :c:func:`PoolCheck`), and the
-expression ``obj->sig`` must be a valid value of type :c:type:`Sig`
-whenever ``obj`` is a valid value of type ``Type``.
-
-:mps:tag:`type.no-sig` This tag is to be referenced in implementations
-whenever the form ``CHECKL(ThingCheck(thing))`` is used instead of
-``CHECK{U,D}(Thing, thing)`` because ``Thing`` is not a fully fledged
-type (:mps:ref:`.full-type`).
diff --git a/mps/manual/html/_sources/glossary/c.txt b/mps/manual/html/_sources/glossary/c.txt
index 514b5305d72..58196b561ec 100644
--- a/mps/manual/html/_sources/glossary/c.txt
+++ b/mps/manual/html/_sources/glossary/c.txt
@@ -8,6 +8,39 @@ Memory Management Glossary: C
.. glossary::
+ C89
+
+ .. see:: :term:`C90`.
+
+ C90
+
+ .. aka:: *C89*.
+
+ A revision of the ANSI/ISO Standard for the :term:`C`
+ programming language. Although more than twenty years old, it
+ remains the only form of Standard C that is supported by all
+ the major compilers, including Microsoft Visual C.
+
+ .. mps:specific::
+
+ The public interface conforms to this standard. See
+ :ref:`topic-interface`.
+
+ .. bibref:: :ref:`ISO/IEC 9899:1990 `.
+
+ C99
+
+ A revision of the ANSI/ISO Standard for C the :term:`C`
+ programming language.
+
+ .. mps:specific::
+
+ :term:`Keyword arguments` can be conveniently passed to
+ functions using C99's compound literal syntax. See
+ :ref:`topic-keyword`.
+
+ .. bibref:: :ref:`ISO/IEC 9899:1999 `.
+
cache (1)
.. aka:: *memory cache*, *cache memory*.
diff --git a/mps/manual/html/_sources/glossary/k.txt b/mps/manual/html/_sources/glossary/k.txt
index 87b349d527e..b08edafb470 100644
--- a/mps/manual/html/_sources/glossary/k.txt
+++ b/mps/manual/html/_sources/glossary/k.txt
@@ -12,6 +12,17 @@ Memory Management Glossary: K
.. see:: :term:`kilobyte`.
+ keyword argument
+
+ An optional argument to a function call, identified by an
+ associated keyword.
+
+ .. mps:specific::
+
+ Keyword arguments are passed to functions in the MPS
+ interface as arrays of structures of type
+ :c:type:`mps_arg_s`. See :ref:`topic-keyword`.
+
kilobyte
.. aka:: *kB*.
diff --git a/mps/manual/html/_sources/guide/advanced.txt b/mps/manual/html/_sources/guide/advanced.txt
index f65de503e9e..7ab02a3141d 100644
--- a/mps/manual/html/_sources/guide/advanced.txt
+++ b/mps/manual/html/_sources/guide/advanced.txt
@@ -712,17 +712,21 @@ Finally, we can create the buckets pool and its allocation points::
/* Create an Automatic Weak Linked (AWL) pool to manage the hash table
buckets. */
- res = mps_pool_create(&buckets_pool,
- arena,
- mps_class_awl(),
- buckets_fmt,
- buckets_find_dependent);
+ res = mps_pool_create_k(&buckets_pool, arena, mps_class_awl(),
+ (mps_arg_s[]){{MPS_KEY_FORMAT, .val.format = buckets_fmt},
+ {MPS_KEY_AWL_FIND_DEPENDENT,
+ .val.addr_method = buckets_find_dependent},
+ {MPS_KEY_ARGS_END}});
if (res != MPS_RES_OK) error("Couldn't create buckets pool");
/* Create allocation points for weak and strong buckets. */
- res = mps_ap_create(&strong_buckets_ap, buckets_pool, mps_rank_exact());
+ res = mps_ap_create_k(&strong_buckets_ap, buckets_pool,
+ (mps_arg_s[]){{MPS_KEY_RANK, .val.rank = mps_rank_exact()},
+ {MPS_KEY_ARGS_END}});
if (res != MPS_RES_OK) error("Couldn't create strong buckets allocation point");
- res = mps_ap_create(&weak_buckets_ap, buckets_pool, mps_rank_weak());
+ res = mps_ap_create_k(&weak_buckets_ap, buckets_pool,
+ (mps_arg_s[]){{MPS_KEY_RANK, .val.rank = mps_rank_weak()},
+ {MPS_KEY_ARGS_END}});
if (res != MPS_RES_OK) error("Couldn't create weak buckets allocation point");
By adding the line::
@@ -888,15 +892,14 @@ Second, the leaf objects must be allocated on ``leaf_ap`` instead of
/* Create an Automatic Mostly-Copying Zero-rank (AMCZ) pool to
manage the leaf objects. */
- res = mps_pool_create(&leaf_pool,
- arena,
- mps_class_amcz(),
- obj_fmt,
- obj_chain);
+ res = mps_pool_create_k(&leaf_pool, arena, mps_class_amcz(),
+ (mps_arg_s[]){{MPS_KEY_CHAIN, .val.chain = obj_chain},
+ {MPS_KEY_FORMAT, .val.format = obj_fmt},
+ {MPS_KEY_ARGS_END}});
if (res != MPS_RES_OK) error("Couldn't create leaf pool");
/* Create allocation point for leaf objects. */
- res = mps_ap_create(&leaf_ap, leaf_pool);
+ res = mps_ap_create_k(&leaf_ap, leaf_pool, mps_args_none);
if (res != MPS_RES_OK) error("Couldn't create leaf objects allocation point");
Note that the new pool shared a :term:`generation chain` with the old
diff --git a/mps/manual/html/_sources/guide/lang.txt b/mps/manual/html/_sources/guide/lang.txt
index 3186774685f..edaee742830 100644
--- a/mps/manual/html/_sources/guide/lang.txt
+++ b/mps/manual/html/_sources/guide/lang.txt
@@ -155,24 +155,32 @@ rather than having to pass it around everywhere::
static mps_arena_t arena;
-Create an arena by calling :c:func:`mps_arena_create`. This function
-takes a third argument when creating a virtual memory arena: the size of
-the amount of virtual virtual :term:`address space` (*not* :term:`RAM`),
-in bytes, that the arena will reserve initially. The MPS will ask for
+Create an arena by calling :c:func:`mps_arena_create_k`. This function
+takes a :term:`keyword argument` when creating a virtual memory arena:
+the size of virtual :term:`address space` (*not* :term:`RAM`), in
+bytes, that the arena will reserve initially. The MPS will ask for
more address space if it runs out, but the more times it has to extend
its address space, the less efficient garbage collection will become.
-The MPS works best if you reserve an address space that is several times
-larger than your peak memory usage.
+The MPS works best if you reserve an address space that is several
+times larger than your peak memory usage.
+
+.. note::
+
+ Functions in the MPS interface take :term:`keyword arguments` for
+ arguments that are optional, or are only required in some
+ circumstances. These argument are passed in the form of an array
+ of structures of type :c:type:`mps_arg_s`. See
+ :ref:`topic-keyword` for the full details.
Let's reserve 32 megabytes::
mps_res_t res;
- res = mps_arena_create(&arena,
- mps_arena_class_vm(),
- (size_t)(32 * 1024 * 1024));
+ res = mps_arena_create_k(&arena, mps_arena_class_vm(),
+ (mps_arg_s[]){{MPS_KEY_ARENA_SIZE, .val.size = 32 * 1024 * 1024},
+ {MPS_KEY_ARGS_END}});
if (res != MPS_RES_OK) error("Couldn't create arena");
-:c:func:`mps_arena_create` is typical of functions in the MPS
+:c:func:`mps_arena_create_k` is typical of functions in the MPS
interface in that it stores its result in a location pointed to by an
:term:`out parameter` (here, ``&arena``) and returns a :term:`result
code`, which is :c:macro:`MPS_RES_OK` if the function succeeded, or
@@ -762,11 +770,10 @@ Third, the :term:`generation chain`::
And finally the :term:`pool`::
mps_pool_t obj_pool;
- res = mps_pool_create(&obj_pool,
- arena,
- mps_class_amc(),
- obj_fmt,
- obj_chain);
+ res = mps_pool_create_k(&obj_pool, arena, mps_class_amc(),
+ (mps_arg_s[]){{MPS_KEY_CHAIN, .val.chain = obj_chain},
+ {MPS_KEY_FORMAT, .val.format = obj_fmt},
+ {MPS_KEY_ARGS_END}});
if (res != MPS_RES_OK) error("Couldn't create obj pool");
@@ -1080,13 +1087,13 @@ may abort.
The MPS solves this problem via the fast, nearly lock-free
:ref:`topic-allocation-point-protocol`. This needs an additional
structure, an :term:`allocation point`, to be attached to the pool by
-calling :c:func:`mps_ap_create`::
+calling :c:func:`mps_ap_create_k`::
static mps_ap_t obj_ap;
/* ... */
- res = mps_ap_create(&obj_ap, obj_pool, mps_rank_exact());
+ res = mps_ap_create_k(&obj_ap, obj_pool, mps_args_none);
if (res != MPS_RES_OK) error("Couldn't create obj allocation point");
And then the constructor can be implemented like this::
diff --git a/mps/manual/html/_sources/mmref/bib.txt b/mps/manual/html/_sources/mmref/bib.txt
index 07845a3701b..aba18413d6e 100644
--- a/mps/manual/html/_sources/mmref/bib.txt
+++ b/mps/manual/html/_sources/mmref/bib.txt
@@ -215,6 +215,14 @@ Bibliography
Richard Brooksby. 2002. "`The Memory Pool System: Thirty person-years of memory management development goes Open Source `_". ISMM'02.
+* .. _C1990:
+
+ International Standard ISO/IEC 9899:1990. "Programming languages — C".
+
+* .. _C1999:
+
+ International Standard ISO/IEC 9899:1999. "`Programming languages — C `_".
+
* .. _CGZ94:
Brad Calder, Dirk Grunwald, Benjamin Zorn. 1994. "`Quantifying Behavioral Differences Between C and C++ Programs `_". *Journal of Programming Languages.* 2(4):313--351.
diff --git a/mps/manual/html/_sources/mmref/lang.txt b/mps/manual/html/_sources/mmref/lang.txt
index fb4473d525e..0d081b82a30 100644
--- a/mps/manual/html/_sources/mmref/lang.txt
+++ b/mps/manual/html/_sources/mmref/lang.txt
@@ -82,7 +82,7 @@ Memory management in various languages
.. seealso:: :term:`automatic storage duration`, :term:`static storage duration`.
- .. bibref:: :ref:`Boehm & Weiser (1988) `, :ref:`Daconta (1993) `, :ref:`Zorn (1993) `.
+ .. bibref:: :ref:`ISO/IEC 9899:1990 `, :ref:`ISO/IEC 9899:1999 `, :ref:`Boehm & Weiser (1988) `, :ref:`Daconta (1993) `, :ref:`Zorn (1993) `.
.. link::
diff --git a/mps/manual/html/_sources/pool/amc.txt b/mps/manual/html/_sources/pool/amc.txt
index 99a4e49778e..7c6c9927aec 100644
--- a/mps/manual/html/_sources/pool/amc.txt
+++ b/mps/manual/html/_sources/pool/amc.txt
@@ -100,20 +100,36 @@ AMC interface
Return the :term:`pool class` for an AMC (Automatic
Mostly-Copying) :term:`pool`.
- When creating an AMC pool, :c:func:`mps_pool_create` takes two
- extra arguments::
+ When creating an AMC pool, :c:func:`mps_pool_create_k` requires
+ two :term:`keyword arguments`:
- mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
- mps_class_t mps_class_amc(),
- mps_fmt_t fmt,
- mps_chain_t chain)
+ * :c:macro:`MPS_KEY_FORMAT` (member ``.val.format``; type
+ :c:type:`mps_fmt_t`) specifies the :term:`object format` for the
+ objects allocated in the pool. The format must provide a
+ :term:`scan method`, a :term:`skip method`, a :term:`forward
+ method`, an :term:`is-forwarded method` and a :term:`padding
+ method`.
- ``fmt`` specifies the :term:`object format` for the objects
- allocated in the pool. The format must provide a :term:`scan
- method`, a :term:`skip method`, a :term:`forward method`, an
- :term:`is-forwarded method` and a :term:`padding method`.
+ * :c:macro:`MPS_KEY_CHAIN` (member ``.val.chain``; type
+ :c:type:`mps_chain_t`) specifies the :term:`generation chain`
+ for the pool.
- ``chain`` specifies the :term:`generation chain` for the pool.
+ For example, in :term:`C99`::
+
+ res = mps_pool_create_k(&pool, arena, mps_class_amc(),
+ (mps_arg_s[]){{MPS_KEY_CHAIN, .val.chain = chain},
+ {MPS_KEY_FORMAT, .val.format = fmt},
+ {MPS_KEY_ARGS_END}});
+
+ .. deprecated:: starting with version 1.112.
+
+ When using :c:func:`mps_pool_create`, pass the format and
+ chain like this::
+
+ mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
+ mps_class_t mps_class_amc(),
+ mps_fmt_t fmt,
+ mps_chain_t chain)
.. index::
diff --git a/mps/manual/html/_sources/pool/amcz.txt b/mps/manual/html/_sources/pool/amcz.txt
index 478173001a8..c3a01202532 100644
--- a/mps/manual/html/_sources/pool/amcz.txt
+++ b/mps/manual/html/_sources/pool/amcz.txt
@@ -59,17 +59,32 @@ AMCZ interface
Return the :term:`pool class` for an AMCZ (Automatic
Mostly-Copying Zero-rank) :term:`pool`.
- When creating an AMCZ pool, :c:func:`mps_pool_create` takes two
- extra arguments::
+ When creating an AMCZ pool, :c:func:`mps_pool_create_k` requires
+ two :term:`keyword arguments`:
- mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
- mps_class_t mps_class_amcz(),
- mps_fmt_t fmt,
- mps_chain_t chain)
+ * :c:macro:`MPS_KEY_FORMAT` (member ``.val.format``; type
+ :c:type:`mps_fmt_t`) specifies the :term:`object format` for the
+ objects allocated in the pool. The format must provide a
+ :term:`skip method`, a :term:`forward method`, an
+ :term:`is-forwarded method` and a :term:`padding method`.
- ``fmt`` specifies the :term:`object format` for the objects
- allocated in the pool. The format must provide a :term:`skip
- method`, a :term:`forward method`, an :term:`is-forwarded method`
- and a :term:`padding method`.
+ * :c:macro:`MPS_KEY_CHAIN` (member ``.val.chain``; type
+ :c:type:`mps_chain_t`) specifies the :term:`generation chain`
+ for the pool.
- ``chain`` specifies the :term:`generation chain` for the pool.
+ For example, in :term:`C99`::
+
+ res = mps_pool_create_k(&pool, arena, mps_class_amcz(),
+ (mps_arg_s[]){{MPS_KEY_CHAIN, .val.chain = chain},
+ {MPS_KEY_FORMAT, .val.format = fmt},
+ {MPS_KEY_ARGS_END}});
+
+ .. deprecated:: starting with version 1.112.
+
+ When using :c:func:`mps_pool_create`, pass the format and
+ chain like this::
+
+ mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
+ mps_class_t mps_class_amcz(),
+ mps_fmt_t fmt,
+ mps_chain_t chain)
diff --git a/mps/manual/html/_sources/pool/ams.txt b/mps/manual/html/_sources/pool/ams.txt
index ec0a9799b7b..0e9cac244c6 100644
--- a/mps/manual/html/_sources/pool/ams.txt
+++ b/mps/manual/html/_sources/pool/ams.txt
@@ -103,20 +103,34 @@ AMS interface
Return the :term:`pool class` for an AMS (Automatic Mark & Sweep)
:term:`pool`.
- When creating an AMS pool, :c:func:`mps_pool_create` takes two
- extra arguments::
+ When creating an AMS pool, :c:func:`mps_pool_create_k` requires
+ two :term:`keyword arguments`:
- mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
- mps_class_t mps_class_ams(),
- mps_fmt_t fmt,
- mps_chain_t chain)
+ * :c:macro:`MPS_KEY_FORMAT` (member ``.val.format``; type
+ :c:type:`mps_fmt_t`) specifies the :term:`object format` for the
+ objects allocated in the pool. The format must provide a
+ :term:`scan method` and a :term:`skip method`.
- ``fmt`` specifies the :term:`object format` for the objects
- allocated in the pool. The format must provide a :term:`scan
- method` and a :term:`skip method`.
+ * :c:macro:`MPS_KEY_CHAIN` (member ``.val.chain``; type
+ :c:type:`mps_chain_t`) specifies the :term:`generation chain`
+ for the pool. It must have a single generation.
- ``chain`` specifies the :term:`generation chain` for the pool. It
- must have a single generation.
+ For example, in :term:`C99`::
+
+ res = mps_pool_create_k(&pool, arena, mps_class_ams(),
+ (mps_arg_s[]){{MPS_KEY_CHAIN, .val.chain = chain},
+ {MPS_KEY_FORMAT, .val.format = fmt},
+ {MPS_KEY_ARGS_END}});
+
+ .. deprecated:: starting with version 1.112.
+
+ When using :c:func:`mps_pool_create`, pass the format and
+ chain like this::
+
+ mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
+ mps_class_t mps_class_ams(),
+ mps_fmt_t fmt,
+ mps_chain_t chain)
.. c:function:: mps_class_t mps_class_ams_debug(void)
@@ -124,16 +138,19 @@ AMS interface
A :ref:`debugging ` version of the AMS pool
class.
- When creating a debugging AMS pool, :c:func:`mps_pool_create`
- takes three extra arguments::
+ When creating a debugging AMS pool, :c:func:`mps_pool_create_k`
+ requires three keyword arguments: :c:macro:`MPS_KEY_FORMAT` and
+ :c:macro:`MPS_KEY_CHAIN` are as described above, and
+ :c:macro:`MPS_KEY_POOL_DEBUG_OPTIONS` specifies the debugging
+ options. See :c:type:`mps_debug_option_s`.
- mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
- mps_class_t mps_class_ams_debug(),
- mps_debug_option_s debug_option,
- mps_fmt_t fmt,
- mps_chain_t chain)
+ .. deprecated:: starting with version 1.112.
- ``debug_option`` specifies the debugging options. See
- :c:type:`mps_debug_option_s`.
+ When using :c:func:`mps_pool_create`, pass the format,
+ chain, and debugging options like this::
- ``fmt`` and ``chain`` are the same as for :c:func:`mps_class_ams`.
+ mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
+ mps_class_t mps_class_ams_debug(),
+ mps_debug_option_s debug_option,
+ mps_fmt_t fmt,
+ mps_chain_t chain)
diff --git a/mps/manual/html/_sources/pool/awl.txt b/mps/manual/html/_sources/pool/awl.txt
index 8ed131653da..61bbd202eed 100644
--- a/mps/manual/html/_sources/pool/awl.txt
+++ b/mps/manual/html/_sources/pool/awl.txt
@@ -318,34 +318,59 @@ AWL interface
Return the :term:`pool class` for an AWL (Automatic Weak Linked)
:term:`pool`.
- When creating an AWL pool, :c:func:`mps_pool_create` takes two
- extra arguments::
+ When creating an AWL pool, :c:func:`mps_pool_create_k` requires
+ two :term:`keyword arguments`:
- mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
- mps_class_t mps_class_awl(),
- mps_fmt_t fmt,
- mps_awl_find_dependent_t find_dependent)
+ * :c:macro:`MPS_KEY_FORMAT` (member ``.val.format``; type
+ :c:type:`mps_fmt_t`) specifies the :term:`object format` for the
+ objects allocated in the pool. The format must provide a :term:`scan
+ method` and a :term:`skip method`.
- ``fmt`` specifies the :term:`object format` for the objects
- allocated in the pool. The format must provide a :term:`scan
- method` and a :term:`skip method`.
+ * :c:macro:`MPS_KEY_AWL_FIND_DEPENDENT` (member
+ ``.val.addr_method``; type :c:type:`mps_awl_find_dependent_t`)
+ is a function that specifies how to find the :term:`dependent
+ object` for an object in the pool.
- ``find_dependent`` is a function of type
- :c:type:`mps_awl_find_dependent_t` that specifies how to find the
- :term:`dependent object` for an object in the pool.
+ For example, in :term:`C99`::
- When creating an allocation point on an AWL pool,
- :c:func:`mps_ap_create` takes one extra argument::
+ res = mps_pool_create_k(&pool, arena, mps_class_awl(),
+ (mps_arg_s[]){{MPS_KEY_FORMAT, .val.format = fmt},
+ {MPS_KEY_AWL_FIND_DEPENDENT, .val.addr_method = find_dependent},
+ {MPS_KEY_ARGS_END}});
- mps_res_t mps_ap_create(mps_ap_t *ap_o, mps_pool_t pool,
- mps_rank_t rank)
+ .. deprecated:: starting with version 1.112.
- ``rank`` specifies the :term:`rank` of references in objects
- allocated on this allocation point. It must be
- :c:func:`mps_rank_exact` (if the objects allocated on this
- allocation point will contain :term:`exact references`), or
- :c:func:`mps_rank_weak` (if the objects will contain :term:`weak
- references (1)`).
+ When using :c:func:`mps_pool_create`, pass the format and
+ find-dependent function like this::
+
+ mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
+ mps_class_t mps_class_awl(),
+ mps_fmt_t fmt,
+ mps_awl_find_dependent_t find_dependent)
+
+ When creating an :term:`allocation point` on an AWL pool,
+ :c:func:`mps_ap_create_k` requires one keyword argument:
+
+ * :c:macro:`MPS_KEY_RANK` (member ``.val.rank``; type
+ :c:type:`mps_rank_t`) specifies the :term:`rank` of references
+ in objects allocated on this allocation point. It must be
+ :c:func:`mps_rank_exact` (if the objects allocated on this
+ allocation point will contain :term:`exact references`), or
+ :c:func:`mps_rank_weak` (if the objects will contain :term:`weak
+ references (1)`).
+
+ For example, in :term:`C99`::
+
+ res = mps_ap_create_k(&ap, awl_pool,
+ (mps_arg_s[]){{MPS_KEY_RANK, .val.rank = mps_rank_weak()},
+ {MPS_KEY_ARGS_END}});
+
+ .. deprecated:: starting with version 1.112.
+
+ When using :c:func:`mps_ap_create`, pass the rank like this::
+
+ mps_res_t mps_ap_create(mps_ap_t *ap_o, mps_pool_t pool,
+ mps_rank_t rank)
.. c:type:: mps_addr_t (*mps_awl_find_dependent_t)(mps_addr_t addr)
diff --git a/mps/manual/html/_sources/pool/lo.txt b/mps/manual/html/_sources/pool/lo.txt
index 20e02c82a54..dad1997a4a1 100644
--- a/mps/manual/html/_sources/pool/lo.txt
+++ b/mps/manual/html/_sources/pool/lo.txt
@@ -105,13 +105,25 @@ LO interface
Return the :term:`pool class` for an LO (Leaf Object)
:term:`pool`.
- When creating an LO pool, :c:func:`mps_pool_create` takes one
- extra argument::
+ When creating an LO pool, :c:func:`mps_pool_create_k` require one
+ :term:`keyword argument`:
- mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
- mps_class_t mps_class_lo(),
- mps_fmt_t fmt)
+ * :c:macro:`MPS_KEY_FORMAT` (member ``.val.format``; type
+ :c:type:`mps_fmt_t`) specifies the :term:`object format` for the
+ objects allocated in the pool. The format must provide a :term:`skip
+ method`.
- ``fmt`` specifies the :term:`object format` for the objects
- allocated in the pool. The format must provide a :term:`skip
- method`.
+ For example, in :term:`C99`::
+
+ res = mps_pool_create_k(&pool, arena, mps_class_lo(),
+ (mps_arg_s[]){{MPS_KEY_FORMAT, .val.format = fmt},
+ {MPS_KEY_ARGS_END}});
+
+ .. deprecated:: starting with version 1.112.
+
+ When using :c:func:`mps_pool_create`, pass the format like
+ this::
+
+ mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
+ mps_class_t mps_class_lo(),
+ mps_fmt_t fmt)
diff --git a/mps/manual/html/_sources/pool/mfs.txt b/mps/manual/html/_sources/pool/mfs.txt
index b98928762e4..9c6bf500f7d 100644
--- a/mps/manual/html/_sources/pool/mfs.txt
+++ b/mps/manual/html/_sources/pool/mfs.txt
@@ -77,19 +77,35 @@ MFS interface
Return the :term:`pool class` for an MFS (Manual Fixed Small)
:term:`pool`.
- When creating an MFS pool, :c:func:`mps_pool_create` takes two
- extra arguments::
+ When creating an MFS pool, :c:func:`mps_pool_create_k` requires
+ two :term:`keyword arguments`:
- mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
- mps_class_t mps_class_mfs(),
- mps_size_t extend_size,
- mps_size_t unit_size)
+ * :c:macro:`MPS_KEY_MFS_UNIT_SIZE` (member ``.val.size``; type
+ :c:type:`size_t`) is the :term:`size` of blocks that will be
+ allocated from this pool, in :term:`bytes (1)`. It must be at
+ least one :term:`word`.
- ``extend_size`` is the :term:`size` of segment that the pool will
- request from the :term:`arena`. It must be at least as big as
- ``unit_size``. If this is not a multiple of ``unit_size``, there
- will be wasted space in each segment.
+ * :c:macro:`MPS_KEY_EXTEND_BY` (member ``.val.size``; type
+ :c:type:`size_t`) is the :term:`size` of segment that the pool
+ will request from the :term:`arena`. It must be at least as big
+ as the unit size specified by the
+ :c:macro:`MPS_KEY_MFS_UNIT_SIZE` keyword argument. If this is
+ not a multiple of the unit size, there will be wasted space in
+ each segment.
- ``unit_size`` is the :term:`size` of blocks that will be allocated
- from this pool, in :term:`bytes (1)`. It must be at least one
- :term:`word`.
+ For example, in :term:`C99`::
+
+ res = mps_pool_create_k(&pool, arena, mps_class_mfs(),
+ (mps_arg_s[]){{MPS_KEY_MFS_UNIT_SIZE, .val.size = 1024},
+ {MPS_KEY_EXTEND_BY, .val.size = 1024 * 1024},
+ {MPS_KEY_ARGS_END}});
+
+ .. deprecated:: starting with version 1.112.
+
+ When using :c:func:`mps_pool_create`, pass the segment size and
+ unit size like this::
+
+ mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
+ mps_class_t mps_class_mfs(),
+ mps_size_t extend_size,
+ mps_size_t unit_size)
diff --git a/mps/manual/html/_sources/pool/mv.txt b/mps/manual/html/_sources/pool/mv.txt
index c0a5f90cc39..dccb5abe0ee 100644
--- a/mps/manual/html/_sources/pool/mv.txt
+++ b/mps/manual/html/_sources/pool/mv.txt
@@ -72,22 +72,42 @@ MV interface
Return the :term:`pool class` for an MV (Manual Variable)
:term:`pool`.
- When creating an MV pool, :c:func:`mps_pool_create` takes three
- extra arguments::
+ When creating an MV pool, :c:func:`mps_pool_create_k` requires
+ three :term:`keyword arguments`:
- mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
- mps_class_t mps_class_mv(),
- mps_size_t extend_size,
- mps_size_t average_size,
- mps_size_t maximum_size)
+ * :c:macro:`MPS_KEY_EXTEND_BY` (member ``.val.size``; type
+ :c:type:`size_t`) is the :term:`size` of segment that the pool
+ will request from the :term:`arena`.
- ``extend_size`` is the :term:`size` of segment that the pool will
- request from the :term:`arena`.
+ * :c:macro:`MPS_KEY_MEAN_SIZE` (member ``.val.size``; type
+ :c:type:`size_t`) is the predicted mean size of blocks that
+ will be allocated from the pool.
- ``average_size`` and ``maximum size`` are the predicted average
- and maximum size of blocks that will be allocated from the pool.
- These are hints to the MPS: the pool will be less efficient if
- these are wrong.
+ * :c:macro:`MPS_KEY_MAX_SIZE` (member ``.val.size``; type
+ :c:type:`size_t`) is the predicted maximum size of blocks that
+ will be allocated from the pool.
+
+ The mean and maximum sizes are *hints* to the MPS: the pool will be
+ less efficient if these are wrong, but nothing will break.
+
+ For example, in :term:`C99`::
+
+ res = mps_pool_create_k(&pool, arena, mps_class_mfs(),
+ (mps_arg_s[]){{MPS_KEY_MEAN_SIZE, .val.size = 32},
+ {MPS_KEY_MAX_SIZE, .val.size = 1024},
+ {MPS_KEY_EXTEND_BY, .val.size = 1024 * 1024},
+ {MPS_KEY_ARGS_END}});
+
+ .. deprecated:: starting with version 1.112.
+
+ When using :c:func:`mps_pool_create`, pass the segment size,
+ mean size, and maximum size like this::
+
+ mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
+ mps_class_t mps_class_mv(),
+ mps_size_t extend_size,
+ mps_size_t average_size,
+ mps_size_t maximum_size)
.. c:function:: mps_class_t mps_class_mv_debug(void)
@@ -95,21 +115,23 @@ MV interface
A :ref:`debugging ` version of the MV pool
class.
- When creating a debugging MV pool, :c:func:`mps_pool_create`
- takes four extra arguments::
+ When creating a debugging MV pool, :c:func:`mps_pool_create_k`
+ requires four keyword arguments: :c:macro:`MPS_KEY_EXTEND_SIZE`,
+ :c:macro:`MPS_KEY_MEAN_SIZE`, :c:macro:`MPS_KEY_MAX_SIZE` are as
+ described above, and :c:macro:`MPS_KEY_POOL_DEBUG_OPTIONS`
+ specifies the debugging options. See :c:type:`mps_debug_option_s`.
- mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
- mps_class_t mps_class_mv_debug(),
- mps_debug_option_s debug_option,
- mps_size_t extend_size,
- mps_size_t average_size,
- mps_size_t maximum_size)
+ .. deprecated:: starting with version 1.112.
- ``debug_option`` specifies the debugging options. See
- :c:type:`mps_debug_option_s`.
+ When using :c:func:`mps_pool_create`, pass the debugging
+ options, segment size, mean size, and maximum size like this::
- ``extend_size``, ``average_size`` and ``maximum_size`` are as
- documented in :c:func:`mps_class_mv`.
+ mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
+ mps_class_t mps_class_mv_debug(),
+ mps_debug_option_s debug_option,
+ mps_size_t extend_size,
+ mps_size_t average_size,
+ mps_size_t maximum_size)
.. index::
diff --git a/mps/manual/html/_sources/pool/mvff.txt b/mps/manual/html/_sources/pool/mvff.txt
index 135525b3351..df91ab9007c 100644
--- a/mps/manual/html/_sources/pool/mvff.txt
+++ b/mps/manual/html/_sources/pool/mvff.txt
@@ -112,37 +112,62 @@ MVFF interface
Return the :term:`pool class` for an MVFF (Manual Variable First
Fit) :term:`pool`.
- When creating an MVFF pool, :c:func:`mps_pool_create` takes six
- extra arguments::
+ When creating an MVFF pool, :c:func:`mps_pool_create_k` requires
+ six :term:`keyword arguments`:
- mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
- mps_class_t mps_class_mvff(),
- mps_size_t extend_size,
- mps_size_t average_size,
- mps_align_t alignment,
- mps_bool_t slot_high,
- mps_bool_t arena_high,
- mps_bool_t first_fit)
+ * :c:macro:`MPS_KEY_EXTEND_BY` (member ``.val.size``; type
+ :c:type:`size_t`) is the :term:`size` of segment that the pool
+ will request from the :term:`arena`.
- ``extend_size`` is the :term:`size` of segment that the pool will
- request from the :term:`arena`.
+ * :c:macro:`MPS_KEY_MEAN_SIZE` (member ``.val.size``; type
+ :c:type:`size_t`) is the predicted mean size of blocks that will
+ be allocated from the pool. This is a *hint* to the MPS: the
+ pool will be less efficient if this is wrong, but nothing will
+ break.
- ``average_size`` is the predicted average size of blocks that will
- be allocated from the pool.
+ * :c:macro:`MPS_KEY_ALIGN` (member ``.val.align``; type
+ :c:type:`mps_align_t`) 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 *)``.
- ``alignment`` is the :term:`alignment` of addresses for allocation
- (and freeing) in the pool. If an unaligned size is passed to
- :c:func:`mps_alloc` or :c:func:`mps_free`, it will be rounded up
- to the pool's alignment. The minimum alignment supported by pools
- of this class is ``sizeof(void *)``.
+ * :c:macro:`MPS_KEY_MVFF_ARENA_HIGH` (member ``.val.b``; type
+ :c:type:`mps_bool_t`) indicates whether new segments for
+ buffered allocation are acquired at high addresses (if true), or
+ at low addresses (if false).
- ``slot_high`` is undocumented. It must have the same value as
- ``arena_high``.
+ * :c:macro:`MPS_KEY_MVFF_SLOT_HIGH` (member ``.val.b``; type
+ :c:type:`mps_bool_t`) is undocumented. It must have the same
+ value as :c:macro:`MPS_KEY_MVFF_ARENA_HIGH`.
- If ``arena_high`` is true, new segments for buffered allocation
- are acquired at high addresses; if false, at low addresses.
+ * :c:macro:`MPS_KEY_MVFF_FIRST_FIT` (member ``.val.b``; type
+ :c:type:`mps_bool_t`) is undocumented and must be set to true.
- ``first_fit`` is undocumented and must be set to true.
+ For example, in :term:`C99`::
+
+ res = mps_pool_create_k(&pool, arena, mps_class_mvff(),
+ (mps_arg_s[]){{MPS_KEY_EXTEND_BY, .val.size = },
+ {MPS_KEY_MEAN_SIZE, .val.size = },
+ {MPS_KEY_ALIGN, .val.align = },
+ {MPS_KEY_MVFF_ARENA_HIGH, .val.b = 0},
+ {MPS_KEY_MVFF_SLOT_HIGH, .val.b = 0},
+ {MPS_KEY_MVFF_FIRST_FIT, .val.b = 1},
+ {MPS_KEY_ARGS_END}});
+
+ .. deprecated:: starting with version 1.112.
+
+ When using :c:func:`mps_pool_create`, pass the arguments like
+ this::
+
+ mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
+ mps_class_t mps_class_mvff(),
+ mps_size_t extend_size,
+ mps_size_t average_size,
+ mps_align_t alignment,
+ mps_bool_t slot_high,
+ mps_bool_t arena_high,
+ mps_bool_t first_fit)
.. c:function:: mps_class_t mps_class_mvff_debug(void)
@@ -150,23 +175,30 @@ MVFF interface
A :ref:`debugging ` version of the MVFF pool
class.
- When creating a debugging MVFF pool, :c:func:`mps_pool_create`
- takes seven extra arguments::
+ When creating a debugging MVFF pool, :c:func:`mps_pool_create_k`
+ requires seven :term:`keyword arguments`.
- mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
- mps_class_t mps_class_mvff_debug(),
- mps_debug_option_s debug_option,
- mps_size_t extend_size,
- mps_size_t average_size,
- mps_align_t alignment,
- mps_bool_t slot_high,
- mps_bool_t arena_high,
- mps_bool_t first_fit)
+ * :c:macro:`MPS_KEY_EXTEND_BY`, :c:macro:`MPS_KEY_MEAN_SIZE`,
+ :c:macro:`MPS_KEY_ALIGN`, :c:macro:`MPS_KEY_MVFF_ARENA_HIGH`,
+ :c:macro:`MPS_KEY_MVFF_SLOT_HIGH`, and
+ :c:macro:`MPS_KEY_MVFF_FIRST_FIT` are as described above, and
+ :c:macro:`MPS_KEY_POOL_DEBUG_OPTIONS` specifies the debugging
+ :c:options. See :c:type:`mps_debug_option_s`.
- ``debug_option`` specifies the debugging options. See
- :c:type:`mps_debug_option_s`.
+ .. deprecated:: starting with version 1.112.
- The other arguments are the same as for :c:func:`mps_class_mvff`.
+ When using :c:func:`mps_pool_create`, pass the debugging
+ options, and other arguments like this::
+
+ mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
+ mps_class_t mps_class_mvff_debug(),
+ mps_debug_option_s debug_option,
+ mps_size_t extend_size,
+ mps_size_t average_size,
+ mps_align_t alignment,
+ mps_bool_t slot_high,
+ mps_bool_t arena_high,
+ mps_bool_t first_fit)
.. index::
diff --git a/mps/manual/html/_sources/pool/mvt.txt b/mps/manual/html/_sources/pool/mvt.txt
index 6fd51db85d9..b670c96998e 100644
--- a/mps/manual/html/_sources/pool/mvt.txt
+++ b/mps/manual/html/_sources/pool/mvt.txt
@@ -112,70 +112,95 @@ MVT interface
Return the :term:`pool class` for an MVT (Manual Variable
Temporal) :term:`pool`.
- When creating an MVT pool, :c:func:`mps_pool_create` takes five
- extra arguments::
+ When creating an MVT pool, :c:func:`mps_pool_create_k` requires
+ five :term:`keyword arguments`:
- mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
- mps_class_t mps_class_mvt(),
- size_t minimum_size,
- size_t mean_size,
- size_t maximum_size,
- mps_count_t reserve_depth,
- mps_count_t fragmentation_limit)
+ * :c:macro:`MPS_KEY_MIN_SIZE` (member ``.val.size``; type
+ :c:type:`size_t`) is the predicted minimum size of blocks that
+ will be allocated from the pool.
- ``minimum_size``, ``mean_size``, and ``maximum_size`` are the
- predicted minimum, mean, and maximum :term:`size` of
- :term:`blocks` expected to be allocated in the pool. Blocks
- smaller than ``minimum_size`` and larger than ``maximum_size`` may
- be allocated, but the pool is not guaranteed to manage them
- space-efficiently. Furthermore, partial freeing is not supported
- for blocks larger than ``maximum_size``; doing so will result in
- the storage of the block never being reused. ``mean_size`` need
- not be an accurate mean, although the pool will manage
- ``mean_size`` blocks more efficiently if it is.
+ * :c:macro:`MPS_KEY_MEAN_SIZE` (member ``.val.size``; type
+ :c:type:`size_t`) is the predicted mean size of blocks that will
+ be allocated from the pool.
- ``reserve_depth`` is the expected hysteresis of the population of
- the pool. When blocks are freed, the pool will retain sufficient
- storage to allocate ``reserve_depth`` blocks of ``mean_size`` for
- near term allocations (rather than immediately making that storage
- available to other pools).
+ * :c:macro:`MPS_KEY_MAX_SIZE` (member ``.val.size``; type
+ :c:type:`size_t`) is the predicted maximum size of blocks that
+ will be allocated from the pool. Partial freeing is not
+ supported for blocks larger than this; doing so will
+ result in the storage of the block never being reused.
- If a pool has a stable population, or one which only grows over
- the lifetime of the pool, or one which grows steadily and then
- shrinks steadily, use a reserve depth of 0.
+ 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.
- It is always safe to use a reserve depth of 0, but if the
- population typically fluctuates in a range (for example, the
- client program repeatedly creates and destroys a subset of blocks
- in a loop), it is more efficient for the pool to retain enough
- storage to satisfy that fluctuation. For example, if a pool has an
- object population that typically fluctuates between 8,000 and
- 10,000, use a reserve depth of 2,000.
+ * :c:macro:`MPS_KEY_MVT_RESERVE_DEPTH` (member ``.val.count``;
+ type :c:type:`mps_count_t`) is the expected hysteresis of the
+ population of the pool. When blocks are freed, the pool will
+ retain sufficient storage to allocate this many blocks of the mean
+ size for near term allocations (rather than immediately making
+ that storage available to other pools).
- The reserve will not normally be available to other pools for
- allocation, even when it is not used by the pool. If this is
- undesirable, a reserve depth of 0 may be used for a pool whose
- object population does vary, at a slight cost in efficiency. The
- reserve does not guarantee any particular amount of allocation.
+ If a pool has a stable population, or one which only grows over
+ the lifetime of the pool, or one which grows steadily and then
+ shrinks steadily, use a reserve depth of 0.
- ``fragmentation_limit`` is a percentage from 1 to 100 (inclusive).
- It sets an upper limit on the space overhead of MVT, in case block
- death times and allocations do not correlate well. If the free
- space managed by the pool as a ratio of all the space managed by
- the pool exceeds ``fragmentation_limit``, the pool falls back to a
- first fit allocation policy, exploiting space more efficiently at
- a cost in time efficiency. A fragmentation limit of 0 would cause
- the pool to operate as a first-fit pool, at a significant cost in
- time efficiency: therefore this is not permitted.
+ It is always safe to use a reserve depth of 0, but if the
+ population typically fluctuates in a range (for example, the
+ client program repeatedly creates and destroys a subset of
+ blocks in a loop), it is more efficient for the pool to retain
+ enough storage to satisfy that fluctuation. For example, if a
+ pool has an object population that typically fluctuates between
+ 8,000 and 10,000, use a reserve depth of 2,000.
- A fragmentation limit of 100 causes the pool to always use
- temporal fit (unless resources are exhausted). If the objects
- allocated in the pool have similar lifetime expectancies, this
- mode will have the best time- and space-efficiency. If the objects
- have widely varying lifetime expectancies, this mode will be
- time-efficient, but may be space-inefficient. An intermediate
- setting can be used to limit the space-inefficiency of temporal
- fit due to varying object life expectancies.
+ The reserve will not normally be available to other pools for
+ allocation, even when it is not used by the pool. If this is
+ undesirable, a reserve depth of 0 may be used for a pool whose
+ object population does vary, at a slight cost in efficiency. The
+ reserve does not guarantee any particular amount of allocation.
+
+ * :c:macro:`MPS_KEY_MVT_FRAG_LIMIT` (member ``.val.count``; type
+ :c:type:`mps_count_t`) is a percentage from 1 to 100
+ (inclusive). It sets an upper limit on the space overhead of an
+ MVT pool, in case block death times and allocations do not
+ correlate well. If the free space managed by the pool as a ratio
+ of all the space managed by the pool exceeds the fragmentation
+ limit, the pool falls back to a first fit allocation policy,
+ exploiting space more efficiently at a cost in time efficiency.
+ A fragmentation limit of 0 would cause the pool to operate as a
+ first-fit pool, at a significant cost in time efficiency:
+ therefore this is not permitted.
+
+ A fragmentation limit of 100 causes the pool to always use
+ temporal fit (unless resources are exhausted). If the objects
+ allocated in the pool have similar lifetime expectancies, this
+ mode will have the best time- and space-efficiency. If the
+ objects have widely varying lifetime expectancies, this mode
+ will be time-efficient, but may be space-inefficient. An
+ intermediate setting can be used to limit the space-inefficiency
+ of temporal fit due to varying object life expectancies.
+
+ For example, in :term:`C99`::
+
+ res = mps_pool_create_k(&pool, arena, mps_class_mvt(),
+ (mps_arg_s[]){{MPS_KEY_MIN_SIZE, .val.size = 4},
+ {MPS_KEY_MEAN_SIZE, .val.size = 32},
+ {MPS_KEY_MAX_SIZE, .val.size = 1024},
+ {MPS_KEY_MVT_RESERVE_DEPTH, .val.count = 256},
+ {MPS_KEY_MVT_FRAG_LIMIT, .val.count = 50},
+ {MPS_KEY_ARGS_END}});
+
+ .. deprecated:: starting with version 1.112.
+
+ When using :c:func:`mps_pool_create`, pass the arguments like
+ this::
+
+ mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
+ mps_class_t mps_class_mvt(),
+ size_t minimum_size,
+ size_t mean_size,
+ size_t maximum_size,
+ mps_count_t reserve_depth,
+ mps_count_t fragmentation_limit)
.. index::
diff --git a/mps/manual/html/_sources/pool/snc.txt b/mps/manual/html/_sources/pool/snc.txt
index e9b5003e91a..04fd8d548ee 100644
--- a/mps/manual/html/_sources/pool/snc.txt
+++ b/mps/manual/html/_sources/pool/snc.txt
@@ -95,23 +95,47 @@ SNC introspection
Return the :term:`pool class` for an SNC (Stack No Check)
:term:`pool`.
- When creating an SNC pool, :c:func:`mps_pool_create` takes one
- extra argument::
+ When creating an SNC pool, :c:func:`mps_pool_create_k` requires one
+ :term:`keyword argument`:
- mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
- mps_class_t mps_class_snc(),
- mps_fmt_t fmt)
+ * :c:macro:`MPS_KEY_FORMAT` (member ``.val.format``; type
+ :c:type:`mps_fmt_t`) specifies the :term:`object format` for the
+ objects allocated in the pool. The format must provide a
+ :term:`scan method`, a :term:`skip method`, and a :term:`padding
+ method`.
- ``fmt`` specifies the :term:`object format` for the objects
- allocated in the pool. The format must provide a :term:`scan
- method`, a :term:`skip method`, and a :term:`padding method`.
+ For example, in :term:`C99`::
- When creating an allocation point on an SNC pool,
- :c:func:`mps_ap_create` takes one extra argument::
+ res = mps_pool_create_k(&pool, arena, mps_class_snc(),
+ (mps_arg_s[]){{MPS_KEY_FORMAT, .val.format = fmt},
+ {MPS_KEY_ARGS_END}});
- mps_res_t mps_ap_create(mps_ap_t *ap_o, mps_pool_t pool,
- mps_rank_t rank)
+ .. deprecated:: starting with version 1.112.
- ``rank`` specifies the :term:`rank` of references in objects
- allocated on this allocation point. It must be
- :c:func:`mps_rank_exact`.
+ When using :c:func:`mps_pool_create`, pass the format like
+ this::
+
+ mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
+ mps_class_t mps_class_snc(),
+ mps_fmt_t fmt)
+
+ When creating an :term:`allocation point` on an SNC pool,
+ :c:func:`mps_ap_create_k` requires one keyword argument:
+
+ * :c:macro:`MPS_KEY_RANK` (member ``.val.rank``; type
+ :c:type:`mps_rank_t`) specifies the :term:`rank` of references
+ in objects allocated on this allocation point. It must be
+ :c:func:`mps_rank_exact`.
+
+ For example, in :term:`C99`::
+
+ res = mps_ap_create_k(&ap, awl_pool,
+ (mps_arg_s[]){{MPS_KEY_RANK, .val.rank = mps_rank_exact()},
+ {MPS_KEY_ARGS_END}});
+
+ .. deprecated:: starting with version 1.112.
+
+ When using :c:func:`mps_ap_create`, pass the rank like this::
+
+ mps_res_t mps_ap_create(mps_ap_t *ap_o, mps_pool_t pool,
+ mps_rank_t rank)
diff --git a/mps/manual/html/_sources/topic/allocation.txt b/mps/manual/html/_sources/topic/allocation.txt
index 1d808828ccd..512935c3765 100644
--- a/mps/manual/html/_sources/topic/allocation.txt
+++ b/mps/manual/html/_sources/topic/allocation.txt
@@ -96,7 +96,7 @@ many small objects. They must be used according to the
:c:type:`mps_ap_s`.
-.. c:function:: mps_res_t mps_ap_create(mps_ap_t *ap_o, mps_pool_t pool, ...)
+.. c:function:: mps_res_t mps_ap_create_k(mps_ap_t *ap_o, mps_pool_t pool, mps_arg_s args[])
Create an :term:`allocation point` in a :term:`pool`.
@@ -105,12 +105,14 @@ many small objects. They must be used according to the
``pool`` is the pool.
+ ``args`` are :term:`keyword arguments` specific to the pool class
+ to which ``pool`` belong. See the documentation for that pool
+ class. (Most pool classes don't take any keyword arguments; in
+ those cases you can pass :c:macro:`mps_args_none`.)
+
Returns :c:macro:`MPS_RES_OK` if successful, or another
:term:`result code` if not.
- Some pool classes require additional arguments to be passed to
- :c:func:`mps_ap_create`. See the documentation for the pool class.
-
.. warning::
An allocation point must not be used by more than one
@@ -124,9 +126,28 @@ many small objects. They must be used according to the
``va_list`` mechanism.
+.. c:function:: mps_res_t mps_ap_create(mps_ap_t *ap_o, mps_pool_t pool, ...)
+
+ .. deprecated:: starting with version 1.112.
+
+ Use :c:func:`mps_ap_create_k` instead: the :term:`keyword
+ arguments` interface is more reliable and produces better
+ error messages.
+
+ An alternative to :c:func:`mps_ap_create_k` that takes its extra
+ arguments using the standard :term:`C` variable argument list
+ mechanism.
+
+
.. c:function:: mps_res_t mps_ap_create_v(mps_ap_t *ap_o, mps_pool_t pool, va_list args)
- An alternative to :c:func:`mps_ap_create` that takes its extra
+ .. deprecated:: starting with version 1.112.
+
+ Use :c:func:`mps_ap_create_k` instead: the :term:`keyword
+ arguments` interface is more reliable and produces better
+ error messages.
+
+ An alternative to :c:func:`mps_ap_create_k` that takes its extra
arguments using the standard :term:`C` ``va_list`` mechanism.
@@ -642,7 +663,7 @@ branch prediction should work well since the test almost never fails).
synchronization in a multi-threaded environment.
Create an allocation point for a pool by calling
- :c:func:`mps_ap_create`, and allocate memory via one by calling
+ :c:func:`mps_ap_create_k`, and allocate memory via one by calling
:c:func:`mps_reserve` and :c:func:`mps_commit`.
diff --git a/mps/manual/html/_sources/topic/arena.txt b/mps/manual/html/_sources/topic/arena.txt
index ee34751c65a..264ae0409b1 100644
--- a/mps/manual/html/_sources/topic/arena.txt
+++ b/mps/manual/html/_sources/topic/arena.txt
@@ -14,7 +14,7 @@ Arenas
An arena is an object that encapsulates the state of the Memory Pool
System, and tells it where to get the memory it manages. You typically
start a session with the MPS by creating an arena with
-:c:func:`mps_arena_create` and end the session by destroying it with
+:c:func:`mps_arena_create_k` and end the session by destroying it with
:c:func:`mps_arena_destroy`. The only function you might need to call
before making an arena is :c:func:`mps_telemetry_control`.
@@ -76,28 +76,14 @@ the way that they acquire the memory to be managed.
.. c:function:: mps_res_t mps_arena_create_k(mps_arena_t *arena_o, mps_arena_class_t arena_class, mps_arg_s args[])
Create an :term:`arena`.
-
- ``arena_o`` points to a location that will hold a pointer to the new
- arena.
-
- ``arena_class`` is the :term:`arena class`.
-
- ``args`` are :ref:`topic-interface-keywords` specific to the arena
- class. See the documentation for the arena class.
-
-
-.. c:function:: mps_res_t mps_arena_create(mps_arena_t *arena_o, mps_arena_class_t arena_class, ...)
-
- Create an :term:`arena`.
``arena_o`` points to a location that will hold a pointer to the new
arena.
``arena_class`` is the :term:`arena class`.
- Some arena classes require additional arguments to be passed to
- :c:func:`mps_arena_create`. See the documentation for the arena
- class.
+ ``args`` are :term:`keyword arguments` specific to the arena
+ class. See the documentation for the arena class.
Returns :c:macro:`MPS_RES_OK` if the arena is created
successfully, or another :term:`result code` otherwise.
@@ -105,17 +91,31 @@ the way that they acquire the memory to be managed.
The arena persists until it is destroyed by calling
:c:func:`mps_arena_destroy`.
- .. note::
- There's an alternative function :c:func:`mps_arena_create_v`
- that takes its extra arguments using the standard :term:`C`
- ``va_list`` mechanism.
+.. c:function:: mps_res_t mps_arena_create(mps_arena_t *arena_o, mps_arena_class_t arena_class, ...)
+
+ .. deprecated:: starting with version 1.112.
+
+ Use :c:func:`mps_arena_create_k` instead: the :term:`keyword
+ arguments` interface is more reliable and produces better
+ error messages.
+
+ An alternative to :c:func:`mps_arena_create_k` that takes its
+ extra arguments using the standard :term:`C` variable argument
+ list mechanism.
.. c:function:: mps_res_t mps_arena_create_v(mps_arena_t *arena_o, mps_arena_class_t arena_class, va_list args)
- An alternative to :c:func:`mps_arena_create` that takes its extra
- arguments using the standard :term:`C` ``va_list`` mechanism.
+ .. deprecated:: starting with version 1.112.
+
+ Use :c:func:`mps_arena_create_k` instead: the :term:`keyword
+ arguments` interface is more reliable and produces better
+ error messages.
+
+ An alternative to :c:func:`mps_arena_create_k` that takes its
+ extra arguments using the standard :term:`C` ``va_list``
+ mechanism.
.. c:function:: void mps_arena_destroy(mps_arena_t arena)
@@ -156,30 +156,24 @@ Client arenas
program`. This memory chunk is passed when the arena is created.
When creating a client arena, :c:func:`mps_arena_create_k` requires two
- :ref:`topic-interface-keywords`:
-
- * ``MPS_KEY_ARENA_CL_BASE`` (type ``mps_addr_t``) is the
- :term:`address` of the chunk of memory that will be managed by the
- arena.
+ :term:`keyword arguments`:
+
+ * :c:macro:`MPS_KEY_ARENA_CL_ADDR` (member ``.val.addr``; type
+ :c:type:`mps_addr_t`) is the :term:`address` of the chunk of memory
+ that will be managed by the arena.
+
+ * :c:macro:`MPS_KEY_ARENA_SIZE` (member ``.val.size``; type
+ :c:type:`size_t`) is its size.
+
+ For example (in :term:`C99`)::
- * ``MPS_KEY_ARENA_SIZE`` (type ``size_t``) is its size.
-
- For example (in C99)::
-
res = mps_arena_create_k(&arena, mps_arena_class_cl(),
- (mps_arg_s[]){{MPS_KEY_ARENA_CL_BASE, .val.addr = base},
+ (mps_arg_s[]){{MPS_KEY_ARENA_CL_ADDR, .val.addr = base},
{MPS_KEY_ARENA_SIZE, .val.size = size},
{MPS_KEY_ARGS_END}});
- When creating a client arena, :c:func:`mps_arena_create` takes the
- these arguments like this::
-
- mps_res_t mps_arena_create(mps_arena_t *arena_o,
- mps_arena_class_t mps_arena_class_cl,
- size_t size, mps_addr_t base)
-
If the chunk is too small to hold the internal arena structures,
- :c:func:`mps_arena_create` returns :c:macro:`MPS_RES_MEMORY`. In
+ :c:func:`mps_arena_create_k` returns :c:macro:`MPS_RES_MEMORY`. In
this case, you need to use a (much) larger chunk.
.. note::
@@ -189,6 +183,15 @@ Client arenas
Client arenas have no mechanism for returning unused memory.
+ .. deprecated:: starting with version 1.112.
+
+ When using :c:func:`mps_arena_create`, pass the size and base
+ address like this::
+
+ mps_res_t mps_arena_create(mps_arena_t *arena_o,
+ mps_arena_class_t mps_arena_class_cl,
+ size_t size, mps_addr_t base)
+
.. c:function:: mps_res_t mps_arena_extend(mps_arena_t arena, mps_addr_t base, size_t size)
@@ -229,13 +232,13 @@ Virtual memory arenas
more efficient.
When creating a virtual memory arena, :c:func:`mps_arena_create_k`
- requires one
- :ref:`topic-interface-keywords`:
-
- * ``MPS_KEY_ARENA_SIZE`` (type ``size_t``)
-
- For example (in C99)::
-
+ requires one :term:`keyword argument`:
+
+ * :c:macro:`MPS_KEY_ARENA_SIZE` (member ``.val.size``; type
+ :c:type:`size_t`).
+
+ For example (in :term:`C99`)::
+
res = mps_arena_create_k(&arena, mps_arena_class_cl(),
(mps_arg_s[]){{MPS_KEY_ARENA_SIZE, .val.size = size},
{MPS_KEY_ARGS_END}});
@@ -256,38 +259,41 @@ Virtual memory arenas
more times it has to extend its address space, the less
efficient garbage collection will become.
- An optional :ref:`topic-interface-keywords` may be passed, but is
+ An optional :term:`keyword argument` may be passed, but is
only used on the Windows operating system:
-
- * ``MPS_KEY_VM_W3_TOP_DOWN`` (type ``mps_bool_t``)
-
+
+ * :c:macro:`MPS_KEY_VMW3_TOP_DOWN` (member ``.val.b``; type
+ :c:type:`mps_bool_t`).
+
If true, the arena will allocate address space starting at the
highest possible address and working downwards through memory.
-
+
.. note::
-
+
This causes the arena to pass the ``MEM_TOP_DOWN`` flag to
`VirtualAlloc`_.
.. _VirtualAlloc: http://msdn.microsoft.com/en-us/library/windows/desktop/aa366887%28v=vs.85%29.aspx
- When creating a virtual memory arena, :c:func:`mps_arena_create`
- takes one extra argument::
-
- mps_res_t mps_arena_create(mps_arena_t *arena_o,
- mps_arena_class_t arena_class_vm(),
- size_t size)
-
If the MPS fails to reserve adequate address space to place the
- arena in, :c:func:`mps_arena_create` returns
+ arena in, :c:func:`mps_arena_create_k` returns
:c:macro:`MPS_RES_RESOURCE`. Possibly this means that other parts
of the program are reserving too much virtual memory.
If the MPS fails to allocate memory for the internal arena
- structures, :c:func:`mps_arena_create` returns
+ structures, :c:func:`mps_arena_create_k` returns
:c:macro:`MPS_RES_MEMORY`. Either ``size`` was far too small or
the operating system refused to provide enough memory.
+ .. deprecated:: starting with version 1.112.
+
+ When using :c:func:`mps_arena_create`, pass the size like
+ this::
+
+ mps_res_t mps_arena_create(mps_arena_t *arena_o,
+ mps_arena_class_t arena_class_vm(),
+ size_t size)
+
.. index::
single: arena; properties
@@ -410,16 +416,17 @@ Arena properties
For a :term:`client arena`, this is the sum of the usable portions
of the chunks of memory passed to the arena by the :term:`client
- program` via :c:func:`mps_arena_create` and
+ program` via :c:func:`mps_arena_create_k` and
:c:func:`mps_arena_extend`.
.. note::
For a client arena, the reserved address may be lower than the
- sum of the ``size`` arguments passed to
- :c:func:`mps_arena_create` and :c:func:`mps_arena_extend`,
- because the arena may be unable to use the whole of each chunk
- for reasons of alignment.
+ sum of the :c:macro:`MPS_KEY_ARENA_SIZE` keyword argument
+ passed to :c:func:`mps_arena_create_k` and the ``size``
+ arguments passed to :c:func:`mps_arena_extend`, because the
+ arena may be unable to use the whole of each chunk for reasons
+ of alignment.
.. c:function:: size_t mps_arena_spare_commit_limit(mps_arena_t arena)
@@ -545,7 +552,7 @@ can only be called in this state.
.. c:function:: void mps_arena_clamp(mps_arena_t arena)
Put an :term:`arena` into the :term:`clamped state`.
-
+
``arena`` is the arena to clamp.
In the clamped state, no object motion will occur and the
@@ -752,7 +759,7 @@ Arena introspection
Introspection functions covered in other chapters are:
* :c:func:`mps_addr_fmt`: determine the :term:`object format` to
- which an address belongs;
+ which an address belongs;
* :c:func:`mps_arena_formatted_objects_walk`: visit all
:term:`formatted objects` in an arena;
* :c:func:`mps_arena_roots_walk`: visit all references in
@@ -763,7 +770,7 @@ Arena introspection
.. c:function:: mps_bool_t mps_arena_has_addr(mps_arena_t arena, mps_addr_t addr)
- Test whether an :term:`address` is managed by an :term:`arena`.
+ Test whether an :term:`address` is managed by an :term:`arena`.
``arena`` is an arena.
diff --git a/mps/manual/html/_sources/topic/debugging.txt b/mps/manual/html/_sources/topic/debugging.txt
index 2c4b68bd71d..32524d7869e 100644
--- a/mps/manual/html/_sources/topic/debugging.txt
+++ b/mps/manual/html/_sources/topic/debugging.txt
@@ -71,15 +71,20 @@ For example::
};
mps_pool_t pool;
mps_res_t res;
- res = mps_pool_create(&pool, arena, mps_class_ams_debug(),
- &debug_options, &fmt, &chain)
+ res = mps_pool_create_k(&pool, arena, mps_class_ams_debug(),
+ (mps_arg_s[]){{MPS_KEY_POOL_DEBUG_OPTIONS, .val.pool_debug_options = &debug_options},
+ {MPS_KEY_FORMAT, .val.format = &fmt},
+ {MPS_KEY_CHAIN, .val.chain = &chain},
+ {MPS_KEY_ARGS_END}});
if (res != MPS_RES_OK) error("can't create debug pool");
.. c:type:: mps_pool_debug_option_s
- The type of the structure used to pass options to
- :c:func:`mps_pool_create` for debugging :term:`pool classes`. ::
+ The type of the structure passed as the
+ :c:macro:`MPS_KEY_POOL_DEBUG_OPTIONS` keyword argument to
+ :c:func:`mps_pool_create_k` when creating a debugging :term:`pool
+ class`. ::
typedef struct mps_pool_debug_option_s {
void *fence_template;
diff --git a/mps/manual/html/_sources/topic/error.txt b/mps/manual/html/_sources/topic/error.txt
index c0178a38d8d..296ddb9fa30 100644
--- a/mps/manual/html/_sources/topic/error.txt
+++ b/mps/manual/html/_sources/topic/error.txt
@@ -227,7 +227,7 @@ this documentation.
``format.c: SigCheck Format: format``
- The client program called :c:func:`mps_pool_create` for a
+ The client program called :c:func:`mps_pool_create_k` for a
:term:`pool class` like :ref:`pool-amc` that requires a
:term:`object format`, but passed something other than a
:c:type:`mps_fmt_t` for this argument.
diff --git a/mps/manual/html/_sources/topic/format.txt b/mps/manual/html/_sources/topic/format.txt
index ea1e7faabb2..f3b4fd330bd 100644
--- a/mps/manual/html/_sources/topic/format.txt
+++ b/mps/manual/html/_sources/topic/format.txt
@@ -92,7 +92,9 @@ For example::
if (res != MPS_RES_OK) error("Couldn't create obj format");
/* obj_fmt created successfully */
- res = mps_pool_create(&obj_pool, arena, pool_class, obj_fmt);
+ res = mps_pool_create_k(&obj_pool, arena, pool_class,
+ (mps_arg_s[]){{MPS_KEY_FORMAT, .val.format = obj_fmt},
+ {MPS_KEY_ARGS_END}});
if (res != MPS_RES_OK) error("Couldn't create obj pool");
diff --git a/mps/manual/html/_sources/topic/index.txt b/mps/manual/html/_sources/topic/index.txt
index baf376f3fc4..b4e6300201e 100644
--- a/mps/manual/html/_sources/topic/index.txt
+++ b/mps/manual/html/_sources/topic/index.txt
@@ -7,6 +7,7 @@ Reference
:numbered:
interface
+ keyword
error
arena
pool
diff --git a/mps/manual/html/_sources/topic/interface.txt b/mps/manual/html/_sources/topic/interface.txt
index a37382a6eb3..e0bca91d1fb 100644
--- a/mps/manual/html/_sources/topic/interface.txt
+++ b/mps/manual/html/_sources/topic/interface.txt
@@ -54,8 +54,8 @@ Support policy
Language
--------
-1. The MPS public interface conforms to ANSI/ISO Standard C (IEC
- 9899:1990).
+1. The MPS public interface conforms to :ref:`ANSI/ISO Standard C (IEC
+ 9899:1990) `.
.. index::
@@ -171,6 +171,10 @@ Functions
7. In/out parameters have names ending with ``_io``.
+8. A function that takes optional arguments does so in the form of an
+ array of keyword argument structures. These functions have names
+ ending with ``_k``. See :ref:`topic-keyword`.
+
.. index::
single: interface; type punning
@@ -258,45 +262,6 @@ Macros
separately.
-.. _topic-interface-keywords:
-
-Keyword arguments
------------------
-
-Some functions take :term:`keyword arguments` in order to pass values
-that might be optional, or are only required in some circumstances. For
-example, :ref:`client arenas ` require a base address. These
-arguments are passed in a keyword argument array, like this::
-
- mps_res_t res;
- mps_arena_t arena;
- mps_arg_s args[3];
- args[0].key = MPS_KEY_ARENA_SIZE;
- args[0].val.size = 6553600;
- args[1].key = MPS_KEY_ARENA_CL_BASE;
- args[1].val.addr = base_address;
- args[2].key = MPS_KEY_ARGS_END;
- res = mps_arena_create_k(&arena, mps_arena_class_cl(), args);
-
-If you are writing C99, you can write this more concisely as::
-
- mps_res_t res;
- mps_arena_t arena;
- res = mps_arena_create_k(&arena, mps_arena_class_cl(),
- (mps_arg_s[]){{MPS_KEY_ARENA_SIZE, .val.size = 6553600},
- {MPS_KEY_ARENA_CL_BASE, .val.addr = base_address},
- {MPS_KEY_ARGS_END}});
-
-The argument array must not be ``NULL``, and must end with
-``MPS_KEY_ARGS_END``.
-
-On return, the keyword argument array will be *modified* to remove any
-arguments that have been used. If all arguments have been used the
-first element key will be MPS_KEY_ARGS_END.
-
-If you don't want to pass any arguments, you can either call the equivalent function that does not take
-
-
.. _topic-interface-general:
General types
diff --git a/mps/manual/html/_sources/topic/keyword.txt b/mps/manual/html/_sources/topic/keyword.txt
new file mode 100644
index 00000000000..1acf73e34bf
--- /dev/null
+++ b/mps/manual/html/_sources/topic/keyword.txt
@@ -0,0 +1,190 @@
+.. index::
+ pair: arguments; keyword
+
+.. _topic-keyword:
+
+Keyword arguments
+-----------------
+
+Some functions in the MPS interface take :term:`keyword arguments` in
+order to pass values that might be optional, or are only required in
+some circumstances. For example, the function
+:c:func:`mps_arena_create_k` creates any class of :term:`arena`, but
+:term:`client arenas` require you to specify a base address. These
+arguments are passed in a keyword argument array, like this::
+
+ mps_res_t res;
+ mps_arena_t arena;
+ mps_arg_s args[3];
+ args[0].key = MPS_KEY_ARENA_SIZE;
+ args[0].val.size = 6553600;
+ args[1].key = MPS_KEY_ARENA_CL_ADDR;
+ args[1].val.addr = base_address;
+ args[2].key = MPS_KEY_ARGS_END;
+ res = mps_arena_create_k(&arena, mps_arena_class_cl(), args);
+
+Each keyword argument in the array is a structure of type
+:c:type:`mps_arg_s`.
+
+For convenience and robustness, the MPS interface includes macros to
+help with forming keyword argument lists::
+
+ MPS_ARGS_BEGIN(args) {
+ MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, size, 6553600);
+ MPS_ARGS_ADD(args, MPS_KEY_ARENA_CL_ADDR, addr, base_address);
+ MPS_ARGS_DONE(args);
+ res = mps_arena_create_k(&arena, mps_arena_class_cl(), args);
+ } MPS_ARGS_END(args);
+
+But if you are writing :term:`C99`, you can write this more concisely as::
+
+ mps_res_t res;
+ mps_arena_t arena;
+ res = mps_arena_create_k(&arena, mps_arena_class_cl(),
+ (mps_arg_s[]){{MPS_KEY_ARENA_SIZE, .val.size = 6553600},
+ {MPS_KEY_ARENA_CL_ADDR, .val.addr = base_address},
+ {MPS_KEY_ARGS_END}});
+
+The argument array must not be ``NULL``, and must end with
+:c:macro:`MPS_KEY_ARGS_END`. If you don't want to pass any arguments, you can
+either call the equivalent function that does not take keyword arguments
+(named without the ``_k``) or pass :c:macro:`mps_args_none`.
+
+When a function that takes keyword arguments returns, the keyword
+argument array has been *modified* to remove any arguments that have
+been used. If all arguments have been used, the first element key is
+now :c:macro:`MPS_KEY_ARGS_END`.
+
+
+.. c:type:: mps_arg_s
+
+ The type of the structure used to represent a single
+ :term:`keyword argument` to a function. ::
+
+ typedef struct mps_arg_s {
+ mps_key_t key;
+ union {
+ mps_bool_t b;
+ char c;
+ const char *string;
+ int i;
+ unsigned u;
+ long l;
+ unsigned long ul;
+ size_t size;
+ mps_addr_t addr;
+ mps_fmt_t format;
+ mps_chain_t chain;
+ struct mps_pool_debug_option_s *pool_debug_options;
+ mps_addr_t (*addr_method)(mps_addr_t);
+ mps_align_t align;
+ mps_word_t count;
+ void *p;
+ mps_rank_t rank;
+ } val;
+ } mps_arg_s;
+
+ ``key`` identifies the key. It must be one of the legal values
+ of :c:type:`mps_key_t` listed in the documentation for that type.
+
+ ``val`` is the corresponding value. The documentation for each
+ value of the type :c:type:`mps_key_t` explains which structure
+ member is used by that keyword.
+
+
+.. c:macro:: mps_args_none
+
+ An array of :c:type:`mps_arg_s` representing the empty list of
+ keyword arguments. Equivalent to::
+
+ mps_arg_s mps_args_none[] = {{MPS_KEY_ARGS_END}};
+
+
+.. c:type:: mps_key_t
+
+ The type of :term:`keyword argument` keys. Must take one of the
+ following values:
+
+ ======================================== ====================== ==========================================================
+ Keyword Value slot See
+ ======================================== ====================== ==========================================================
+ :c:macro:`MPS_KEY_ARGS_END` *none* *see above*
+ :c:macro:`MPS_KEY_ALIGN` ``align`` :c:func:`mps_class_mvff`
+ :c:macro:`MPS_KEY_AMS_SUPPORT_AMBIGUOUS` ``b`` :c:func:`mps_class_ams`
+ :c:macro:`MPS_KEY_ARENA_CL_ADDR` ``addr`` :c:func:`mps_arena_class_cl`
+ :c:macro:`MPS_KEY_ARENA_SIZE` ``size`` :c:func:`mps_arena_class_vm`, :c:func:`mps_arena_class_cl`
+ :c:macro:`MPS_KEY_AWL_FIND_DEPENDENT` ``addr_method`` :c:func:`mps_class_awl`
+ :c:macro:`MPS_KEY_CHAIN` ``chain`` :c:func:`mps_class_amc`, :c:func:`mps_class_amcz`, :c:func:`mps_class_ams`
+ :c:macro:`MPS_KEY_EXTEND_BY` ``size`` :c:func:`mps_class_mfs`, :c:func:`mps_class_mv`, :c:func:`mps_class_mvff`
+ :c:macro:`MPS_KEY_FORMAT` ``format`` :c:func:`mps_class_amc`, :c:func:`mps_class_amcz`, :c:func:`mps_class_ams`, :c:func:`mps_class_awl`, :c:func:`mps_class_lo` , :c:func:`mps_class_snc`
+ :c:macro:`MPS_KEY_MAX_SIZE` ``size`` :c:func:`mps_class_mv`
+ :c:macro:`MPS_KEY_MEAN_SIZE` ``size`` :c:func:`mps_class_mv`, :c:func:`mps_class_mvt`, :c:func:`mps_class_mvff`
+ :c:macro:`MPS_KEY_MFS_UNIT_SIZE` ``size`` :c:func:`mps_class_mfs`
+ :c:macro:`MPS_KEY_MIN_SIZE` ``size`` :c:func:`mps_class_mvt`
+ :c:macro:`MPS_KEY_MVFF_ARENA_HIGH` ``b`` :c:func:`mps_class_mvff`
+ :c:macro:`MPS_KEY_MVFF_FIRST_FIT` ``b`` :c:func:`mps_class_mvff`
+ :c:macro:`MPS_KEY_MVFF_SLOT_HIGH` ``b`` :c:func:`mps_class_mvff`
+ :c:macro:`MPS_KEY_MVT_FRAG_LIMIT` ``count`` :c:func:`mps_class_mvt`
+ :c:macro:`MPS_KEY_MVT_RESERVE_DEPTH` ``count`` :c:func:`mps_class_mvt`
+ :c:macro:`MPS_KEY_POOL_DEBUG_OPTIONS` ``pool_debug_options`` :c:func:`mps_class_ams_debug`, :c:func:`mps_class_mv_debug`, :c:func:`mps_class_mvff_debug`
+ :c:macro:`MPS_KEY_RANK` ``rank`` :c:func:`mps_class_awl`, :c:func:`mps_class_snc`
+ :c:macro:`MPS_KEY_VMW3_TOP_DOWN` ``b`` :c:func:`mps_arena_class_vm`
+ ======================================== ====================== ==========================================================
+
+
+.. c:function:: MPS_ARGS_BEGIN(args)
+
+ Start construction of a list of keyword arguments. This macro must
+ be used like this::
+
+ MPS_ARGS_BEGIN(args) {
+ MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, size, 6553600);
+ MPS_ARGS_ADD(args, MPS_KEY_ARENA_CL_ADDR, addr, base_address);
+ MPS_ARGS_DONE(args);
+ res = mps_arena_create_k(&arena, mps_arena_class_cl(), args);
+ } MPS_ARGS_END(args);
+
+ That is, you must call :c:func:`MPS_ARGS_ADD` zero or more times,
+ and then call :c:func:`MPS_ARGS_DONE` before passing the arguments
+ to a function.
+
+ ``args`` is the name of the array that contains the keyword
+ arguments. The array is stack-allocated, and exists between
+ :c:macro:`MPS_ARGS_BEGIN` and :c:macro:`MPS_ARGS_END`.
+
+ It is safe to nest blocks created by :c:macro:`MPS_ARGS_BEGIN` and
+ :c:macro:`MPS_ARGS_END`.
+
+
+.. c:function:: MPS_ARGS_ADD(mps_arg_s args[], mps_key_t key, value)
+
+ Add an argument to a list of keyword arguments. This macro must be
+ used only between :c:macro:`MPS_ARGS_BEGIN` and
+ :c:macro:`MPS_ARGS_END`.
+
+ ``args`` is the name of array that contains the keyword arguments.
+ It must match the argument to the preceding call to
+ :c:func:`MPS_ARGS_BEGIN`.
+
+
+.. c:function:: MPS_ARGS_DONE(args)
+
+ Finalize a list of keyword arguments. This macro must be used only
+ between :c:macro:`MPS_ARGS_BEGIN` and :c:macro:`MPS_ARGS_END`.
+
+ ``args`` is the name of array that contains the keyword arguments.
+ It must match the argument to the preceding call to
+ :c:func:`MPS_ARGS_BEGIN`.
+
+ After calling this macro, the array ``args`` is ready to pass to a
+ function.
+
+
+.. c:function:: MPS_ARGS_END(args)
+
+ Finish using a list of keyword arguments whose construction was
+ started by :c:func:`MPS_ARGS_BEGIN`.
+
+ ``args`` is the name of array that contains the keyword arguments.
+ It must match the argument to the preceding call to
+ :c:func:`MPS_ARGS_BEGIN`.
diff --git a/mps/manual/html/_sources/topic/pool.txt b/mps/manual/html/_sources/topic/pool.txt
index 41d68b0d6bf..ad748310a22 100644
--- a/mps/manual/html/_sources/topic/pool.txt
+++ b/mps/manual/html/_sources/topic/pool.txt
@@ -19,7 +19,7 @@ making it available for allocation.
:c:func:`mps_alloc` or via an :term:`allocation point`.
-.. c:function:: mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena, mps_class_t class, ...)
+.. c:function:: mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena, mps_class_t class, mps_arg_s args[])
Create a :term:`pool` in an :term:`arena`.
@@ -30,9 +30,8 @@ making it available for allocation.
``class`` is the :term:`pool class` of the new pool.
- Some pool classes require additional arguments to be passed to
- :c:func:`mps_pool_create`. See the documentation for the pool
- class.
+ ``args`` are :term:`keyword arguments` specific to the pool class.
+ See the documentation for the pool class.
Returns :c:macro:`MPS_RES_OK` if the pool is created successfully,
or another :term:`result code` otherwise.
@@ -40,16 +39,29 @@ making it available for allocation.
The pool persists until it is destroyed by calling
:c:func:`mps_pool_destroy`.
- .. note::
- There's an alternative function :c:func:`pool_create_v` that
- takes its extra arguments using the standard :term:`C`
- ``va_list`` mechanism.
+.. c:function:: mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena, mps_class_t class, ...)
+
+ .. deprecated:: starting with version 1.112.
+
+ Use :c:func:`mps_pool_create_k` instead: the :term:`keyword
+ arguments` interface is more reliable and produces better
+ error messages.
+
+ An alternative to :c:func:`mps_pool_create_k` that takes its
+ extra arguments using the standard :term:`C` variable argument
+ list mechanism.
.. c:function:: mps_res_t mps_pool_create_v(mps_pool_t *pool_o, mps_arena_t arena, mps_class_t class, va_list args)
- An alternative to :c:func:`mps_pool_create` that takes its extra
+ .. deprecated:: starting with version 1.112.
+
+ Use :c:func:`mps_pool_create_k` instead: the :term:`keyword
+ arguments` interface is more reliable and produces better
+ error messages.
+
+ An alternative to :c:func:`mps_pool_create_k` that takes its extra
arguments using the standard :term:`C` ``va_list`` mechanism.
diff --git a/mps/manual/html/_static/pygments.css b/mps/manual/html/_static/pygments.css
index d79caa151c2..1a14f2ae1ab 100644
--- a/mps/manual/html/_static/pygments.css
+++ b/mps/manual/html/_static/pygments.css
@@ -13,11 +13,11 @@
.highlight .gr { color: #FF0000 } /* Generic.Error */
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.highlight .gi { color: #00A000 } /* Generic.Inserted */
-.highlight .go { color: #333333 } /* Generic.Output */
+.highlight .go { color: #303030 } /* Generic.Output */
.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
-.highlight .gt { color: #0044DD } /* Generic.Traceback */
+.highlight .gt { color: #0040D0 } /* Generic.Traceback */
.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
diff --git a/mps/manual/html/design/arena.html b/mps/manual/html/design/arena.html
index a417e0492e4..61dee7ca97a 100644
--- a/mps/manual/html/design/arena.html
+++ b/mps/manual/html/design/arena.html
@@ -286,7 +286,7 @@ 1.6.3. Tracts.tract.if.tractofaddr: The function TractOfAddr()
finds the tract corresponding to an address in memory. (See
.req.fun.trans):
-Bool TractOfAddr(Tract *tractReturn, Arena arena, Addr addr);
+Bool TractOfAddr(Tract *tractReturn, Arena arena, Addr addr);
If addr is an address which has been allocated to some pool, then
diff --git a/mps/manual/html/design/bt.html b/mps/manual/html/design/bt.html
index ff5dd9c4d3f..eaab3a6b356 100644
--- a/mps/manual/html/design/bt.html
+++ b/mps/manual/html/design/bt.html
@@ -426,7 +426,7 @@
2.9. Interface.if.find.general: There are four functions (below) to find
reset ranges. All the functions have the same prototype (for
symmetry):
-Bool find(Index *baseReturn, Index *limitReturn,
+Bool find(Index *baseReturn, Index *limitReturn,
BT bt,
Index searchBase, Index searchLimit,
Count length);
diff --git a/mps/manual/html/design/config.html b/mps/manual/html/design/config.html
index 9572bf4ac71..07719552c5d 100644
--- a/mps/manual/html/design/config.html
+++ b/mps/manual/html/design/config.html
@@ -416,19 +416,19 @@ 7.8.3. Configuring module implementations
This example is allowed:
#ifdef PROTECTION
-void ProtSync(Space space);
-/* more decls. */
+void ProtSync(Space space);
+/* more decls. */
#else /* PROTECTION not */
#define ProtSync(space) NOOP
-/* more decls. */
+/* more decls. */
#endif /* PROTECTION */
diff --git a/mps/manual/html/genindex.html b/mps/manual/html/genindex.html
index ef065ed48de..945205996ca 100644
--- a/mps/manual/html/genindex.html
+++ b/mps/manual/html/genindex.html
@@ -537,6 +537,17 @@
A
+
+ arguments
+
+
+
+
+ - keyword
+
+
+
+
ASLR
@@ -896,6 +907,18 @@
C
+
C89
+
+
+
+
C90
+
+
+
+
C99
+
+
+
cache (1)
@@ -1075,6 +1098,8 @@
C
COBOL
+
+
-
code
@@ -1086,8 +1111,6 @@
C
- |
-
- collect
@@ -2233,9 +2256,24 @@ K
- kB
+
+ -
+ keyword
+
+
+
+
+ - arguments
+
+
+
|
+ - keyword argument
+
+
+
- kilobyte
@@ -2785,6 +2823,10 @@ M
+ - mps_ap_create_k (C function)
+
+
+
- mps_ap_create_v (C function)
@@ -2861,6 +2903,10 @@ M
+ - mps_arena_create_k (C function)
+
+
+
- mps_arena_create_v (C function)
@@ -2937,6 +2983,30 @@ M
+ - mps_arg_s (C type)
+
+
+
+ - MPS_ARGS_ADD (C function)
+
+
+
+ - MPS_ARGS_BEGIN (C function)
+
+
+
+ - MPS_ARGS_DONE (C function)
+
+
+
+ - MPS_ARGS_END (C function)
+
+
+
+ - mps_args_none (C macro)
+
+
+
- mps_awl_find_dependent_t (C type)
@@ -3128,6 +3198,8 @@ M
- mps_fmt_isfwd_t (C type)
+ |
+
- mps_fmt_pad_t (C type)
@@ -3144,8 +3216,6 @@ M
- mps_fmt_skip_t (C type)
- |
-
- mps_fmt_t (C type)
@@ -3187,6 +3257,10 @@ M
+ - mps_key_t (C type)
+
+
+
- mps_label_t (C type)
@@ -3427,7 +3501,7 @@ M
- - mps_pool_create (C function)
+
- mps_pool_create (C function), [1]
diff --git a/mps/manual/html/glossary/c.html b/mps/manual/html/glossary/c.html
index a264da7974a..74e2d1dbb3b 100644
--- a/mps/manual/html/glossary/c.html
+++ b/mps/manual/html/glossary/c.html
@@ -83,6 +83,45 @@ Navigation
| Y
| Z
+- C89
+-
+
+- C90
+-
+
A revision of the ANSI/ISO Standard for the C
+programming language. Although more than twenty years old, it
+remains the only form of Standard C that is supported by all
+the major compilers, including Microsoft Visual C.
+
+
+
+- C99
+A revision of the ANSI/ISO Standard for C the C
+programming language.
+
+
+
- cache(1)
Also known as
diff --git a/mps/manual/html/glossary/k.html b/mps/manual/html/glossary/k.html
index be1517f5450..ba862822c07 100644
--- a/mps/manual/html/glossary/k.html
+++ b/mps/manual/html/glossary/k.html
@@ -89,6 +89,16 @@ Navigation
kilobyte.
+- keyword argument
+An optional argument to a function call, identified by an
+associated keyword.
+
+ In the MPS
+ Keyword arguments are passed to functions in the MPS
+interface as arrays of structures of type
+mps_arg_s. See Keyword arguments.
+
+
- kilobyte
Also known as
diff --git a/mps/manual/html/guide/advanced.html b/mps/manual/html/guide/advanced.html
index bf29a49f776..62fc10c65b7 100644
--- a/mps/manual/html/guide/advanced.html
+++ b/mps/manual/html/guide/advanced.html
@@ -61,8 +61,8 @@ Navigation
In Scheme, an open file is represented by a port. In the toy Scheme
interpreter, a port is a wrapper around a standard C file handle:
typedef struct port_s {
- type_t type; /* TYPE_PORT */
- obj_t name; /* name of stream */
+ type_t type; /* TYPE_PORT */
+ obj_t name; /* name of stream */
FILE *stream;
} port_s;
@@ -84,14 +84,14 @@ Navigation
Any block in an automatically managed pool can be registered for finalization by calling
mps_finalize(). In the toy Scheme interpreter, this can be done
in make_port:
- static obj_t make_port(obj_t name, FILE *stream)
+ static obj_t make_port(obj_t name, FILE *stream)
{
- mps_addr_t port_ref;
- obj_t obj;
- mps_addr_t addr;
+ mps_addr_t port_ref;
+ obj_t obj;
+ mps_addr_t addr;
size_t size = ALIGN(sizeof(port_s));
do {
- mps_res_t res = mps_reserve(&addr, obj_ap, size);
+ mps_res_t res = mps_reserve(&addr, obj_ap, size);
if (res != MPS_RES_OK) error("out of memory in make_port");
obj = addr;
obj->port.type = TYPE_PORT;
@@ -127,17 +127,17 @@ Navigation
message queue is at the start of the read–eval–print loop. When a
finalization message is found, the associated file handle is closed
(unless it has been closed already), and the message is discarded.
- mps_message_type_t type;
+ mps_message_type_t type;
while (mps_message_queue_type(&type, arena)) {
- mps_message_t message;
- mps_bool_t b;
+ mps_message_t message;
+ mps_bool_t b;
b = mps_message_get(&message, arena, type);
assert(b); /* we just checked there was one */
if (type == mps_message_type_finalization()) {
- mps_addr_t port_ref;
- obj_t port;
+ mps_addr_t port_ref;
+ obj_t port;
mps_message_finalization_ref(&port_ref, arena, message);
port = port_ref;
assert(TYPE(port) == TYPE_PORT);
@@ -176,11 +176,11 @@ Navigation
optimization: setting stream to NULL ensures that the file
handle wouldn’t be closed more than once, even if the port object were
later finalized.
-static void port_close(obj_t port)
+static void port_close(obj_t port)
{
assert(TYPE(port) == TYPE_PORT);
if(port->port.stream != NULL) {
- mps_addr_t port_ref = port;
+ mps_addr_t port_ref = port;
fclose(port->port.stream);
port->port.stream = NULL;
mps_definalize(arena, &port_ref);
@@ -253,24 +253,24 @@ Navigation
case of a hash table, it is most convenient to inline it in the hash
table’s metadata:
typedef struct table_s {
- type_t type; /* TYPE_TABLE */
- hash_t hash; /* hash function */
- cmp_t cmp; /* comparison function */
+ type_t type; /* TYPE_TABLE */
+ hash_t hash; /* hash function */
+ cmp_t cmp; /* comparison function */
mps_ld_s ld; /* location dependency */
- obj_t buckets; /* hash buckets */
+ obj_t buckets; /* hash buckets */
} table_s;
Before being used, the location dependency must be reset to indicate
that nothing is depended upon, by calling mps_ld_reset().
For example:
-static obj_t make_table(size_t length, hash_t hashf, cmp_t cmpf)
+static obj_t make_table(size_t length, hash_t hashf, cmp_t cmpf)
{
- obj_t obj;
- mps_addr_t addr;
+ obj_t obj;
+ mps_addr_t addr;
size_t l, size = ALIGN(sizeof(table_s));
do {
- mps_res_t res = mps_reserve(&addr, obj_ap, size);
+ mps_res_t res = mps_reserve(&addr, obj_ap, size);
if (res != MPS_RES_OK) error("out of memory in make_table");
obj = addr;
obj->table.type = TYPE_TABLE;
@@ -296,12 +296,12 @@ Navigation
dependency.)
In the toy Scheme interpreter, this is done just before the computation
of the hash of the address.
-static unsigned long eq_hash(obj_t obj, mps_ld_t ld)
+static unsigned long eq_hash(obj_t obj, mps_ld_t ld)
{
- union {char s[sizeof(obj_t)]; obj_t addr;} u;
+ union {char s[sizeof(obj_t)]; obj_t addr;} u;
if (ld) mps_ld_add(ld, arena, obj);
u.addr = obj;
- return hash(u.s, sizeof(obj_t));
+ return hash(u.s, sizeof(obj_t));
}
@@ -309,7 +309,7 @@ Navigation
avoids adding unnecessary dependencies on a location. For example, an
eqv? hash table does not need to depend on the location of numbers
and characters:
-static unsigned long eqv_hash(obj_t obj, mps_ld_t ld)
+static unsigned long eqv_hash(obj_t obj, mps_ld_t ld)
{
switch(TYPE(obj)) {
case TYPE_INTEGER:
@@ -339,7 +339,7 @@ Navigation
function mps_ld_isstale() tells you if any of the blocks whose
locations you depended upon since the last call to
mps_ld_reset() might have moved.
-static obj_t table_ref(obj_t tbl, obj_t key)
+static obj_t table_ref(obj_t tbl, obj_t key)
{
struct bucket_s *b = buckets_find(tbl, tbl->table.buckets, key, NULL);
if (b && b->key != NULL && b->key != obj_deleted)
@@ -425,7 +425,7 @@ Navigation
Don’t forget to check the location dependency for staleness if you are
about to delete a key from a hash table but discover that it’s not
there. In the toy Scheme interpreter, deletion looks like this:
-static void table_delete(obj_t tbl, obj_t key)
+static void table_delete(obj_t tbl, obj_t key)
{
struct bucket_s *b;
assert(TYPE(tbl) == TYPE_TABLE);
@@ -500,9 +500,9 @@ Navigation
and values to have different ranks.
These vectors will be allocated from an AWL pool with two allocation
points, one for strong references, and one for weak references:
-static mps_pool_t buckets_pool; /* pool for hash table buckets */
-static mps_ap_t strong_buckets_ap; /* allocation point for strong buckets */
-static mps_ap_t weak_buckets_ap; /* allocation point for weak buckets */
+static mps_pool_t buckets_pool; /* pool for hash table buckets */
+static mps_ap_t strong_buckets_ap; /* allocation point for strong buckets */
+static mps_ap_t weak_buckets_ap; /* allocation point for weak buckets */
@@ -515,16 +515,16 @@ Navigation
replacing it with a null pointer when it is fixed by the object
format’s scan method. So the scan method for the buckets is
going to have the following structure. (See below for the actual code.)
- static mps_res_t buckets_scan(mps_ss_t ss, mps_addr_t base, mps_addr_t limit)
+static mps_res_t buckets_scan(mps_ss_t ss, mps_addr_t base, mps_addr_t limit)
{
MPS_SCAN_BEGIN(ss) {
while (base < limit) {
- buckets_t buckets = base;
+ buckets_t buckets = base;
size_t length = buckets->length;
for (i = 0; i < length; ++i) {
- mps_addr_t p = buckets->bucket[i];
+ mps_addr_t p = buckets->bucket[i];
if (MPS_FIX1(ss, p)) {
- mps_res_t res = MPS_FIX2(ss, &p);
+ mps_res_t res = MPS_FIX2(ss, &p);
if (res != MPS_RES_OK) return res;
if (p == NULL) {
/* TODO: key/value was splatted: splat value/key too */
@@ -556,9 +556,9 @@ Navigation
The AWL pool determines an object’s dependent object by calling a
function that you supply when creating the pool. This means that each
object needs to have a reference to its dependent object:
-static mps_addr_t buckets_find_dependent(mps_addr_t addr)
+static mps_addr_t buckets_find_dependent(mps_addr_t addr)
{
- buckets_t buckets = addr;
+ buckets_t buckets = addr;
return buckets->dependent;
}
@@ -580,25 +580,25 @@ Navigation
size_t length; /* number of buckets (tagged) */
size_t used; /* number of buckets in use (tagged) */
size_t deleted; /* number of deleted buckets (tagged) */
- obj_t bucket[1]; /* hash buckets */
- } buckets_s, *buckets_t;
+ obj_t bucket[1]; /* hash buckets */
+ } buckets_s, *buckets_t;
Now the full details of the scan method can be given, with the revised
code highlighted:
- static mps_res_t buckets_scan(mps_ss_t ss, mps_addr_t base, mps_addr_t limit)
+static mps_res_t buckets_scan(mps_ss_t ss, mps_addr_t base, mps_addr_t limit)
{
MPS_SCAN_BEGIN(ss) {
while (base < limit) {
- buckets_t buckets = base;
+ buckets_t buckets = base;
size_t i, length = UNTAG_SIZE(buckets->length);
FIX(buckets->dependent);
if(buckets->dependent != NULL)
assert(buckets->dependent->length == buckets->length);
for (i = 0; i < length; ++i) {
- mps_addr_t p = buckets->bucket[i];
+ mps_addr_t p = buckets->bucket[i];
if (MPS_FIX1(ss, p)) {
- mps_res_t res = MPS_FIX2(ss, &p);
+ mps_res_t res = MPS_FIX2(ss, &p);
if (res != MPS_RES_OK) return res;
if (p == NULL) {
/* key/value was splatted: splat value/key too */
@@ -649,9 +649,9 @@ Navigation
The skip method is straightforward:
- static mps_addr_t buckets_skip(mps_addr_t base)
+static mps_addr_t buckets_skip(mps_addr_t base)
{
- buckets_t buckets = base;
+ buckets_t buckets = base;
size_t length = UNTAG_SIZE(buckets->length);
return (char *)base +
ALIGN(offsetof(buckets_s, bucket) +
@@ -679,17 +679,21 @@ Navigation
/* Create an Automatic Weak Linked (AWL) pool to manage the hash table
buckets. */
-res = mps_pool_create(&buckets_pool,
- arena,
- mps_class_awl(),
- buckets_fmt,
- buckets_find_dependent);
+res = mps_pool_create_k(&buckets_pool, arena, mps_class_awl(),
+ (mps_arg_s[]){{MPS_KEY_FORMAT, .val.format = buckets_fmt},
+ {MPS_KEY_AWL_FIND_DEPENDENT,
+ .val.addr_method = buckets_find_dependent},
+ {MPS_KEY_ARGS_END}});
if (res != MPS_RES_OK) error("Couldn't create buckets pool");
/* Create allocation points for weak and strong buckets. */
-res = mps_ap_create(&strong_buckets_ap, buckets_pool, mps_rank_exact());
+res = mps_ap_create_k(&strong_buckets_ap, buckets_pool,
+ (mps_arg_s[]){{MPS_KEY_RANK, .val.rank = mps_rank_exact()},
+ {MPS_KEY_ARGS_END}});
if (res != MPS_RES_OK) error("Couldn't create strong buckets allocation point");
-res = mps_ap_create(&weak_buckets_ap, buckets_pool, mps_rank_weak());
+res = mps_ap_create_k(&weak_buckets_ap, buckets_pool,
+ (mps_arg_s[]){{MPS_KEY_RANK, .val.rank = mps_rank_weak()},
+ {MPS_KEY_ARGS_END}});
if (res != MPS_RES_OK) error("Couldn't create weak buckets allocation point");
@@ -749,15 +753,15 @@ Navigation
Here’s the new symbol structure:
typedef struct symbol_s {
- type_t type; /* TYPE_SYMBOL */
- obj_t name; /* its name (a string) */
+ type_t type; /* TYPE_SYMBOL */
+ obj_t name; /* its name (a string) */
} symbol_s;
and the new implementation of intern:
-static obj_t intern_string(obj_t name)
+static obj_t intern_string(obj_t name)
{
- obj_t symbol;
+ obj_t symbol;
assert(TYPE(name) == TYPE_STRING);
symbol = table_ref(symtab, name);
if(symbol == NULL) {
@@ -767,7 +771,7 @@ Navigation
return symbol;
}
-static obj_t intern(char *string)
+static obj_t intern(char *string)
{
return intern_string(make_string(strlen(string), string));
}
@@ -775,7 +779,7 @@ Navigation
The symbol table now becomes a very simple root, that only has
to be registered once (not every time it is rehashed, as previously):
- mps_addr_t ref;
+mps_addr_t ref;
symtab = NULL;
ref = &symtab;
res = mps_root_create_table(&symtab_root, arena, mps_rank_exact(), 0,
@@ -823,23 +827,22 @@ Navigation
Here the appropriate class is AMCZ (Automatic Mostly-Copying Zero-rank), and the necessary code
changes are straightforward. First, global variables for the new pool
and its allocation point:
-static mps_pool_t leaf_pool; /* pool for leaf objects */
-static mps_ap_t leaf_ap; /* allocation point for leaf objects */
+static mps_pool_t leaf_pool; /* pool for leaf objects */
+static mps_ap_t leaf_ap; /* allocation point for leaf objects */
Second, the leaf objects must be allocated on leaf_ap instead of
obj_ap. And third, the pool and its allocation point must be created:
/* Create an Automatic Mostly-Copying Zero-rank (AMCZ) pool to
manage the leaf objects. */
-res = mps_pool_create(&leaf_pool,
- arena,
- mps_class_amcz(),
- obj_fmt,
- obj_chain);
+res = mps_pool_create_k(&leaf_pool, arena, mps_class_amcz(),
+ (mps_arg_s[]){{MPS_KEY_CHAIN, .val.chain = obj_chain},
+ {MPS_KEY_FORMAT, .val.format = obj_fmt},
+ {MPS_KEY_ARGS_END}});
if (res != MPS_RES_OK) error("Couldn't create leaf pool");
/* Create allocation point for leaf objects. */
-res = mps_ap_create(&leaf_ap, leaf_pool);
+res = mps_ap_create_k(&leaf_ap, leaf_pool, mps_args_none);
if (res != MPS_RES_OK) error("Couldn't create leaf objects allocation point");
diff --git a/mps/manual/html/guide/debug.html b/mps/manual/html/guide/debug.html
index 7e52d984e9c..6b4684fb187 100644
--- a/mps/manual/html/guide/debug.html
+++ b/mps/manual/html/guide/debug.html
@@ -227,13 +227,13 @@ Navigation
4.3. Example: allocating with wrong size
Here’s another kind of mistake: an off-by-one error in make_string
leading to the allocation of string objects with the wrong size:
-static obj_t make_string(size_t length, char *string)
+static obj_t make_string(size_t length, char *string)
{
- obj_t obj;
- mps_addr_t addr;
+ obj_t obj;
+ mps_addr_t addr;
size_t size = ALIGN(offsetof(string_s, string) + length/* oops, forgot: +1 */);
do {
- mps_res_t res = mps_reserve(&addr, obj_ap, size);
+ mps_res_t res = mps_reserve(&addr, obj_ap, size);
if (res != MPS_RES_OK) error("out of memory in make_string");
obj = addr;
obj->string.type = TYPE_STRING;
diff --git a/mps/manual/html/guide/lang.html b/mps/manual/html/guide/lang.html
index 1698595f1e2..55b43e428e9 100644
--- a/mps/manual/html/guide/lang.html
+++ b/mps/manual/html/guide/lang.html
@@ -90,7 +90,7 @@ Navigation
A Scheme object (whose type is not necessarily known) is represented by
an obj_t, which is a pointer to a union of every type in the
language:
-typedef union obj_u *obj_t;
+typedef union obj_u *obj_t;
typedef union obj_u {
type_s type;
pair_s pair;
@@ -113,8 +113,8 @@ Navigation
represented by a pointer to the structure pair_s defined as
follows:
typedef struct pair_s {
- type_t type; /* TYPE_PAIR */
- obj_t car, cdr; /* first and second projections */
+ type_t type; /* TYPE_PAIR */
+ obj_t car, cdr; /* first and second projections */
} pair_s;
@@ -122,7 +122,7 @@ Navigation
operate on objects generically, testing TYPE(obj) as necessary
(which is a macro for obj->type.type). For example, the
print() function is implemented like this:
-static void print(obj_t obj, unsigned depth, FILE *stream)
+static void print(obj_t obj, unsigned depth, FILE *stream)
{
switch (TYPE(obj)) {
case TYPE_INTEGER:
@@ -140,9 +140,9 @@ Navigation
Each constructor allocates memory for the new object by calling
malloc. For example, make_pair is the constructor for pairs:
- static obj_t make_pair(obj_t car, obj_t cdr)
+static obj_t make_pair(obj_t car, obj_t cdr)
{
- obj_t obj = (obj_t)malloc(sizeof(pair_s));
+ obj_t obj = (obj_t)malloc(sizeof(pair_s));
if (obj == NULL) error("out of memory");
obj->pair.type = TYPE_PAIR;
CAR(obj) = car;
@@ -181,26 +181,34 @@ Navigation
There’s only one arena, and many MPS functions take an arena as an
argument, so it makes sense for the arena to be a global variable
rather than having to pass it around everywhere:
-static mps_arena_t arena;
+static mps_arena_t arena;
-Create an arena by calling mps_arena_create(). This function
-takes a third argument when creating a virtual memory arena: the size of
-the amount of virtual virtual address space (not RAM),
-in bytes, that the arena will reserve initially. The MPS will ask for
+ Create an arena by calling mps_arena_create_k(). This function
+takes a keyword argument when creating a virtual memory arena:
+the size of virtual address space (not RAM), in
+bytes, that the arena will reserve initially. The MPS will ask for
more address space if it runs out, but the more times it has to extend
its address space, the less efficient garbage collection will become.
-The MPS works best if you reserve an address space that is several times
-larger than your peak memory usage.
+The MPS works best if you reserve an address space that is several
+times larger than your peak memory usage.
+
+ Note
+ Functions in the MPS interface take keyword arguments for
+arguments that are optional, or are only required in some
+circumstances. These argument are passed in the form of an array
+of structures of type mps_arg_s. See
+Keyword arguments for the full details.
+
Let’s reserve 32 megabytes:
-mps_res_t res;
-res = mps_arena_create(&arena,
- mps_arena_class_vm(),
- (size_t)(32 * 1024 * 1024));
+mps_res_t res;
+res = mps_arena_create_k(&arena, mps_arena_class_vm(),
+ (mps_arg_s[]){{MPS_KEY_ARENA_SIZE, .val.size = 32 * 1024 * 1024},
+ {MPS_KEY_ARGS_END}});
if (res != MPS_RES_OK) error("Couldn't create arena");
-mps_arena_create() is typical of functions in the MPS
+ mps_arena_create_k() is typical of functions in the MPS
interface in that it stores its result in a location pointed to by an
out parameter (here, &arena) and returns a result
code, which is MPS_RES_OK if the function succeeded, or
@@ -266,7 +274,7 @@ Navigation
obj_pad,
};
-mps_fmt_t obj_fmt;
+mps_fmt_t obj_fmt;
res = mps_fmt_create_A(&obj_fmt, arena, &obj_fmt_s);
if (res != MPS_RES_OK) error("Couldn't create obj format");
@@ -324,11 +332,11 @@ Navigation
discover references and so determine which objects are alive and which are dead, and also to update references
after objects have been moved.
Here’s the scan method for the toy Scheme interpreter:
- static mps_res_t obj_scan(mps_ss_t ss, mps_addr_t base, mps_addr_t limit)
+static mps_res_t obj_scan(mps_ss_t ss, mps_addr_t base, mps_addr_t limit)
{
MPS_SCAN_BEGIN(ss) {
while (base < limit) {
- obj_t obj = base;
+ obj_t obj = base;
switch (TYPE(obj)) {
case TYPE_PAIR:
FIX(CAR(obj));
@@ -406,9 +414,9 @@ Navigation
mps_fmt_skip_t. It is called by the MPS to skip over an
object belonging to the format, and also to determine its size.
Here’s the skip method for the toy Scheme interpreter:
-static mps_addr_t obj_skip(mps_addr_t base)
+static mps_addr_t obj_skip(mps_addr_t base)
{
- obj_t obj = base;
+ obj_t obj = base;
switch (TYPE(obj)) {
case TYPE_PAIR:
base = (char *)base + ALIGN(sizeof(pair_s));
@@ -461,24 +469,24 @@ Navigation
The first type is suitable for forwarding objects of three words or
longer:
typedef struct fwd_s {
- type_t type; /* TYPE_FWD */
- obj_t fwd; /* forwarded object */
+ type_t type; /* TYPE_FWD */
+ obj_t fwd; /* forwarded object */
size_t size; /* total size of this object */
} fwd_s;
while the second type is suitable for forwarding objects of two words:
typedef struct fwd2_s {
- type_t type; /* TYPE_FWD2 */
- obj_t fwd; /* forwarded object */
+ type_t type; /* TYPE_FWD2 */
+ obj_t fwd; /* forwarded object */
} fwd2_s;
Here’s the forward method for the toy Scheme interpreter:
-static void obj_fwd(mps_addr_t old, mps_addr_t new)
+static void obj_fwd(mps_addr_t old, mps_addr_t new)
{
- obj_t obj = old;
- mps_addr_t limit = obj_skip(old);
+ obj_t obj = old;
+ mps_addr_t limit = obj_skip(old);
size_t size = (char *)limit - (char *)old;
assert(size >= ALIGN_UP(sizeof(fwd2_s)));
if (size == ALIGN_UP(sizeof(fwd2_s))) {
@@ -537,9 +545,9 @@ Navigation
object is a forwarding object, and if it is, to determine the
location where that object was moved.
Here’s the is-forwarded method for the toy Scheme interpreter:
-static mps_addr_t obj_isfwd(mps_addr_t addr)
+static mps_addr_t obj_isfwd(mps_addr_t addr)
{
- obj_t obj = addr;
+ obj_t obj = addr;
switch (TYPE(obj)) {
case TYPE_FWD2:
return obj->fwd2.fwd;
@@ -573,7 +581,7 @@ Navigation
types of padding object. The first type is suitable for padding
objects of two words or longer:
typedef struct pad_s {
- type_t type; /* TYPE_PAD */
+ type_t type; /* TYPE_PAD */
size_t size; /* total size of this object */
} pad_s;
@@ -581,14 +589,14 @@ Navigation
while the second type is suitable for padding objects consisting of a
single word:
typedef struct pad1_s {
- type_t type; /* TYPE_PAD1 */
+ type_t type; /* TYPE_PAD1 */
} pad1_s;
Here’s the padding method:
- static void obj_pad(mps_addr_t addr, size_t size)
+static void obj_pad(mps_addr_t addr, size_t size)
{
- obj_t obj = addr;
+ obj_t obj = addr;
assert(size >= ALIGN(sizeof(pad1_s)));
if (size == ALIGN(sizeof(pad1_s))) {
TYPE(obj) = TYPE_PAD1;
@@ -664,7 +672,7 @@ Navigation
Second, the object format:
struct mps_fmt_A_s obj_fmt_s = {
- sizeof(mps_word_t),
+ sizeof(mps_word_t),
obj_scan,
obj_skip,
NULL,
@@ -673,7 +681,7 @@ Navigation
obj_pad,
};
-mps_fmt_t obj_fmt;
+mps_fmt_t obj_fmt;
res = mps_fmt_create_A(&obj_fmt, arena, &obj_fmt_s);
if (res != MPS_RES_OK) error("Couldn't create obj format");
@@ -684,7 +692,7 @@ Navigation
{ 170, 0.45 },
};
- mps_chain_t obj_chain;
+ mps_chain_t obj_chain;
res = mps_chain_create(&obj_chain,
arena,
LENGTH(obj_gen_params),
@@ -693,12 +701,11 @@ Navigation
And finally the pool:
-mps_pool_t obj_pool;
-res = mps_pool_create(&obj_pool,
- arena,
- mps_class_amc(),
- obj_fmt,
- obj_chain);
+mps_pool_t obj_pool;
+res = mps_pool_create_k(&obj_pool, arena, mps_class_amc(),
+ (mps_arg_s[]){{MPS_KEY_CHAIN, .val.chain = obj_chain},
+ {MPS_KEY_FORMAT, .val.format = obj_fmt},
+ {MPS_KEY_ARGS_END}});
if (res != MPS_RES_OK) error("Couldn't create obj pool");
@@ -721,15 +728,15 @@ Navigation
describe to the MPS how to scan them for references.
The toy Scheme interpreter has a number of static variables that point
to heap-allocated objects. First, the special objects, including:
-static obj_t obj_empty; /* (), the empty list */
+static obj_t obj_empty; /* (), the empty list */
Second, the predefined symbols, including:
-static obj_t obj_quote; /* "quote" symbol */
+static obj_t obj_quote; /* "quote" symbol */
And third, the global symbol table:
-static obj_t *symtab;
+static obj_t *symtab;
static size_t symtab_size;
@@ -740,7 +747,7 @@ Navigation
In the case of the toy Scheme interpreter, the root scanning function
for the special objects and the predefined symbols could be written
like this:
-static mps_res_t globals_scan(mps_ss_t ss, void *p, size_t s)
+static mps_res_t globals_scan(mps_ss_t ss, void *p, size_t s)
{
MPS_SCAN_BEGIN(ss) {
FIX(obj_empty);
@@ -755,7 +762,7 @@ Navigation
but in fact the interpreter already has tables of these global
objects, so it’s simpler and more extensible for the root scanning
function to iterate over them:
-static mps_res_t globals_scan(mps_ss_t ss, void *p, size_t s)
+static mps_res_t globals_scan(mps_ss_t ss, void *p, size_t s)
{
MPS_SCAN_BEGIN(ss) {
size_t i;
@@ -770,7 +777,7 @@ Navigation
Each root scanning function must be registered with the MPS by calling
mps_root_create(), like this:
- mps_root_t globals_root;
+mps_root_t globals_root;
res = mps_root_create(&globals_root, arena, mps_rank_exact(), 0,
globals_scan, NULL, 0);
if (res != MPS_RES_OK) error("Couldn't register globals root");
@@ -808,11 +815,11 @@ Navigation
the global symbol table, but the case of a table of references is
sufficiently common that the MPS provides a convenient (and optimized)
function, mps_root_create_table(), for registering it:
-static mps_root_t symtab_root;
+static mps_root_t symtab_root;
/* ... */
-mps_addr_t ref = symtab;
+mps_addr_t ref = symtab;
res = mps_root_create_table(&symtab_root, arena, mps_rank_exact(), 0,
ref, symtab_size);
if (res != MPS_RES_OK) error("Couldn't register new symtab root");
@@ -821,15 +828,15 @@ Navigation
The root must be re-registered whenever the global symbol table
changes size:
static void rehash(void) {
- obj_t *old_symtab = symtab;
+ obj_t *old_symtab = symtab;
unsigned old_symtab_size = symtab_size;
- mps_root_t old_symtab_root = symtab_root;
+ mps_root_t old_symtab_root = symtab_root;
unsigned i;
- mps_addr_t ref;
- mps_res_t res;
+ mps_addr_t ref;
+ mps_res_t res;
symtab_size *= 2;
- symtab = malloc(sizeof(obj_t) * symtab_size);
+ symtab = malloc(sizeof(obj_t) * symtab_size);
if (symtab == NULL) error("out of memory");
/* Initialize the new table to NULL so that "find" will work. */
@@ -843,7 +850,7 @@ Navigation
for (i = 0; i < old_symtab_size; ++i)
if (old_symtab[i] != NULL) {
- obj_t *where = find(old_symtab[i]->symbol.string);
+ obj_t *where = find(old_symtab[i]->symbol.string);
assert(where != NULL); /* new table shouldn't be full */
assert(*where == NULL); /* shouldn't be in new table */
*where = old_symtab[i];
@@ -906,7 +913,7 @@ Navigation
You register a thread with an arena by calling
mps_thread_reg():
-mps_thr_t thread;
+mps_thr_t thread;
res = mps_thread_reg(&thread, arena);
if (res != MPS_RES_OK) error("Couldn't register thread");
@@ -915,7 +922,7 @@ Navigation
calling mps_root_create_reg() and passing
mps_stack_scan_ambig():
void *marker = ▮
-mps_root_t reg_root;
+mps_root_t reg_root;
res = mps_root_create_reg(®_root,
arena,
mps_rank_ambig(),
@@ -946,11 +953,11 @@ Navigation
Manual pools typically support
malloc-like allocation using the function
mps_alloc(). But automatic pools cannot, because of the following problem:
-static obj_t make_pair(obj_t car, obj_t cdr)
+static obj_t make_pair(obj_t car, obj_t cdr)
{
- obj_t obj;
- mps_addr_t addr;
- mps_res_t res;
+ obj_t obj;
+ mps_addr_t addr;
+ mps_res_t res;
res = mps_alloc(&addr, pool, sizeof(pair_s));
if (res != MPS_RES_OK) error("out of memory in make_pair");
obj = addr;
@@ -972,23 +979,23 @@ Navigation
The MPS solves this problem via the fast, nearly lock-free
Allocation point protocol. This needs an additional
structure, an allocation point, to be attached to the pool by
-calling mps_ap_create():
-static mps_ap_t obj_ap;
+calling mps_ap_create_k():
+static mps_ap_t obj_ap;
/* ... */
-res = mps_ap_create(&obj_ap, obj_pool, mps_rank_exact());
+res = mps_ap_create_k(&obj_ap, obj_pool, mps_args_none);
if (res != MPS_RES_OK) error("Couldn't create obj allocation point");
And then the constructor can be implemented like this:
-static obj_t make_pair(obj_t car, obj_t cdr)
+static obj_t make_pair(obj_t car, obj_t cdr)
{
- obj_t obj;
- mps_addr_t addr;
+ obj_t obj;
+ mps_addr_t addr;
size_t size = ALIGN(sizeof(pair_s));
do {
- mps_res_t res = mps_reserve(&addr, obj_ap, size);
+ mps_res_t res = mps_reserve(&addr, obj_ap, size);
if (res != MPS_RES_OK) error("out of memory in make_pair");
obj = addr;
obj->pair.type = TYPE_PAIR;
diff --git a/mps/manual/html/index.html b/mps/manual/html/index.html
index cff70dc3459..81bf16f42e7 100644
--- a/mps/manual/html/index.html
+++ b/mps/manual/html/index.html
@@ -63,24 +63,25 @@ - Pool reference
diff --git a/mps/manual/html/mmref/bib.html b/mps/manual/html/mmref/bib.html
index a521d287424..dfef33450bf 100644
--- a/mps/manual/html/mmref/bib.html
+++ b/mps/manual/html/mmref/bib.html
@@ -131,6 +131,10 @@ Navigation
Richard Brooksby. 2002. “The Memory Pool System: Thirty person-years of memory management development goes Open Source”. ISMM‘02.
+ International Standard ISO/IEC 9899:1990. “Programming languages — C”.
+
+ International Standard ISO/IEC 9899:1999. “Programming languages — C”.
+
Brad Calder, Dirk Grunwald, Benjamin Zorn. 1994. “Quantifying Behavioral Differences Between C and C++ Programs”. Journal of Programming Languages. 2(4):313–351.
Dante J. Cannarozzi, Michael P. Plezbert, Ron K. Cytron. 2000. “Contaminated garbage collection”. ACM. Proceedings of the ACM SIGPLAN ‘00 conference on on Programming language design and implementation, pp. 264–273.
diff --git a/mps/manual/html/mmref/lang.html b/mps/manual/html/mmref/lang.html
index ecfa367138b..65e3347368c 100644
--- a/mps/manual/html/mmref/lang.html
+++ b/mps/manual/html/mmref/lang.html
@@ -125,7 +125,7 @@ Navigation
|