1
Fork 0
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:
Gareth Rees 2012-10-29 21:47:14 +00:00
parent bd355caff8
commit f6f55dba1d
7 changed files with 519 additions and 70 deletions

View 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

View file

@ -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/>`_.

View file

@ -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

View file

@ -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

View file

@ -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
--------

View file

@ -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

View file

@ -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`.