mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-10 21:50:37 -08:00
Write plinth chapter.
Copied from Perforce Change: 180147 ServerID: perforce.ravenbrook.com
This commit is contained in:
parent
bd355caff8
commit
f6f55dba1d
7 changed files with 519 additions and 70 deletions
266
mps/manual/source/diagrams/mark-sweep.svg
Normal file
266
mps/manual/source/diagrams/mark-sweep.svg
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="250"
|
||||
height="220"
|
||||
id="svg9412"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.2 r9819"
|
||||
sodipodi:docname="mark-sweep.svg">
|
||||
<defs
|
||||
id="defs9414">
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Lend"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
id="path4412"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1"
|
||||
inkscape:cx="51.5"
|
||||
inkscape:cy="92.046973"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
fit-margin-top="10"
|
||||
fit-margin-left="10"
|
||||
fit-margin-right="10"
|
||||
fit-margin-bottom="10"
|
||||
inkscape:window-width="1276"
|
||||
inkscape:window-height="756"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-grids="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid9420"
|
||||
empspacing="5"
|
||||
visible="true"
|
||||
enabled="true"
|
||||
snapvisiblegridlinesonly="true" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata9417">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-89.5,-12.862183)">
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker-end:none"
|
||||
id="path3150"
|
||||
sodipodi:cx="-100"
|
||||
sodipodi:cy="70"
|
||||
sodipodi:rx="10"
|
||||
sodipodi:ry="10"
|
||||
d="m -90,70 c 0,5.522847 -4.477153,10 -10,10 -5.52285,0 -10,-4.477153 -10,-10 0,-5.522847 4.47715,-10 10,-10 5.522847,0 10,4.477153 10,10 z"
|
||||
transform="translate(209.5,-37.137817)" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Lend)"
|
||||
d="m 189.5,82.862183 80,-32"
|
||||
id="path3928"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Lend)"
|
||||
d="m 299.5,122.86218 0,-57.999997"
|
||||
id="path3930"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Lend)"
|
||||
d="m 189.5,82.862183 80,31.999997"
|
||||
id="path3932"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Lend)"
|
||||
d="m 299.5,202.86218 0,-58"
|
||||
id="path3936"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:none;marker-end:url(#Arrow1Lend)"
|
||||
d="m 189.5,162.86218 0,-58"
|
||||
id="path4566"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:none;marker-end:url(#Arrow1Lend)"
|
||||
d="m 189.5,162.86218 80,32"
|
||||
id="path4568"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<g
|
||||
id="g3125"
|
||||
transform="translate(59.5,-59.5)">
|
||||
<path
|
||||
transform="translate(10,0)"
|
||||
d="m 150,142.36218 c 0,11.0457 -13.43146,20 -30,20 -16.56854,0 -30,-8.9543 -30,-20 0,-11.04569 13.43146,-20 30,-20 16.56854,0 30,8.95431 30,20 z"
|
||||
sodipodi:ry="20"
|
||||
sodipodi:rx="30"
|
||||
sodipodi:cy="142.36218"
|
||||
sodipodi:cx="120"
|
||||
id="path9422"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
||||
sodipodi:type="arc" />
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text9932"
|
||||
y="148.36218"
|
||||
x="130"
|
||||
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Verdana;-inkscape-font-specification:Verdana"
|
||||
y="148.36218"
|
||||
x="130"
|
||||
id="tspan9934"
|
||||
sodipodi:role="line">1</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
id="g3135"
|
||||
transform="translate(9.5,-19.5)">
|
||||
<path
|
||||
transform="translate(170,0)"
|
||||
sodipodi:type="arc"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
||||
id="path9936"
|
||||
sodipodi:cx="120"
|
||||
sodipodi:cy="142.36218"
|
||||
sodipodi:rx="30"
|
||||
sodipodi:ry="20"
|
||||
d="m 150,142.36218 c 0,11.0457 -13.43146,20 -30,20 -16.56854,0 -30,-8.9543 -30,-20 0,-11.04569 13.43146,-20 30,-20 16.56854,0 30,8.95431 30,20 z" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||
x="290"
|
||||
y="148.36218"
|
||||
id="text9938"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan9940"
|
||||
x="290"
|
||||
y="148.36218"
|
||||
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Verdana;-inkscape-font-specification:Verdana">3</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
id="g3130"
|
||||
transform="translate(89.5,-39.5)">
|
||||
<path
|
||||
transform="translate(90,-60)"
|
||||
sodipodi:type="arc"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
||||
id="path9944"
|
||||
sodipodi:cx="120"
|
||||
sodipodi:cy="142.36218"
|
||||
sodipodi:rx="30"
|
||||
sodipodi:ry="20"
|
||||
d="m 150,142.36218 c 0,11.0457 -13.43146,20 -30,20 -16.56854,0 -30,-8.9543 -30,-20 0,-11.04569 13.43146,-20 30,-20 16.56854,0 30,8.95431 30,20 z" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||
x="210"
|
||||
y="88.362183"
|
||||
id="text9946"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan9948"
|
||||
x="210"
|
||||
y="88.362183"
|
||||
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Verdana;-inkscape-font-specification:Verdana">2</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
id="g3140"
|
||||
transform="translate(-20.5,-39.5)">
|
||||
<path
|
||||
d="m 150,142.36218 c 0,11.0457 -13.43146,20 -30,20 -16.56854,0 -30,-8.9543 -30,-20 0,-11.04569 13.43146,-20 30,-20 16.56854,0 30,8.95431 30,20 z"
|
||||
sodipodi:ry="20"
|
||||
sodipodi:rx="30"
|
||||
sodipodi:cy="142.36218"
|
||||
sodipodi:cx="120"
|
||||
id="path9950"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
||||
sodipodi:type="arc"
|
||||
transform="translate(90,60)" />
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text9952"
|
||||
y="208.36218"
|
||||
x="210"
|
||||
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Verdana;-inkscape-font-specification:Verdana"
|
||||
y="208.36218"
|
||||
x="210"
|
||||
id="tspan9954"
|
||||
sodipodi:role="line">4</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
id="g3145"
|
||||
transform="translate(20,-70)">
|
||||
<path
|
||||
d="m 150,142.36218 c 0,11.0457 -13.43146,20 -30,20 -16.56854,0 -30,-8.9543 -30,-20 0,-11.04569 13.43146,-20 30,-20 16.56854,0 30,8.95431 30,20 z"
|
||||
sodipodi:ry="20"
|
||||
sodipodi:rx="30"
|
||||
sodipodi:cy="142.36218"
|
||||
sodipodi:cx="120"
|
||||
id="path3119"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
||||
sodipodi:type="arc"
|
||||
transform="translate(159.5,130.5)" />
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text3121"
|
||||
y="278.86218"
|
||||
x="279.5"
|
||||
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Verdana;-inkscape-font-specification:Verdana"
|
||||
y="278.86218"
|
||||
x="279.5"
|
||||
id="tspan3123"
|
||||
sodipodi:role="line">5</tspan></text>
|
||||
</g>
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Lend)"
|
||||
d="m 109.5,32.862183 54,36"
|
||||
id="path3926"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 11 KiB |
|
|
@ -79,6 +79,8 @@ Bibliography
|
|||
|
||||
.. [HM93] Antony L. Hosking, J. Eliot B. Moss. 1993. "Protection traps and alternatives for memory management of an object-oriented language".
|
||||
|
||||
.. [ISO90] "International Standard ISO/IEC 9899:1990 Programming languages — C".
|
||||
|
||||
.. [JONES96] Richard E. Jones, Rafael Lins. 1996. "Garbage Collection: Algorithms for Automatic Dynamic Memory Management".
|
||||
|
||||
.. [JONES12] Richard E. Jones, Antony Hosking, and Eliot Moss. 2012. "The Garbage Collection Handbook". Chapman & Hall. `<http://gchandbook.org/>`_.
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ A brief history of memory management
|
|||
1970
|
||||
|
||||
Intel produce the 1103, the first generally available
|
||||
:term:`DRAM`.
|
||||
:term:`DRAM <dynamic memory>`.
|
||||
|
||||
1970
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ In the second phase, the collector *sweeps* all allocated memory,
|
|||
searching for blocks that have not been marked. If it finds any, it
|
||||
returns them to the allocator for reuse.
|
||||
|
||||
.. figure:: ../diagrams/mark-sweep.png
|
||||
.. figure:: ../diagrams/mark-sweep.svg
|
||||
:align: center
|
||||
:alt: Diagram: Five memory blocks, three of which are reachable from program variables.
|
||||
|
||||
|
|
@ -70,8 +70,8 @@ two problems that typically occur:
|
|||
|
||||
* the memory in use is widely scattered in memory, causing poor
|
||||
performance in the :term:`memory caches <cache (1)>` or
|
||||
:term:`virtual memory (1)` systems of most modern computers (known
|
||||
as poor :term:`locality of reference`);
|
||||
:term:`virtual memory` systems of most modern computers (known as
|
||||
poor :term:`locality of reference`);
|
||||
|
||||
* it becomes difficult to allocate large blocks because free memory is
|
||||
divided into small pieces, separated by blocks in use (known as
|
||||
|
|
@ -201,8 +201,8 @@ keeping the counts up to date. An object cannot be reclaimed as soon
|
|||
as its count has dropped to zero, because there might still be a
|
||||
reference to it from a program variable. Instead, the program
|
||||
variables (including the :term:`control stack`) are periodically
|
||||
:term:`scanned`, and any objects which are not referenced from there
|
||||
and which have zero count are reclaimed.
|
||||
:term:`scanned <scan>`, and any objects which are not referenced from
|
||||
there and which have zero count are reclaimed.
|
||||
|
||||
Deferred reference counting cannot normally be used unless it is
|
||||
directly supported by the compiler. It's more common for modern
|
||||
|
|
@ -215,16 +215,16 @@ program variables.
|
|||
One-bit reference counting
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Another variation on reference counting, called :term:`one-bit
|
||||
reference counting`, uses a single bit flag to indicate whether each
|
||||
Another variation on reference counting, known as the :term:`one-bit
|
||||
reference count`, uses a single bit flag to indicate whether each
|
||||
object has either "one" or "many" references. If a reference to an
|
||||
object with "one" reference is removed, then the object can be
|
||||
recycled. If an object has "many" references, then removing references
|
||||
does not change this, and that object will never be recycled. It is
|
||||
possible to store the flag as part of the *pointer* to the
|
||||
object, so no additional space is required in each object to store the
|
||||
count. One-bit reference counting is effective in practice because
|
||||
most actual objects have a reference count of one.
|
||||
possible to store the flag as part of the *pointer* to the object, so
|
||||
no additional space is required in each object to store the count.
|
||||
One-bit reference counting is effective in practice because most
|
||||
actual objects have a reference count of one.
|
||||
|
||||
|
||||
Weighted reference counting
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ Outstanding
|
|||
collection. (RB needs to write this.)
|
||||
|
||||
126. Things that are "within reach", i.e. that we could do if people
|
||||
needed them.
|
||||
needed them. (RB needs to write this.)
|
||||
|
||||
127. :c:func:`mps_arena_roots_walk` says, "A client-supplied function
|
||||
is called for every root reference which points to an object in
|
||||
|
|
@ -81,6 +81,19 @@ Outstanding
|
|||
supported platforms section doesn't exist elsewhere. Note that
|
||||
the platforms we build with (in build.txt) is not the same list.
|
||||
|
||||
131. Is :c:type:`mps_clock_t` a transparent alias for ``unsigned
|
||||
long``? I presume it must be: if it were platform-specific, or
|
||||
supplied by the plinth, then it wouldn't be defined in ``mps.h``,
|
||||
surely?
|
||||
|
||||
132. :c:func:`mps_lib_get_stderr` appears in ``mpslib.h`` and
|
||||
``mpsliban.c`` but is not called by the MPS (it uses
|
||||
:c:func:`mps_lib_assert_fail` for assertions). Should this be
|
||||
documented to reserve the option of using it, or should it be
|
||||
left out?
|
||||
|
||||
133. What's the purpose of ``mps_SEH_filter`` and ``mps_SEH_handler``?
|
||||
|
||||
|
||||
Complete
|
||||
--------
|
||||
|
|
|
|||
|
|
@ -165,8 +165,8 @@ out parameter, like this::
|
|||
res = mps_alloc((mps_addr_t *)&fp, pool, sizeof(struct foo));
|
||||
|
||||
This is known as :term:`type punning`, and its behaviour is not
|
||||
defined in ANSI/ISO Standard C. See §6.3.2.3, which defines the
|
||||
conversion of a pointer from one type to another: the behaviour of
|
||||
defined in ANSI/ISO Standard C. See [ISO90]_ §6.3.2.3, which defines
|
||||
the conversion of a pointer from one type to another: the behaviour of
|
||||
this cast is not covered by any of the cases in the standard.
|
||||
|
||||
Instead, we recommend this approach::
|
||||
|
|
@ -178,14 +178,14 @@ Instead, we recommend this approach::
|
|||
fp = (struct foo *)p;
|
||||
|
||||
This is portable because conversion from ``void *`` to any other
|
||||
:term:`object pointer` type is defined by §6.3.2.3.1.
|
||||
:term:`object pointer` type is defined by [ISO90]_ §6.3.2.3.1.
|
||||
|
||||
|
||||
Macros
|
||||
------
|
||||
|
||||
1. For function-like macros, the MPS follows the same convention as
|
||||
the Standard C library. To quote §7.1.7:
|
||||
the Standard C library. To quote [ISO90]_ §7.1.7:
|
||||
|
||||
Any function declared in a header may additionally be
|
||||
implemented as a macro defined in the header, so a library
|
||||
|
|
@ -266,6 +266,17 @@ General types
|
|||
"true".
|
||||
|
||||
|
||||
.. c:type:: mps_clock_t
|
||||
|
||||
The type of a processor time.
|
||||
|
||||
It is a :term:`transparent alias <transparent type>` for
|
||||
``unsigned long``.
|
||||
|
||||
This is the type returned by the plinth function
|
||||
:c:func:`mps_clock`.
|
||||
|
||||
|
||||
.. c:type:: mps_word_t
|
||||
|
||||
An unsigned integral type that is the same size as an
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
`<https://info.ravenbrook.com/project/mps/master/design/lib/>`_
|
||||
`<https://info.ravenbrook.com/project/mps/doc/2002-06-18/obsolete-mminfo/mmdoc/doc/mps/ref-man/concepts/>`_
|
||||
`<https://info.ravenbrook.com/project/mps/doc/2002-06-18/obsolete-mminfo/mmdoc/doc/mps/guide/interface/>`_
|
||||
`<https://info.ravenbrook.com/project/mps/doc/2002-06-18/obsolete-mminfo/mmdoc/doc/mps/guide/appendix/plinth/>`_
|
||||
|
||||
|
||||
.. _topic-plinth:
|
||||
|
|
@ -11,45 +12,52 @@
|
|||
Plinth
|
||||
======
|
||||
|
||||
The MPS is designed to be portable to systems that have only a
|
||||
*conforming freestanding implementation* of the C language: that is,
|
||||
systems which potentially lack the facilities of the Standard C
|
||||
Library that must be provided by *hosted* implementations.
|
||||
The :dfn:`plinth` is a program module providing the MPS with all the
|
||||
support it needs from the execution environment. It serves two
|
||||
purposes, both relating to operating system support:
|
||||
|
||||
Instead of using hosted facilities like Standard I/O, the MPS uses the
|
||||
:dfn:`plinth`: a program module providing all the support it needs
|
||||
from the execution environment.
|
||||
1. The MPS is designed to be portable to systems that have only a
|
||||
*conforming freestanding implementation* of the C language: that
|
||||
is, systems which potentially lack facilities of the Standard C
|
||||
Library, such as Standard I/O. The plinth provides all the
|
||||
necessary facilities.
|
||||
|
||||
The plinth may be provided by the client application; however, a
|
||||
2. The plinth gives the :term:`client program` complete control of
|
||||
interaction between the MPS and the user, including :ref:`messages
|
||||
<topic-message>` and :ref:`telemetry <topic-telemetry>`.
|
||||
|
||||
The plinth may be provided by the :term:`client program`; however, a
|
||||
sample implementation of the plinth using ANSI Standard C Library
|
||||
facilities is included with the MPS, and this is good enough for most
|
||||
applications.
|
||||
|
||||
There are many reasons why you might want to write your own plinth.
|
||||
You may be targetting a *freestanding environment* such as an embedded
|
||||
system. You might need to write the telemetry stream to a system
|
||||
logging facility, or transmit it over a serial port or network
|
||||
connection. Or you might need to direct debugging output to a
|
||||
convenient window in the user interface.
|
||||
|
||||
The plinth is divided into two parts:
|
||||
|
||||
1. The :ref:`topic-plinth-io` enables the MPS to write binary messages
|
||||
to an output stream.
|
||||
|
||||
2. The :ref:`topic-plinth-lib` provides miscellaneous functionality
|
||||
that would be available via the Standard C Library on a hosted
|
||||
platform, including functions for reporting errors and accessing
|
||||
a processor clock.
|
||||
|
||||
|
||||
.. _topic-plinth-io:
|
||||
|
||||
From
|
||||
I/O module
|
||||
----------
|
||||
|
||||
To perform its various duties, the MPS needs very little external support. Indeed, there is a way of using it so that it needs none at all, making it possible to use the MPS in embedded applications. There are two key components to this: the client arena and the plinth . This section concerns the plinth; for more information about the client arena, see mps_arena_class_cl in the Reference Manual.
|
||||
::
|
||||
|
||||
The plinth also has another purpose: it gives the application programmer complete control of how interaction between the MPS and the user happens. This comprises things like debugging messages and logging. The two purposes are intertwined, because both relate to operating system support.
|
||||
#include "mpsio.h"
|
||||
|
||||
The plinth is a program module providing the MPS with all the support functions it needs from the execution environment. The plinth is provided by the application programmer; this is how the plinth removes the need for external libraries, by getting the support from the client application, and at the same time, gives the application programmer control over the implementation of its features.
|
||||
|
||||
However, before you panic, a sample implementation of a plinth using standard ISO C library facilities is provided with the MPS (mpsliban.c and mpsioan.c), and this is often adequate for your needs, so you don't have to write your own. Naturally, if you use the ISO plinth, you then need to link with the C library.
|
||||
|
||||
There are many reasons why you might want to write your own plinth. For embedded applications, the MPS will work in what the C standard calls a freestanding environment, as long as you provide it with a plinth that works in that environment, and use the client arena (virtual memory arenas contain OS-specific code that calls the VM interfaces of the OS). Programmers of GUI applications might want a plinth that directs debugging output to a convenient window.
|
||||
|
||||
See <https://info.ravenbrook.com/project/mps/doc/2002-06-18/obsolete-mminfo/mmdoc/doc/mps/guide/appendix/plinth/>
|
||||
|
||||
The example ANSI plinth, ``mpsliban.c``, implements :c:func:`mps_clock` by calling the ISO C function ``clock`` in ``time.h``. The difference between two of these clock values may be converted to seconds by dividing by the ``CLOCKS_PER_SEC`` conversion factor.
|
||||
|
||||
|
||||
See also <https://info.ravenbrook.com/project/mps/master/design/io/>
|
||||
|
||||
|
||||
Declared in ``mpsio.h``
|
||||
-----------------------
|
||||
|
||||
.. c:type:: mps_io_t
|
||||
|
||||
|
|
@ -60,6 +68,11 @@ Declared in ``mpsio.h``
|
|||
needs to. Alternatively, it may leave the structure type undefined
|
||||
and simply cast its own pointer to and from :c:type:`mps_io_t`.
|
||||
|
||||
.. note::
|
||||
|
||||
In the ANSI I/O module, ``mpsioan.c``, this is an alias for
|
||||
``FILE *``.
|
||||
|
||||
|
||||
.. c:function:: mps_res_t mps_io_create(mps_io_t *io_o)
|
||||
|
||||
|
|
@ -77,6 +90,12 @@ Declared in ``mpsio.h``
|
|||
A typical plinth will use it to open a file for writing, or to
|
||||
connect to the system logging interface.
|
||||
|
||||
.. note::
|
||||
|
||||
In the ANSI I/O module, ``mpsioan.c``, this calls ``fopen`` on
|
||||
the file named by the environment variable
|
||||
:envvar:`MPS_TELEMETRY_FILENAME`.
|
||||
|
||||
|
||||
.. c:function:: void mps_io_destroy(mps_io_t io)
|
||||
|
||||
|
|
@ -89,6 +108,10 @@ Declared in ``mpsio.h``
|
|||
After calling this function, the MPS guarantees not to use the
|
||||
value ``io`` again.
|
||||
|
||||
.. note::
|
||||
|
||||
In the ANSI I/O module, ``mpsioan.c``, this calls ``fclose``.
|
||||
|
||||
|
||||
.. c:function:: mps_res_t mps_io_write(mps_io_t io, void *buf, size_t size)
|
||||
|
||||
|
|
@ -104,6 +127,10 @@ Declared in ``mpsio.h``
|
|||
|
||||
Returns :c:macro:`MPS_RES_OK` if successful.
|
||||
|
||||
.. note::
|
||||
|
||||
In the ANSI I/O module, ``mpsioan.c``, this calls ``fwrite``.
|
||||
|
||||
|
||||
.. c:function:: mps_res_t mps_io_flush(mps_io_t io)
|
||||
|
||||
|
|
@ -124,9 +151,140 @@ Declared in ``mpsio.h``
|
|||
bug, for example) or some interactive tool require access to the
|
||||
event data.
|
||||
|
||||
.. note::
|
||||
|
||||
In the ANSI I/O module, ``mpsioan.c``, this calls ``fflush``.
|
||||
|
||||
|
||||
.. _topic-plinth-lib:
|
||||
|
||||
Library module
|
||||
--------------
|
||||
|
||||
::
|
||||
|
||||
#include "mpslib.h"
|
||||
|
||||
|
||||
.. c:function:: mps_clock_t mps_clock(void)
|
||||
|
||||
Return the time since some epoch, in units given by
|
||||
:c:func:`mps_clocks_per_sec`.
|
||||
|
||||
This should be a cheap, high-resolution processor timer. There is
|
||||
no requirement to be able to relate this time to wall clock time.
|
||||
|
||||
.. note::
|
||||
|
||||
The ANSI Library module, ``mpsliban.c``, calls ``clock``.
|
||||
|
||||
|
||||
.. c:function:: mps_clock_t mps_clocks_per_sec(void)
|
||||
|
||||
Return the number of clock units (as returned by
|
||||
:c:func:`mps_clock`) per second.
|
||||
|
||||
.. note::
|
||||
|
||||
The ANSI Library module, ``mpsliban.c``, returns
|
||||
``CLOCKS_PER_SEC``.
|
||||
|
||||
|
||||
.. c:function:: void mps_lib_assert_fail(const char *message)
|
||||
|
||||
Report an assertion failure and abort.
|
||||
|
||||
``message`` is a NUL-terminated string describing the assertion
|
||||
failure.
|
||||
|
||||
.. note::
|
||||
|
||||
In the ANSI Library module, ``mpsliban.c``, this reports the
|
||||
failure using ``fprintf(stderr, "...%s...", message)`` and
|
||||
terminates the program by calling ``abort``.
|
||||
|
||||
|
||||
.. c:type:: mps_lib_FILE
|
||||
|
||||
The type of output streams provided by the plinth.
|
||||
|
||||
.. note::
|
||||
|
||||
In the ANSI Library module, ``mpsliban.c``, this is an alias
|
||||
for ``FILE *``.
|
||||
|
||||
|
||||
.. c:function:: int mps_lib_fputc(int c, mps_lib_FILE *stream)
|
||||
|
||||
Write a character to an output stream.
|
||||
|
||||
``c`` is the character.
|
||||
|
||||
``stream`` is the stream.
|
||||
|
||||
Return the character written if successful, or
|
||||
:c:func:`mps_lib_get_EOF` if not.
|
||||
|
||||
This function is intended to have the same semantics as the
|
||||
``fputc`` function of the ANSI C Standard ([ISO90]_ §7.11.7.3).
|
||||
|
||||
.. note::
|
||||
|
||||
In the ANSI Library module, ``mpsliban.c``, this is a simple
|
||||
wrapper around ``fputc``.
|
||||
|
||||
|
||||
.. c:function:: int mps_lib_fputs(const char *s, mps_lib_FILE *stream)
|
||||
|
||||
Write a string to an output stream.
|
||||
|
||||
``s`` is the NUL-terminated string.
|
||||
|
||||
``stream`` is the stream.
|
||||
|
||||
This function is intended to have the same semantics as the
|
||||
``fputs`` function of the ANSI C Standard ([ISO90]_ §7.11.7.4).
|
||||
|
||||
Return a non-negative integer if successful, or
|
||||
:c:func:`mps_lib_get_EOF` if not.
|
||||
|
||||
.. note::
|
||||
|
||||
In the ANSI Library module, ``mpsliban.c``, this is a simple
|
||||
wrapper around ``fputs``.
|
||||
|
||||
|
||||
.. c:function:: int mps_lib_get_EOF(void)
|
||||
|
||||
Return the value that is returned from :c:func:`mps_lib_fputc` and
|
||||
:c:func:`mps_lib_fputs` to indicate failure.
|
||||
|
||||
.. note::
|
||||
|
||||
In the ANSI Library module, ``mpsliban.c``, this returns
|
||||
``EOF``.
|
||||
|
||||
|
||||
.. c:function:: mps_lib_FILE *mps_lib_get_stderr(void)
|
||||
|
||||
Returns an output stream suitable for reporting errors.
|
||||
|
||||
.. note::
|
||||
|
||||
In the ANSI Library module, ``mpsliban.c``, this returns
|
||||
``stderr``.
|
||||
|
||||
|
||||
.. c:function:: mps_lib_FILE *mps_lib_get_stdout(void)
|
||||
|
||||
Returns an output stream suitable for reporting informative
|
||||
output.
|
||||
|
||||
.. note::
|
||||
|
||||
In the ANSI Library module, ``mpsliban.c``, this returns
|
||||
``stdout``.
|
||||
|
||||
Declared in ``mpslib.h``
|
||||
------------------------
|
||||
|
||||
.. c:function:: int mps_lib_memcmp(const void *s1, const void *s2, size_t n)
|
||||
|
||||
|
|
@ -143,7 +301,12 @@ Declared in ``mpslib.h``
|
|||
equal to, or less than the block pointed to by ``s2``.
|
||||
|
||||
This function is intended to have the same semantics as the
|
||||
``memcmp`` function of the [ANSI C Standard]_ (section 7.11.4.1).
|
||||
``memcmp`` function of the ANSI C Standard ([ISO90]_ §7.11.4.1).
|
||||
|
||||
.. note::
|
||||
|
||||
In the ANSI Library module, ``mpsliban.c``, this is a simple
|
||||
wrapper around ``memcmp``.
|
||||
|
||||
|
||||
.. c:function:: void *mps_lib_memcpy(void *dest, const void *source, size_t n)
|
||||
|
|
@ -160,11 +323,17 @@ Declared in ``mpslib.h``
|
|||
Returns ``dest``.
|
||||
|
||||
This function is intended to have the same semantics as the
|
||||
``memcpy`` function of the [ANSI C Standard]_ (section 7.11.2.1).
|
||||
``memcpy`` function of the ANSI C Standard ([ISO90]_ §7.11.2.1).
|
||||
|
||||
The MPS never passes overlapping blocks to
|
||||
:c:func:`mps_lib_memcpy`.
|
||||
|
||||
.. note::
|
||||
|
||||
In the ANSI Library module, ``mpsliban.c``, this is a simple
|
||||
wrapper around ``memcpy``.
|
||||
|
||||
|
||||
.. c:function:: void *mps_lib_memset(void *s, int c, size_t n)
|
||||
|
||||
A :term:`plinth` function similar to the standard :term:`C`
|
||||
|
|
@ -179,7 +348,12 @@ Declared in ``mpslib.h``
|
|||
Returns ``s``.
|
||||
|
||||
This function is intended to have the same semantics as the
|
||||
``memset`` function of the [ANSI C Standard]_ (section 7.11.6.1).
|
||||
``memset`` function of the ANSI C Standard ([ISO90]_ §7.11.6.1).
|
||||
|
||||
.. note::
|
||||
|
||||
In the ANSI Library module, ``mpsliban.c``, this is a simple
|
||||
wrapper around ``memset``.
|
||||
|
||||
|
||||
.. c:function:: unsigned long mps_lib_telemetry_control()
|
||||
|
|
@ -192,29 +366,12 @@ Declared in ``mpslib.h``
|
|||
Returns the default value of the telemetry filter, as derived from
|
||||
the environment. It is recommended that the environment be
|
||||
consulted for a symbol analogous to
|
||||
:c:macro:`MPS_TELEMETRY_CONTROL`, subject to local restrictions.
|
||||
:envvar:`MPS_TELEMETRY_CONTROL`, subject to local restrictions.
|
||||
|
||||
In the absence of environmental data, a default of zero is
|
||||
recommended.
|
||||
|
||||
.. note::
|
||||
|
||||
Undocumented in ``mpslib.h``
|
||||
----------------------------
|
||||
|
||||
.. c:function:: int mps_lib_get_EOF(void)
|
||||
.. c:type:: mps_lib_FILE
|
||||
.. c:function:: mps_lib_FILE *mps_lib_get_stderr(void)
|
||||
.. c:function:: mps_lib_FILE *mps_lib_get_stdout(void)
|
||||
.. c:function:: int mps_lib_fputc(int c, mps_lib_FILE *stream)
|
||||
.. c:function:: int mps_lib_fputs(const char *s, mps_lib_FILE *stream)
|
||||
.. c:function:: void mps_lib_assert_fail(const char *message)
|
||||
.. c:function:: mps_clock_t mps_clock(void)
|
||||
.. c:type:: mps_clock_t
|
||||
.. c:function:: mps_clock_t mps_clocks_per_sec(void)
|
||||
|
||||
|
||||
Undocumented in ``mpsw3.h``
|
||||
---------------------------
|
||||
|
||||
.. c:function:: LONG mps_SEH_filter(LPEXCEPTION_POINTERS info, void **hp_o, size_t *hs_o)
|
||||
.. c:function:: void mps_SEH_handler(void *p, size_t s)
|
||||
In the ANSI Library module, ``mpsliban.c``, this reads the
|
||||
environment variable :envvar:`MPS_TELEMETRY_CONTROL`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue