mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-08 04:30:45 -08:00
First draft of land design.
Copied from Perforce Change: 185146 ServerID: perforce.ravenbrook.com
This commit is contained in:
parent
651c2b9df0
commit
6beb2ed5f2
5 changed files with 341 additions and 173 deletions
|
|
@ -19,7 +19,7 @@ SRCID(arena, "$Id$");
|
|||
|
||||
#define ArenaControlPool(arena) MV2Pool(&(arena)->controlPoolStruct)
|
||||
#define ArenaCBSBlockPool(arena) (&(arena)->freeCBSBlockPoolStruct.poolStruct)
|
||||
#define ArenaFreeLand(arena) ((Land)&(arena)->freeLandStruct)
|
||||
#define ArenaFreeLand(arena) (&(arena)->freeLandStruct.landStruct)
|
||||
|
||||
|
||||
/* Forward declarations */
|
||||
|
|
|
|||
|
|
@ -29,50 +29,24 @@ high level communication with the client about the size of contiguous
|
|||
ranges, and detection of protocol violations.
|
||||
|
||||
|
||||
Definitions
|
||||
-----------
|
||||
|
||||
_`.def.range`: A (contiguous) *range* of addresses is a semi-open
|
||||
interval on address space.
|
||||
|
||||
_`.def.isolated`: A contiguous range is *isolated* with respect to
|
||||
some property it has, if adjacent elements do not have that property.
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
_`.req.set`: Must maintain a set of addresses.
|
||||
In addition to the generic land requirements (see
|
||||
design.mps.land.req), the CBS must satisfy:
|
||||
|
||||
_`.req.fast`: Common operations must have a low amortized cost.
|
||||
|
||||
_`.req.add`: Must be able to add address ranges to the set.
|
||||
|
||||
_`.req.remove`: Must be able to remove address ranges from the set.
|
||||
|
||||
_`.req.size`: Must report concisely to the client when isolated
|
||||
contiguous ranges of at least a certain size appear and disappear.
|
||||
|
||||
_`.req.iterate`: Must support the iteration of all isolated
|
||||
contiguous ranges. This will not be a common operation.
|
||||
|
||||
_`.req.protocol`: Must detect protocol violations.
|
||||
|
||||
_`.req.debug`: Must support debugging of client code.
|
||||
|
||||
_`.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.
|
||||
|
||||
_`.req.align`: Must support an alignment (the alignment of all
|
||||
addresses specifying ranges) of down to ``sizeof(void *)`` without
|
||||
losing memory.
|
||||
|
||||
|
||||
Interface
|
||||
---------
|
||||
|
||||
_`.header`: CBS is used through impl.h.cbs.
|
||||
_`.land`: The interface to CBS is the generic functions for the *land*
|
||||
abstract data type. See `design.mps.land <land/>`_.
|
||||
|
||||
|
||||
External types
|
||||
|
|
@ -80,147 +54,51 @@ External types
|
|||
|
||||
``typedef struct CBSStruct *CBS``
|
||||
|
||||
_`.type.cbs`: ``CBS`` is the main data structure for manipulating a
|
||||
CBS. It is intended that a ``CBSStruct`` be embedded in another
|
||||
structure. No convenience functions are provided for the allocation or
|
||||
deallocation of the CBS.
|
||||
|
||||
``typedef Bool (*CBSIterateMethod)(CBS cbs, Range range, void *closureP, Size closureS)``
|
||||
|
||||
_`.type.cbs.iterate.method`: Type ``CBSIterateMethod`` is a callback
|
||||
function that may be passed to ``CBSIterate()``. It is called for
|
||||
every isolated contiguous range in address order. The function must
|
||||
returns a ``Bool`` indicating whether to continue with the iteration.
|
||||
_`.type.cbs`: A ``CBSStruct`` may be embedded in another structure, or
|
||||
you can create it using ``LandCreate()``.
|
||||
|
||||
|
||||
External functions
|
||||
..................
|
||||
|
||||
``Res CBSInit(Arena arena, CBS cbs, void *owner, Align alignment, Bool fastFind, ArgList args)``
|
||||
``LandClass CBSLandClassGet(void)``
|
||||
|
||||
_`.function.cbs.init`: ``CBSInit()`` is the function that initialises
|
||||
the CBS structure. It performs allocation in the supplied arena. The
|
||||
parameter ``owner`` is passed to ``MeterInit()``, an ``alignment``
|
||||
indicates the alignment of ranges to be maintained. An initialised CBS
|
||||
contains no ranges.
|
||||
|
||||
``fastFind``, if set, causes the CBS to maintain, for each subtree,
|
||||
the size of the largest block in that subtree. This must be true if
|
||||
any of the ``CBSFindFirst()``, ``CBSFindLast()``, or
|
||||
``CBSFindLargest()`` functions are going to be used on the CBS.
|
||||
|
||||
``CBSInit()`` may take one keyword argument:
|
||||
|
||||
* ``MPS_KEY_CBS_EXTEND_BY`` (type ``Size``; default 4096) is the size
|
||||
of segment that the CBS will request from the arena in which to
|
||||
allocate its ``CBSBlock`` structures.
|
||||
|
||||
``void CBSFinish(CBS cbs)``
|
||||
|
||||
_`.function.cbs.finish`: ``CBSFinish()`` is the function that finishes
|
||||
the CBS structure and discards any other resources associated with the
|
||||
CBS.
|
||||
|
||||
``Res CBSInsert(Range rangeReturn, CBS cbs, Range range)``
|
||||
|
||||
_`.function.cbs.insert`: If any part of ``range`` is already in the
|
||||
CBS, then leave it unchanged and return ``ResFAIL``. Otherwise,
|
||||
attempt to insert ``range`` into the CBS. If the insertion succeeds,
|
||||
then update ``rangeReturn`` to describe the contiguous isolated range
|
||||
containing the inserted range (this may differ from ``range`` if there
|
||||
was coalescence on either side) and return ``ResOK``. If the insertion
|
||||
fails, return a result code indicating allocation failure.
|
||||
|
||||
_`.function.cbs.insert.fail`: Insertion of a valid range (that is, one
|
||||
that does not overlap with any range in the CBS) can only fail if the
|
||||
new range is isolated and the allocation of the necessary data
|
||||
structure to represent it failed.
|
||||
_`.function.class`: The function ``CBSLandClassGet()`` returns the CBS
|
||||
class, a subclass of ``LandClass`` suitable for passing to
|
||||
``LandCreate()`` or ``LandInit()``.
|
||||
|
||||
|
||||
``Res CBSDelete(Range rangeReturn, CBS cbs, Range range)``
|
||||
Keyword arguments
|
||||
.................
|
||||
|
||||
_`.function.cbs.delete`: If any part of the range is not in the CBS,
|
||||
then leave the CBS unchanged and return ``ResFAIL``. Otherwise, update
|
||||
``rangeReturn`` to describe the contiguous isolated range that
|
||||
contains ``range`` (this may differ from ``range`` if there are
|
||||
fragments on either side) and attempt to delete the range from the
|
||||
CBS. If the deletion succeeds, return ``ResOK``. If the deletion
|
||||
fails, return a result code indicating allocation failure.
|
||||
When initializing a CBS, ``LandCreate()`` and ``LandInit()`` take the
|
||||
following optional keyword arguments:
|
||||
|
||||
_`.function.cbs.delete.fail`: Deletion of a valid range (that is, one
|
||||
that is wholly contained in the CBS) can only fail if there are
|
||||
fragments on both sides and the allocation of the necessary data
|
||||
structures to represent them fails.
|
||||
* ``CBSBlockPool`` (type ``Pool``) is the pool from which the CBS
|
||||
block descriptors will be allocated. If omitted, a new MFS pool is
|
||||
created for this purpose.
|
||||
|
||||
_`.function.cbs.delete.return`: ``CBSDelete()`` returns the contiguous
|
||||
isolated range that contains ``range`` even if the deletion fails.
|
||||
This is so that the caller can try deleting the whole block (which is
|
||||
guaranteed to succeed) and managing the fragments using a fallback
|
||||
strategy.
|
||||
* ``MPS_KEY_CBS_EXTEND_BY`` (type ``Size``; default 4096) is passed as
|
||||
the ``MPS_KEY_EXTEND_BY`` keyword argument to ``PoolCreate()`` if a
|
||||
block descriptor pool is created. It specifies the size of segment
|
||||
that the block descriptor pool will request from the arena.
|
||||
|
||||
``void CBSIterate(CBS cbs, CBSIterateMethod iterate, void *closureP, Size closureS)``
|
||||
* ``MFSExtendSelf`` (type ``Bool``; default ``TRUE``) is passed to
|
||||
``PoolCreate()`` if a block descriptor pool is created. If ``TRUE``,
|
||||
the block descriptor pool automatically extends itself when out of
|
||||
space; if ``FALSE``, the pool returns ``ResLIMIT`` in this case.
|
||||
(This feature is used by the arena to bootstrap its own CBS of free
|
||||
memory.)
|
||||
|
||||
_`.function.cbs.iterate`: ``CBSIterate()`` is the function used to
|
||||
iterate all isolated contiguous ranges in a CBS. It receives a
|
||||
pointer, ``Size`` closure pair to pass on to the iterator method,
|
||||
and an iterator method to invoke on every range in address order. If
|
||||
the iterator method returns ``FALSE``, then the iteration is
|
||||
terminated.
|
||||
* ``CBSFastFind`` (type ``Bool``; default ``FALSE``). If ``TRUE``,
|
||||
causes the CBS to maintain, for each subtree, the size of the
|
||||
largest block in that subtree. This enables the ``LandFindFirst()``,
|
||||
``LandFindLast()``, and ``LandFindLargest()`` generic functions.
|
||||
|
||||
``Res CBSDescribe(CBS cbs, mps_lib_FILE *stream)``
|
||||
|
||||
_`.function.cbs.describe`: ``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.
|
||||
|
||||
``Bool CBSFindFirst(Range rangeReturn, Range oldRangeReturn, CBS cbs, Size size, FindDelete findDelete)``
|
||||
|
||||
_`.function.cbs.find.first`: Locate the first block (in address order)
|
||||
within the CBS of at least the specified size, update ``rangeReturn``
|
||||
to describe that range, and return ``TRUE``. If there is no such
|
||||
block, it returns ``FALSE``.
|
||||
|
||||
In addition, optionally delete the top, bottom, or all of the found
|
||||
range, depending on the ``findDelete`` argument. This saves a separate
|
||||
call to ``CBSDelete()``, and uses the knowledge of exactly where we
|
||||
found the range. The value of ``findDelete`` must come from this
|
||||
enumeration::
|
||||
|
||||
enum {
|
||||
FindDeleteNONE, /* don't delete after finding */
|
||||
FindDeleteLOW, /* delete size bytes from low end of block */
|
||||
FindDeleteHIGH, /* delete size bytes from high end of block */
|
||||
FindDeleteENTIRE /* delete entire range */
|
||||
};
|
||||
|
||||
The original contiguous isolated range in which the range was found is
|
||||
returned via the ``oldRangeReturn`` argument. (If ``findDelete`` is
|
||||
``FindDeleteNONE`` or ``FindDeleteENTIRE``, then this will be
|
||||
identical to the range returned via the ``rangeReturn`` argument.)
|
||||
|
||||
``CBSFindFirst()`` requires that ``fastFind`` was true when
|
||||
``CBSInit()`` was called.
|
||||
|
||||
``Bool CBSFindLast(Range rangeReturn, Range oldRangeReturn, CBS cbs, Size size, FindDelete findDelete)``
|
||||
|
||||
_`.function.cbs.find.last`: Like ``CBSFindFirst()``, except that it
|
||||
finds the last block in address order.
|
||||
|
||||
``Bool CBSFindLargest(Range rangeReturn, Range oldRangeReturn, CBS cbs, Size size, FindDelete findDelete)``
|
||||
|
||||
_`.function.cbs.find.largest`: Locate the largest block within the
|
||||
CBS, and if that block is at least as big as ``size``, return its
|
||||
range via the ``rangeReturn`` argument, and return ``TRUE``. If there
|
||||
are no blocks in the CBS at least as large as ``size``, return
|
||||
``FALSE``. Pass 0 for ``size`` if you want the largest block
|
||||
unconditionally.
|
||||
|
||||
Like ``CBSFindFirst()``, optionally delete the range (specifying
|
||||
``FindDeleteLOW`` or ``FindDeleteHIGH`` has the same effect as
|
||||
``FindDeleteENTIRE``). This feature requires that ``fastFind`` was
|
||||
true when ``CBSInit()`` was called.
|
||||
* ``CBSZoned`` (type ``Bool``; default ``FALSE``). If ``TRUE``, caused
|
||||
the CBS to maintain, for each subtree, the union of the zone sets of
|
||||
all ranges in that subtree. This enables the ``LandFindInZones()``
|
||||
generic function.
|
||||
|
||||
|
||||
Implementation
|
||||
|
|
@ -241,19 +119,19 @@ for comparison is the base of another range.
|
|||
|
||||
.. _design.mps.splay: splay
|
||||
|
||||
_`.impl.splay.fast-find`: ``CBSFindFirst()`` and ``CBSFindLast()`` use
|
||||
_`.impl.splay.fast-find`: ``cbsFindFirst()`` and ``cbsFindLast()`` use
|
||||
the update/refresh facility of splay trees to store, in each
|
||||
``CBSBlock``, an accurate summary of the maximum block size in the
|
||||
tree rooted at the corresponding splay node. This allows rapid
|
||||
location of the first or last suitable block, and very rapid failure
|
||||
if there is no suitable block.
|
||||
|
||||
_`.impl.find-largest`: ``CBSFindLargest()`` simply finds out the size
|
||||
_`.impl.find-largest`: ``cbsFindLargest()`` simply finds out the size
|
||||
of the largest block in the CBS from the root of the tree, using
|
||||
``SplayRoot()``, and does ``SplayFindFirst()`` for a block of that
|
||||
size. This takes time proportional to the logarithm of the size of the
|
||||
free list, so it's about the best you can do without maintaining a
|
||||
separate priority queue, just to do ``CBSFindLargest()``.
|
||||
separate priority queue, just to do ``cbsFindLargest()``.
|
||||
|
||||
|
||||
Low memory behaviour
|
||||
|
|
@ -261,10 +139,10 @@ Low memory behaviour
|
|||
|
||||
_`.impl.low-mem`: When the CBS tries to allocate a new ``CBSBlock``
|
||||
structure for a new isolated range as a result of either
|
||||
``CBSInsert()`` or ``CBSDelete()``, and there is insufficient memory
|
||||
``LandInsert()`` or ``LandDelete()``, and there is insufficient memory
|
||||
to allocation the ``CBSBlock`` structure, then the range is not added
|
||||
to the CBS or deleted from it, and the call to ``CBSInsert()`` or
|
||||
``CBSDelete()`` returns ``ResMEMORY``.
|
||||
to the CBS or deleted from it, and the call to ``LandInsert()`` or
|
||||
``LandDelete()`` returns ``ResMEMORY``.
|
||||
|
||||
|
||||
The CBS block
|
||||
|
|
@ -285,15 +163,8 @@ Testing
|
|||
|
||||
_`.test`: The following testing will be performed on this module:
|
||||
|
||||
_`.test.cbstest`: There is a stress test for this module in
|
||||
impl.c.cbstest. This allocates a large block of memory and then
|
||||
simulates the allocation and deallocation of ranges within this block
|
||||
using both a ``CBS`` and a ``BT``. It makes both valid and invalid
|
||||
requests, and compares the ``CBS`` response to the correct behaviour
|
||||
as determined by the ``BT``. It also iterates the ranges in the
|
||||
``CBS``, comparing them to the ``BT``. It also invokes the
|
||||
``CBSDescribe()`` method, but makes no automatic test of the resulting
|
||||
output. It does not currently test the callbacks.
|
||||
_`.test.fbmtest`: A generic test for land implementations. See
|
||||
design.mps.land.fbmtest.
|
||||
|
||||
_`.test.pool`: Several pools (currently MVT_ and MVFF_) are implemented
|
||||
on top of a CBS. These pool are subject to testing in development, QA,
|
||||
|
|
@ -359,6 +230,9 @@ Document History
|
|||
talking about the deleted "emergency" free list allocator.
|
||||
Documented ``fastFind`` argument to ``CBSInit()``.
|
||||
|
||||
- 2014-04-01 GDR_ Moved generic material to design.mps.land.
|
||||
Documented new keyword arguments.
|
||||
|
||||
.. _RB: http://www.ravenbrook.com/consultants/rb/
|
||||
.. _GDR: http://www.ravenbrook.com/consultants/gdr/
|
||||
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ guide.impl.c.format_ Coding standard: conventions for the general format of C
|
|||
interface-c_ The design of the Memory Pool System interface to C
|
||||
io_ The design of the MPS I/O subsystem
|
||||
keyword-arguments_ The design of the MPS mechanism for passing arguments by keyword.
|
||||
land_ Lands (collections of address ranges)
|
||||
lib_ The design of the Memory Pool System library interface
|
||||
lock_ The design of the lock module
|
||||
locus_ The design for the locus manager
|
||||
|
|
|
|||
292
mps/design/land.txt
Normal file
292
mps/design/land.txt
Normal file
|
|
@ -0,0 +1,292 @@
|
|||
.. mode: -*- rst -*-
|
||||
|
||||
Lands
|
||||
=====
|
||||
|
||||
:Tag: design.mps.land
|
||||
:Author: Gareth Rees
|
||||
:Date: 2014-04-01
|
||||
:Status: incomplete design
|
||||
:Revision: $Id$
|
||||
:Copyright: See section `Copyright and License`_.
|
||||
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
_`.intro`: This is the design of the *land* abstract data type, which
|
||||
represents a collection of contiguous address ranges.
|
||||
|
||||
_`.readership`: This document is intended for any MPS developer.
|
||||
|
||||
_`.source`: `design.mps.cbs <cbs/>`_, `design.mps.freelist <freelist/>`_.
|
||||
|
||||
_`.overview`: Collections of address ranges are used in several places
|
||||
in the MPS: the arena stores a set of mapped address ranges; pools
|
||||
store sets of address ranges which have been acquired from the arena
|
||||
and sets of address ranges that are available for allocation. The
|
||||
*land* abstract data type makes it easy to try out different
|
||||
implementations with different performance characteristics and other
|
||||
attributes.
|
||||
|
||||
_`.name`: The name is inspired by *rangeland* meaning *group of
|
||||
ranges* (where *ranges* is used in the sense *grazing areas*).
|
||||
|
||||
|
||||
Definitions
|
||||
-----------
|
||||
|
||||
_`.def.range`: A (contiguous) *range* of addresses is a semi-open
|
||||
interval on address space.
|
||||
|
||||
_`.def.isolated`: A contiguous range is *isolated* with respect to
|
||||
some property it has, if adjacent elements do not have that property.
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
_`.req.set`: Must maintain a set of addresses.
|
||||
|
||||
_`.req.add`: Must be able to add address ranges to the set.
|
||||
|
||||
_`.req.remove`: Must be able to remove address ranges from the set.
|
||||
|
||||
_`.req.size`: Must report concisely to the client when isolated
|
||||
contiguous ranges of at least a certain size appear and disappear.
|
||||
|
||||
_`.req.iterate`: Must support the iteration of all isolated
|
||||
contiguous ranges.
|
||||
|
||||
_`.req.protocol`: Must detect protocol violations.
|
||||
|
||||
_`.req.debug`: Must support debugging of client code.
|
||||
|
||||
_`.req.align`: Must support an alignment (the alignment of all
|
||||
addresses specifying ranges) of down to ``sizeof(void *)`` without
|
||||
losing memory.
|
||||
|
||||
|
||||
Interface
|
||||
---------
|
||||
|
||||
Types
|
||||
.....
|
||||
|
||||
``typedef LandStruct *Land;``
|
||||
|
||||
_`.type.land`: The type of a generic land instance.
|
||||
|
||||
``typedef Bool (*LandVisitor)(Land land, Range range, void *closureP, Size closureS);``
|
||||
|
||||
_`.type.visitor`: Type ``LandVisitor`` is a callback function that
|
||||
may be passed to ``LandIterate()``. It is called for every isolated
|
||||
contiguous range in address order. The function must return a
|
||||
``Bool`` indicating whether to continue with the iteration.
|
||||
|
||||
|
||||
Generic functions
|
||||
.................
|
||||
|
||||
``Res LandInit(Land land, LandClass class, Arena arena, Align alignment, void *owner, ArgList args)``
|
||||
|
||||
_`.function.init`: ``LandInit()`` initializes the land structure for
|
||||
the given class. The land will perform allocation (if necessary -- not
|
||||
all land classes need to allocate) in the supplied arena. The
|
||||
``alignment`` parameter is the alignment of the address ranges that
|
||||
will be stored and retrieved from the land. The parameter ``owner`` is
|
||||
output as a parameter to the ``LandInit`` event. The newly initialized
|
||||
land contains no ranges.
|
||||
|
||||
``Res LandCreate(Land *landReturn, Arena arena, LandClass class, Align alignment, void *owner, ArgList args)``
|
||||
|
||||
_`.function.create`: ``LandCreate()`` allocates memory for a land
|
||||
structure of the given class in ``arena``, and then passes all
|
||||
parameters to ``LandInit()``.
|
||||
|
||||
``void LandDestroy(Land land)``
|
||||
|
||||
_`.function.destroy`: ``LandDestroy()`` calls ``LandFinish()`` to
|
||||
finish the land structure, and then frees its memory.
|
||||
|
||||
``void LandFinish(Land land)``
|
||||
|
||||
_`.function.finish`: ``LandFinish()`` finishes the land structure and
|
||||
discards any other resources associated with the land.
|
||||
|
||||
``Res LandInsert(Range rangeReturn, Land land, Range range)``
|
||||
|
||||
_`.function.insert`: If any part of ``range`` is already in the
|
||||
land, then leave it unchanged and return ``ResFAIL``. Otherwise,
|
||||
attempt to insert ``range`` into the land. If the insertion succeeds,
|
||||
then update ``rangeReturn`` to describe the contiguous isolated range
|
||||
containing the inserted range (this may differ from ``range`` if there
|
||||
was coalescence on either side) and return ``ResOK``. If the insertion
|
||||
fails, return a result code indicating allocation failure.
|
||||
|
||||
_`.function.insert.fail`: Insertion of a valid range (that is, one
|
||||
that does not overlap with any range in the land) can only fail if the
|
||||
new range is isolated and the allocation of the necessary data
|
||||
structure to represent it failed.
|
||||
|
||||
``Res LandDelete(Range rangeReturn, Land land, Range range)``
|
||||
|
||||
_`.function.delete`: If any part of the range is not in the land,
|
||||
then leave the land unchanged and return ``ResFAIL``. Otherwise, update
|
||||
``rangeReturn`` to describe the contiguous isolated range that
|
||||
contains ``range`` (this may differ from ``range`` if there are
|
||||
fragments on either side) and attempt to delete the range from the
|
||||
land. If the deletion succeeds, return ``ResOK``. If the deletion
|
||||
fails, return a result code indicating allocation failure.
|
||||
|
||||
_`.function.delete.fail`: Deletion of a valid range (that is, one
|
||||
that is wholly contained in the land) can only fail if there are
|
||||
fragments on both sides and the allocation of the necessary data
|
||||
structures to represent them fails.
|
||||
|
||||
_`.function.delete.return`: ``LandDelete()`` returns the contiguous
|
||||
isolated range that contains ``range`` even if the deletion fails.
|
||||
This is so that the caller can try deleting the whole block (which is
|
||||
guaranteed to succeed) and managing the fragments using a fallback
|
||||
strategy.
|
||||
|
||||
``void LandIterate(Land land, LandIterateMethod iterate, void *closureP, Size closureS)``
|
||||
|
||||
_`.function.iterate`: ``LandIterate()`` is the function used to
|
||||
iterate all isolated contiguous ranges in a land. It receives a
|
||||
pointer, ``Size`` closure pair to pass on to the iterator method,
|
||||
and an iterator method to invoke on every range in address order. If
|
||||
the iterator method returns ``FALSE``, then the iteration is
|
||||
terminated.
|
||||
|
||||
``Bool LandFindFirst(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete)``
|
||||
|
||||
_`.function.find.first`: Locate the first block (in address order)
|
||||
within the land of at least the specified size, update ``rangeReturn``
|
||||
to describe that range, and return ``TRUE``. If there is no such
|
||||
block, it returns ``FALSE``.
|
||||
|
||||
In addition, optionally delete the top, bottom, or all of the found
|
||||
range, depending on the ``findDelete`` argument. This saves a separate
|
||||
call to ``LandDelete()``, and uses the knowledge of exactly where we
|
||||
found the range. The value of ``findDelete`` must come from this
|
||||
enumeration::
|
||||
|
||||
enum {
|
||||
FindDeleteNONE, /* don't delete after finding */
|
||||
FindDeleteLOW, /* delete size bytes from low end of block */
|
||||
FindDeleteHIGH, /* delete size bytes from high end of block */
|
||||
FindDeleteENTIRE /* delete entire range */
|
||||
};
|
||||
|
||||
The original contiguous isolated range in which the range was found is
|
||||
returned via the ``oldRangeReturn`` argument. (If ``findDelete`` is
|
||||
``FindDeleteNONE`` or ``FindDeleteENTIRE``, then this will be
|
||||
identical to the range returned via the ``rangeReturn`` argument.)
|
||||
|
||||
``Bool LandFindLast(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete)``
|
||||
|
||||
_`.function.find.last`: Like ``LandFindFirst()``, except that it
|
||||
finds the last block in address order.
|
||||
|
||||
``Bool LandFindLargest(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete)``
|
||||
|
||||
_`.function.find.largest`: Locate the largest block within the
|
||||
land, and if that block is at least as big as ``size``, return its
|
||||
range via the ``rangeReturn`` argument, and return ``TRUE``. If there
|
||||
are no blocks in the land at least as large as ``size``, return
|
||||
``FALSE``. Pass 0 for ``size`` if you want the largest block
|
||||
unconditionally.
|
||||
|
||||
Like ``LandFindFirst()``, optionally delete the range (specifying
|
||||
``FindDeleteLOW`` or ``FindDeleteHIGH`` has the same effect as
|
||||
``FindDeleteENTIRE``), and return the original contiguous isolated
|
||||
range in which the range was found via the ``oldRangeReturn``
|
||||
argument.
|
||||
|
||||
``Res LandFindInZones(Range rangeReturn, Range oldRangeReturn, Land land, Size size, ZoneSet zoneSet, Bool high)``
|
||||
|
||||
_`.function.find.zones`: Locate a block at least as big as ``size``
|
||||
that lies entirely within the ``zoneSet``, return its range via the
|
||||
``rangeReturn`` argument, and return ``TRUE``. (The first such block,
|
||||
if ``high`` is ``FALSE``, or the last, if ``high`` is ``TRUE``.) If
|
||||
there is no such block, , return ``FALSE``.
|
||||
|
||||
Delete the range as for ``LandFindFirst()`` and ``LastFindLast()``
|
||||
(with the effect of ``FindDeleteLOW`` if ``high`` is ``FALSE`` and the
|
||||
effect of ``FindDeleteHIGH`` if ``high`` is ``TRUE``), and return the
|
||||
original contiguous isolated range in which the range was found via
|
||||
the ``oldRangeReturn`` argument.
|
||||
|
||||
``Res LandDescribe(Land land, mps_lib_FILE *stream)``
|
||||
|
||||
_`.function.describe`: ``LandDescribe()`` is a function that prints
|
||||
a textual representation of the land 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.
|
||||
|
||||
|
||||
Testing
|
||||
-------
|
||||
|
||||
_`.test.fbmtest`: There is a stress test for implementations of this
|
||||
interface in impl.c.fbmtest. This allocates a large block of memory
|
||||
and then simulates the allocation and deallocation of ranges within
|
||||
this block using both a ``Land`` and a ``BT``. It makes both valid and
|
||||
invalid requests, and compares the ``Land`` response to the correct
|
||||
behaviour as determined by the ``BT``. It iterates the ranges in the
|
||||
``Land``, comparing them to the ``BT``. It invokes the
|
||||
``LandDescribe()`` generic function, but makes no automatic test of
|
||||
the resulting output.
|
||||
|
||||
|
||||
Document History
|
||||
----------------
|
||||
|
||||
- 2014-04-01 GDR_ Created based on `design.mps.cbs <cbs/>`_.
|
||||
|
||||
.. _GDR: http://www.ravenbrook.com/consultants/gdr/
|
||||
|
||||
|
||||
Copyright and License
|
||||
---------------------
|
||||
|
||||
Copyright © 2014 Ravenbrook Limited. All rights reserved.
|
||||
<http://www.ravenbrook.com/>. This is an open source license. Contact
|
||||
Ravenbrook for commercial licensing options.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
#. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
#. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
#. Redistributions in any form must be accompanied by information on how
|
||||
to obtain complete source code for this software and any
|
||||
accompanying software that uses this software. The source code must
|
||||
either be included in the distribution or be available for no more than
|
||||
the cost of distribution plus a nominal fee, and must be freely
|
||||
redistributable under reasonable conditions. For an executable file,
|
||||
complete source code means the source code for all modules it contains.
|
||||
It does not include source code for modules or files that typically
|
||||
accompany the major components of the operating system on which the
|
||||
executable file runs.
|
||||
|
||||
**This software is provided by the copyright holders and contributors
|
||||
"as is" and any express or implied warranties, including, but not
|
||||
limited to, the implied warranties of merchantability, fitness for a
|
||||
particular purpose, or non-infringement, are disclaimed. In no event
|
||||
shall the copyright holders and contributors be liable for any direct,
|
||||
indirect, incidental, special, exemplary, or consequential damages
|
||||
(including, but not limited to, procurement of substitute goods or
|
||||
services; loss of use, data, or profits; or business interruption)
|
||||
however caused and on any theory of liability, whether in contract,
|
||||
strict liability, or tort (including negligence or otherwise) arising in
|
||||
any way out of the use of this software, even if advised of the
|
||||
possibility of such damage.**
|
||||
|
|
@ -14,6 +14,7 @@ Design
|
|||
guide.hex.trans
|
||||
guide.impl.c.format
|
||||
keyword-arguments
|
||||
land
|
||||
range
|
||||
ring
|
||||
sig
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue