1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-30 12:21:25 -08:00

Converting design.mps.config to restructuredtext. rewriting, correcting, clarifying, and generally bringing it up-to-date.

Removing misplaced obsolete design text from mpstd.h.
Tidying up the format of a couple of other docs.

Copied from Perforce
 Change: 181717
 ServerID: perforce.ravenbrook.com
This commit is contained in:
Richard Brooksby 2013-05-11 17:52:01 +01:00
parent 9f81b9b8a0
commit 2f79ef3b9e
6 changed files with 640 additions and 600 deletions

View file

@ -9,51 +9,22 @@
* documentation, or, in the case of GCC, from the compiler itself.
* References to the documentation appear above each detection line.
*
* For more details on how this file fits into the MPS build system,
* and an explanation of all the MPS_* defines, see design.config.pf
* "MPS Configuration" <../design/config.txt>
*
* .macos.ppc.align: MacOS / PowerPC requires 8 bytes alignment (in
* general). See "Mac OS Runtime Architecture", table 4-2.
*/
#ifndef mpstd_h
#define mpstd_h
/* DESIGN NOTES
* ------------
* [These should be moved to a proper buildsys design doc. RHSK]
*
* mpstd.h does two main things:
* 1. platform detection by looking at preprocessor symbols;
* 2. setting variables (eg. MPS_PF_STRING, MPS_WORD_WIDTH).
*
* Sometimes the platform is *already* known by the buildsystem:
* - the Global Graphics buildsystem always sets CONFIG_PF_*.
* - the Ravenbrook buildsystem knows the platform and may (but
* typically does not) set CONFIG_PF_*.
*
* Regardless of this, mpstd.h still attempts to detect the platform.
* (This is intentional). However if both CONFIG_PF_* and
* CONFIG_PF_STRING are set, then mpstd.h performs a third function:
* 3. checking that the detected platform corresponds to that
* specified by CONFIG_PF_*.
*
* Sometimes no MPS buildsystem is in use, so the platform *must*
* be detected. For example, when client software #includes mps.h,
* we want it to just work out of the box with whatever compiler is
* being used. In other words we do not require the client to define
* CONFIG_PF_*.
* (This is the case that justifies mpstd.h doing platform detection
* by looking at preprocessor symbols; otherwise we'd simply use
* CONFIG_PF_*).
*
* mpstd.h fails if it cannot detect the platform (even if CONFIG_PF_*
* is specified). This is intentional. mpstd.h does *not* allow
* CONFIG_PF_* to override the platform as detected from preprocessor
* symbols. This is intentional.
*
* References:
* GG buildsys use of CONFIG_PF_*:
* <http://info.ravenbrook.com/mail/2005/03/01/15-45-17/0.txt>
* symbols. This is intentional. [This needs justifying. RB 2013-05-11]
*/
#ifndef mpstd_h
#define mpstd_h
/* Visual C++ 2.0, Books Online, C/C++ Book, Preprocessor Reference,
* Chapter 1: The Preprocessor, Macros, Predefined Macros.

606
mps/design/config.txt Normal file
View file

@ -0,0 +1,606 @@
MPS Configuration
=================
:Tag: design.mps.config
:Author: Richard Brooksby
:Date: 1997-02-19
:Status: incomplete design
:Revision: $Id$
:Copyright: See section `C. Copyright and License`_.
Introduction
------------
_`.intro`: This document describes how the `Memory Pool System
<http://www.ravenbrook.com/project/mps/>`_ source code is configured so
that it can target different architectures, operating systems, build
environments, varieties, and products.
Requirements
------------
_`.req.import`: The MPS must be simple to include in third-party projects.
_`.req.arch`: Allow architecture specific configurations of the MPS, so
that we can vary the MPS according to the target architecture.
_`.req.os`: Allow operating system specific configurations of the MPS,
so that we can vary the MPS according to the target OS.
_`.req.builder`: Allow build environment specific configurations of the
MPS, so that we can vary the MPS according to the compiler, etc.
_`.req.var`: Allow configurations with different amounts of
instrumentation (assertions, metering, etc.).
_`.req.impact`: The configuration system should have a minimal effect on
maintainability of the implementation.
_`.req.port`: The system should be easy to port across platforms.
_`.req.maint`: Maintenance of the configuration and build system should
not consume much developer time.
Retired requirements
....................
_`.req.prod`: Allow product specific configurations of the MPS, so that
we can build variants of the MPS for use in different products. This
requirement has been retired on 2012-09-03 as part of work on the
variety-reform_ branch. Client-specific customisation of the MPS will
be handled in source control, while the MPS source remains generic, to
reduce costs and increase reliability. See [RB_2012-09-13]_.
Definitions
-----------
_`.def.platform`: A *platform* is a combination of an architecture
(.def.arch_), an operating system (.def.os_), and a builder
(`.def.builder`_). The set of supported platforms is maintained in the
`Platforms section of "Building the Memory Pool System"
<../manual/html/guide/build.html#platforms>`_.
_`.def.arch`: An *architecture* is processor type with associated calling
conventions and other binary interface stuff these days often called the
`ABI <http://en.wikipedia.org/wiki/Application_binary_interface>`_.
Most importantly for the MPS it determines the layout of the register
file, thread context, and thread stack.
_`.def.os`: An *operating system* is the interface to external resources.
Most importantly for the MPS it determines the low level interface to
virtual memory (if any) and threading.
_`.def.builder`: A *builder* is the tools (C compiler, etc.) used to make
the target (.def.target). The MPS minimises use of compiler-specific
extensions, but this is handy for suppressing warnings, inlining hints,
etc.
_`.def.var`: A *variety* determines things like the amount of debugging,
internal consistency checking, annotation, etc. In modern IDEs this
called a "build configuration" and the usual default is to have two:
"debug" and "release". The MPS predates this convention, but the concept
is the same.
_`.def.prod`: A *product* is the intended product into which the MPS will
fit, e.g. ScriptWorks, Dylan, etc. We no longer maintain this concept
as a dimension of configuration since .req.prod_ has been retired.
_`.def.target`: The *target* is the result of the build.
Overview
--------
_`.import.source`: The MPS can be simply included in client products as
source code. Since `version 1.110`_ we made it possible to simply
include the file ``mps.c`` in a client's build process, without
requiring a separate build of the MPS or linking a library. This is
described `section 2.3.1, "Compiling for production" of the MPS manual
<../manual/html/guide/build.html#compiling-for-production>`_.
.. _`version 1.110`: http://www.ravenbrook.com/project/mps/version/1.110/
_`.no-gen`: No generated code or external tools are required. On most
platforms the only tool is the C compiler. On 64-bit Windows we require
the assembler since Microsoft withdrew in-line assembler from their C
compiler.
_`.no-spaghetti`: Several of the MPS team have worked on some extremely
messy code bases which used a great number of ``#ifdef`` statements.
These quickly became very expensive to maintain and develop. The
general rule in the MPS is "no ``#ifdefs``". Instead, platform-specific
code is kept in separate source files and selected by carefully controlled
``#ifdefs``, such as in `mps.c <../code/mps.c>`_.
_`.min-dep`: Dependency on a particular configuration should be
minimized and localized when developing code. This is enshrined in the
general rules for implementation [ref?] that are enforced by MPS
development procedures including code review and inspection.
The Build System
----------------
Abstract Build Function
.......................
_`.build.fun`: The MPS implementation assumes only a simple "build
function" that takes a set of sources, possibly in several languages,
compiles them with a set of predefined preprocessor symbols, and links
the result with a set of libraries to form the target::
target := build(<defs>, <srcs>, <libs>)
_`.build.sep`: Separate compilation and linkage can be seen as a
memoization of this function, and is not strictly necessary for the
build. Indeed, since `version 1.110` we found that modern compilers are
quite happy to compile the whole MPS in one go `.import.source`_.
_`.build.cc`: A consequence of this approach is that it should always be possible
to build a complete target with a single UNIX command line calling the compiler
driver (usually "cc" or "gcc"), for example::
cc -o main -DCONFIG_VAR_DF foo.c bar.c baz.s -lz
_`.build.defs`: The "defs" are the set of preprocessor macros which are to be
predefined when compiling the module sources::
CONFIG_VAR_<variety-code>
The variety-codes are the letter code that appears after "variety." in
the tag of the relevant variety document (see variety.*) converted to
upper case. Currently (2012-09-03):
_`.var.hot`: ``HOT``
Intended for release in products. Optimised, reduced internal
checking, especially on the `critical path <critical-path.txt>`_
[RB_2012-09-07]_.
_`.var.cool`: ``COOL``
Intended for use during development. Moderately thorough internal
consistency checking. Reduced optimisation to allow for
single-stepping.
_`.var.rash`: ``RASH``
No internal checking at all. Slight performance improvement over
`.var.hot`_ at the cost of early detection of memory management
bugs. We do not advise use of this variety, as memory management
bugs tend to be extremely expensive to deal with.
_`.var.diag`: ``DIAG`` (deprecated)
This variety does some client-specific analysis and produces some
specialised diagnostic output, and is not intended for general use.
It will be phased out of the open sources.
_`.default.hot`: If no ``CONFIG_VAR`` is present, ``HOT`` is assumed in
`config.h`_.
_`.build.srcs`: The "srcs" are the set of sources that must be compiled in order
to build the target. The set of sources may vary depending on the
configuration. For example, different sets of sources may be required to build
different architectures. [This is a dependency between the makefile (or whatever)
and the module configuration in `config.h`_.]
_`.build.libs`: The "libs" are the set of libraries to which the compiled sources
must be linked in order to build the target. For example, when building a test
program, it might include the ANSI C library and an operating system interface
library.
File Structure
..............
_`.file.dir`: The MPS source code is arranged in a single directory
called "code" containing all the sources for the whole family of
targets.
_`.file.base`: The names of sources must be unique in the first eight
characters in order to conform to FAT filesystem naming restrictions.
(Do not scoff -- this has been an important requirement as recently as
2012!)
_`.file.ext`: The extension may be up to three characters and directly
indicates the source language.
_`.file.platform`: Platform-specific files include the platform code
in their name. See `.mod.impls`_.
Modules and Naming
..................
_`.mod.unique`: Each module has an identifier which is unique within the MPS.
_`.mod.impls`: Each module has one or more implementations which may be
in any language supported by the relevant build environment.
_`.mod.primary`: The primary implementation of a module is written in
target-independent ANSI C in a source file with the same name as the
module. _`.mod.an`: Where there are platform-specific implementations
and an inferior portable ANSI C fallback implementation, "an" is used in
place of the platform code. _`.mod.secondary`: The names of other
implementations should begin with the same prefix (the module id or a
shortened version of it) and be suffixed with on or more target
parameter codes (defined below). In particular, the names of assembly
language sources must include the target parameter code for the relevant
architecture.
_`.mod.example`: For example, the stack scanner is defined in `ss.h
<../code/ss.h>`_ (which is platform-independent). It has some
platform-independent C in `ss.c <../code/ss.c>`_ and, for example,
`ssw3i6mv.c <../code/ssw3i6mv.c>`_ is specific to Windows on the x64
architecture built with Microsoft Visual C.
Build System Rationale
......................
_`.build.rat`: This simple design makes it possible to build the MPS
using many different tools. Microsoft Visual C and other graphical
development tools do not support much in the way of generated sources,
staged building, or other such stuff. The Visual C and Xcode "project"
files correspond closely to a closure of the build function
(`.build.fun`_). The simplicity of the build function has also made it
easy to set up builds using NMAKE (DOS), MPW (Macintosh), and to get the
MPS up and running on other platforms such as FreeBSD and Linux in very
little time. The cost of maintaining the build systems on these various
platforms is also reduced to a minimum, allowing the MPS developers to
concentrate on primary development. The source code is kept simple and
straightforward. When looking at MPS sources you can tell exactly what
is going to be generated with very little context. The sources are not
munged beyond the standard ANSI C preprocessor.
_`.build.port`: The portability requirement (`.req.port`_) implies that
the build system must use only standard tools that will be available on
all conceivable target platforms. Experience of development
environments on the Macintosh (Metrowerks Codewarrior) and Windows NT
(Visual C++) indicates that we cannot assume much sophistication in the
use of file structure by development environments. The best that we can
hope for is the ability to combine a fixed list of source files,
libraries, and predefined preprocessor symbols into a single target.
_`.build.maint`: The maintainability requirement (`.req.maint`_) implies
that we don't spend time trying to develop a set of tools to support
anything more complicated than the simple build function described
above. The effort in constructing and maintaining a portable system of
this kind is considerable. Such efforts failed in the Electronic
Publishing division of Harlequin.
Implementation
--------------
[ Now in impl.h.config, may symbols out of date. GavinM 1997-08-07 ]
_`.impl`: The two implementation files `config.h`_ and `mpstd.h`_ can be
seen as preprocessor programs which "accept" build parameters and "emit"
configuration parameters (`.fig.impl`_). The build parameters are
defined either by the builder (in the case of target detection) or by
the build function (in the case of selecting the variety).
_`.fig.impl`::
build parameters configuration parameters
CONFIG_VAR_DF --> config.h --> MPS_VAR_DF, ASSERT_MPM, etc.
_WIN32 --> mpstd.h --> MPS_OS_W3, etc.
_`.impl.dep`: No source code, other than the directives in `config.h`_
and `mpstd.h`_, should depend on any build parameters. That is,
identifers beginning "CONFIG\_" should only appear in impl.h.config.
Code may depend on configuration parameters in certain, limited ways, as
defined below (`.conf`_).
.. _`config.h`: <../code/config.h>
.. _`mpstd.h`: <../code/mpstd.h>
Target Platform Detection
.........................
_`.pf`: The target platform is "detected" by the preprocessor directives in
`mpstd.h`_.
_`.pf.form`: This file consists of sets of directives of the form::
#elif <conjunction of builder predefinitions>
#define MPS_PF_<platform code>
#define MPS_OS_<operating system code>
#define MPS_ARCH_<architecture code>
#define MPS_BUILD_<builder code>
#define MPS_T_WORD <word type>
#define MPS_T_ULONGEST <longest unsigned integer type>
#define MPS_WORD_SHIFT <word shift>
#define MPS_PF_ALIGN <minimum alignment>
_`.pf.detect`: The conjunction of builder predefinitions is a constant
expression which detects the target platform. It is a logical AND of
expressions which look for preprocessor symbols defined by the build
environment to indicate the target. These must be accompanied by a
reference to the build tool documentation from which the symbols came.
For example::
/* "Predefined Macros" from "Visual Studio 2010" on MSDN
* <http://msdn.microsoft.com/en-us/library/b0084kay(v=vs.100).aspx>. */
#elif defined(_MSC_VER) && defined(_WIN32) && defined(_M_IX86)
_`.pf.codes`: The declarations of the platform, operating system,
architecture, and builder codes define preprocessor macros corresponding
the the target detected (`.pf.detect`_). For example::
#define MPS_PF_W3I3MV
#define MPS_OS_W3
#define MPS_ARCH_I3
#define MPS_BUILD_MV
_`.pf.word`: The declaration of ``MPS_T_WORD`` defines the unsigned
integral type which corresponds, on the detected target, to the machine
word. It is used to defined the MPS Word type (design.mps.type.word).
[Insert backwards ref there.] (We avoid using ``typedef`` here because
`mpstd.h`_ could potentially be included in assembly language source
code.) For example::
#define MPS_T_WORD unsigned long
_`.pf.word-width`: The declaration of ``MPS_WORD_WIDTH`` defines the
number of bits in the type defined by `MPS_T_WORD` (`.pf.word`_) on the
target. For example::
#define MPS_WORD_WIDTH 32
_`.pf.word-shift`: The declaration of ``MPS_WORD_SHIFT`` defines the log
to the base 2 of ``MPS_WORD_WIDTH``. For example::
#define MPS_WORD_SHIFT 5
_`.pf.pf-align`: The declaration of ``MPS_PF_ALIGN`` defines the minimum
alignment which must be used for a memory block to permit any normal
processor memory access. In other words, it is the maximum alignment
required by the processor for normal memory access. For example::
#define MPS_PF_ALIGN 4
_`.pf.ulongest`: The declaration of ``MPS_T_ULONGEST`` defines the
longest available unsigned integer type on the platform. This is
usually just ``unsigned long`` but under Microsoft C on 64-bit Windows
``unsigned long`` is just 32-bits (curse them!) For example::
#define MPS_T_ULONGEST unsigned __int64
_`.pf.pf-string`: The declaration of ``MPS_PF_STRING`` defines a string
that is used to identify the target platform in `version.c
<../code/version.c>`_. For example::
#define MPS_PF_STRING "w3i6mv"
Target Varieties
................
_`.var`: The target variety is handled by preprocessor directives in
impl.h.config. _`.var.form`: The file contains sets of directives of
the form::
#elif defined(CONFIG_VAR_DF)
#define MPS_VAR_DF
#define ASSERT_MPSI
#define ASSERT_MPM
etc.
_`.var.detect`: The configured variety is one of the variety
preprocessor definitions passed to the build function (`.build.defs`_),
e.g. ``CONFIG_VAR_HOT``. These are decoupled so that it's possible to
tell the difference between overridden settings etc. [Explain.]
_`.var.symbols`: The directives should define whatever symbols are
necessary to control annotations. These symbols parameterize other
parts of the code, such as the declaration of assertions, etc. The
symbols should all begin with the prefix ``MPS_VAR\_``.
[Tidy this up:]
Note, anything which can be configured, is configured, even if it's just
configured to "NONE" meaning nothing. This makes sure that you can't
choose something by omission. Where these symbols are used there will
be a #error to catch the unused case. Exception: To allow simple
building of the MPS with "cc -c mps.c" we choose CONFIG_VAR_HOT by
default.
[This is a general principle which applies to other configuration stuff too.]
Source Code Configuration
-------------------------
_`.conf`: This section describes how the configuration may affect the
source code of the MPS.
_`.conf.limit`: The form of dependency allowed is carefully limited to
ensure that code remains maintainable and portable (`.req.impact`_).
_`.conf.min`: The dependency of code on configuration parameters should
be kept to a minimum in order to keep the system maintainable
(`.req.impact`_).
Configuration Parameters
........................
_`.conf.params`: The compilation of a module is parameterized by::
MPS_ARCH_<arch-code>
MPS_OS_<os-code>
MPS_BUILDER_<builder-code>
MPS_PF_<platform-code>
Abstract and Concrete Module Interfaces
.......................................
_`.abs.caller`: Basic principle: the caller musn't be affected by
configuration of a module. This reduces complexity and dependency of
configuration. All callers use the same abstract interface. Caller
code does not change.
_`.abs.interface`: Abstract interface includes:
- method definitions (logical function prototypes which may be macro methods)
- names of types
- names of constants
- names of structures and fields which form part of the interface, and
possibly their types, depending on the protocol defined
- the protocols
_`.abs.rule`: The abstract interface to a module may not be altered by a
configuration parameter. However, the concrete interface may vary.
For example, this isn't allowed, because there is a change in the interface::
#if defined(PROT_FOO)
void ProtSpong(Foo foo, Bar bar);
#else
int ProtSpong(Bar bar, Foo foo);
#endif
This example shows how::
#ifdef PROTECTION
void ProtSync(Space space);
/* more decls. */
#else /* PROTECTION not */
#define ProtSync(space) NOOP
/* more decls. */
#endif /* PROTECTION */
or::
#if defined(PROT_FOO)
typedef struct ProtStruct {
int foo;
} ProtStruct;
#define ProtSpong(prot) X((prot)->foo)
#elif defined(PROT_BAR)
typedef struct ProtStruct {
float bar;
} ProtStruct;
#define ProtSpong(prot) Y((prot)->bar)
#else
#error "No PROT_* configured."
#endif
Configuration parameters may not be used to vary implementations in C files.
For example, this sort of thing::
int map(void *base, size_t size)
{
#if defined(MPS_OS_W3)
VirtualAlloc(foo, bar, base, size);
#elif defined(MPS_OS_SU)
mmap(base, size, frob);
#else
#error "No implementation of map."
#endif
}
This violates `.no-spaghetti`_.
To document
-----------
- What about constants in config.h?
- Update files to refer to this design document.
- Explain the role of ``mps.c``
- Reference to ``build.txt``
- Procedures for adding an architecture, etc.
- Reduce duplication in this document (especially after
`Configuration Parameters`_ which looks like it's been pasted in from
elsewhere.)
A. References
-------------
.. [MPS_Manual] "Memory Pool System documentation"; Ravenbrook Limited;
<http://www.ravenbrook.com/project/mps/master/manual/html/>.
.. [RB_2012-09-07] "The critical path through the MPS"; `Richard Brooksby <RB>`_;
Ravenbrook Limited; 2012-09-07;
<http://www.ravenbrook.com/project/mps/master/design/critical-path>.
.. [RB_2012-09-13] "The Configura CET custom mainline"; `Richard
Brooksby <RB>`_; Ravenbrook Limited; 2013-09-13;
<https://info.ravenbrook.com/mail/2012/09/13/16-43-35/0/>.
.. [PP_2005-03-01] "MPS platforms"; Pekka Pirinen; Global Graphics;
<https://info.ravenbrook.com/mail/2005/03/01/15-45-17/0.txt>.
B. Document History
-------------------
- 1997-02-19 RB_ Initial draft based on discussions of configuration at
meeting.general.1997-02-05.
- 1997-02-20? RB_ Various improvements and clarifications to the draft
discussed between RB_ and NB_ at meeting.general.1997-02-19.
- 2002-06-07 RB_ Converted from MMInfo database design document.
- 2012-09-03 RB_ Updated for variety-reform_ branch, to remove untrue
things, though the document could do with a rewrite.
- 2013-05-11 RB_ Converted to reStructuredText. Clarified various
sections, brought some up-to-date, and removed obsolete junk.
.. _variety-reform: http://www.ravenbrook.com/project/mps/branch/2012-08-15/variety-reform/
.. _RB: http://www.ravenbrook.com/consultants/rb/
.. _NB: http://www.ravenbrook.com/consultants/nb/
C. Copyright and License
------------------------
Copyright (C) 2013 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:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. 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.
3. 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.**

View file

@ -1,537 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>The design of MPS configuration</title>
</head>
<body bgcolor="#FFFFFF" text="#000000" link="#000099" vlink="#660066" alink="#FF0000">
<div align="center">
<p>
<a href="/">Ravenbrook</a> /
<a href="/project/">Projects</a> /
<a href="/project/mps/">Memory Pool System</a> /
<a href="/project/mps/master/">Master Product Sources</a> /
<a href="/project/mps/master/design/">Design Documents</a>
</p>
<p><i><a href="/project/mps/">Memory Pool System Project</a></i></p>
<hr />
</div>
<pre>
THE DESIGN OF MPS CONFIGURATION
design.mps.config
incomplete design
richard 1997-02-19
INTRODUCTION
<a id="intro" name="intro">.intro</a>: This document describes how the MPS configuration is parameterized so
that it can target different architectures, operating systems, build
environments, varieties, and products.
<a id="bg" name="bg">.bg</a>: For background see [build system mail, configuration mail,
meeting.general.something]
Document History
<a id="hist.0" name="hist.0">.hist.0</a>: Initial draft created by Richard Brooksby &lt;richard&gt; on 1997-02-19
based on discussions of configuration at meeting.general.1997-02-05.
<a id="hist.1" name="hist.1">.hist.1</a>: Various improvements and clarifications to the draft discussed between
Richard and Nick Barnes &lt;nickb&gt; at meeting.general.1997-02-19.
REQUIREMENTS
<a id="req.arch" name="req.arch">.req.arch</a>: Allow architecture specific configurations of the MPS.
<a id="req.os" name="req.os">.req.os</a>: Allow operating system specific configurations of the MPS.
<a id="req.builder" name="req.builder">.req.builder</a>: Allow build environment (compiler, etc.) specific configurations
of the MPS.
<a id="req.prod" name="req.prod">.req.prod</a>: Allow product specific
configurations of the MPS. [This requirement has been retired on
2012-09-03. Client-specific customisation of the MPS will be handled by
configuration management, while the MPS source remains generic, to
reduce costs and increase reliability. RB 2012-09-03]
<a id="req.var" name="req.var">.req.var</a>: Allow configurations with different amounts of instrumentation
(assertions, metering, etc.).
<a id="req.impact" name="req.impact">.req.impact</a>: The configuration system should have a minimal effect on
maintainability of the implementation.
<a id="req.port" name="req.port">.req.port</a>: The system should be easy to port across operating systems.
<a id="req.maint" name="req.maint">.req.maint</a>: Maintenance of the configuration and build system should not
consume much developer time.
DEFINITIONS
<a id="def.platform" name="def.platform">.def.platform</a>: A platform is a combination of an architecture (.def.arch), an
operating system (.def.os), and a builder (.def.builder). The set of supported
platforms is platform.*.
<a id="def.arch" name="def.arch">.def.arch</a>: An architecture is processor type with associated calling
conventions and other binary interface stuff.
<a id="def.os" name="def.os">.def.os</a>: An operating system is the interface to external resources.
<a id="def.builder" name="def.builder">.def.builder</a>: A builder is the tools (C compiler, etc.) used to make the target
(.def.target).
<a id="def.var" name="def.var">.def.var</a>: A variety is a combination of annotations such as assertions,
metering, etc.
<a id="def.prod" name="def.prod">.def.prod</a>: A product is the intended product into which the MPS will fit, e.g.
ScriptWorks, Dylan, etc.
<a id="def.target" name="def.target">.def.target</a>: The target is the result of the build.
OVERVIEW
- No automatically generated code. Use only C compiler and linker.
- Simple build function (design.mps.buildsys.????)
- Avoid conditional code spaghetti in implementations.
- Dependency on a particular configuration should be minimized and localized
when developing code.
THE BUILD SYSTEM
Abstract Build Function
<a id="build.fun" name="build.fun">.build.fun</a>: The MPS implementation assumes only a simple "build function" which
takes a set of sources, possibly in several languages, compiles them with a set
of predefined preprocessor symbols, and links the result with a set of
libraries to form the target:
target := build(&lt;defs&gt;, &lt;srcs&gt;, &lt;libs&gt;)
<a id="build.sep" name="build.sep">.build.sep</a>: Separate compilation and linkage can be seen as a memoization of
this function, and is not strictly necessary for the build.
<a id="build.cc" name="build.cc">.build.cc</a>: A consequence of this approach is that it should always be possible
to build a complete target with a single UNIX command line calling the compiler
driver (usually "cc" or "gcc"), for example:
cc -o main -DCONFIG_VAR_DF foo.c bar.c baz.s -lz
<a id="build.defs" name="build.defs">.build.defs</a>: The "defs" are the set of preprocessor macros which are to be
predefined when compiling the module sources.
CONFIG_VAR_&lt;variety-code&gt;
The variety-codes are the letter code that appears after "variety." in the
tag of the relevant variety document (see variety.*) converted to upper case.
Currently (2012-09-03): RASH, HOT, COOL, DIAG, TI
If no CONFIG_VAR is present, HOT is assumed in <code/config.h>.
<a id="build.srcs" name="build.srcs">.build.srcs</a>: The "srcs" are the set of sources that must be compiled in order
to build the target. The set of sources may vary depending on the
configuration. For example, different sets of sources may be required to build
on different architectures. [This is a dependency between the makefile (or whatever)
and the module configuration in config.h.]
<a id="build.libs" name="build.libs">.build.libs</a>: The "libs" are the set of libraries to which the compiled sources
must be linked in order to build the target. For example, when building a test
program, it might include the ANSI C library and an operating system interface
library.
File Structure
<a id="file.dir" name="file.dir">.file.dir</a>: Each product consists of a single directory (corresponding to a HOPE
compound) containing all the sources for the whole family of targets.
<a id="file.base" name="file.base">.file.base</a>: The names of sources must be unique in the first eight characters
in order to conform to FAT filesystem naming restrictions. <a id="file.ext" name="file.ext">.file.ext</a>: The
extension may be up to three characters and directly indicates the source
language.
[Where is the set of valid extensions and languages defined?]
Modules and Naming
<a id="mod.unique" name="mod.unique">.mod.unique</a>: Each module has an identifier which is unique within the MPS.
<a id="mod.impls" name="mod.impls">.mod.impls</a>: Each module has one or more implementations which may be in any
language supported by the relevant build environment. <a id="mod.primary" name="mod.primary">.mod.primary</a>: The
primary implementation of a module is written in target-independent ANSI C in a
source file with the same name as the module. [This seems to be with an "an"
suffix now. GavinM 1997-08-07] <a id="mod.secondary" name="mod.secondary">.mod.secondary</a>: The names of other
implementations should begin with the same prefix (the module id or a shortened
version of it) and be suffixed with on or more target parameter codes (defined
below). In particular, the names of assembly language sources must include the
target parameter code for the relevant architecture.
Build System Rationale
<a id="build.rat" name="build.rat">.build.rat</a>: This simple design makes it possible to build the MPS using many
different tools. Microsoft Visual C++, Metrowerks Codewarrior, and other
graphical development tools do not support much in the way of generated
sources, staged building, or other such stuff. The Visual C and Metrowerks
"project" files correspond closely to a closure of the build function
(.build.fun). The simplicity of the build function has also made it easy to
set up builds using NMAKE (DOS), MPW (Macintosh), and to get the MPS up and
running on other platforms such as FreeBSD and Linux in very little time. The
cost of maintaining the build systems on these various platforms is also
reduced to a minimum, allowing the MM Group to concentrate on primary
development. The source code is kept simple and straightforward. When looking
at MPS sources you can tell exactly what is going to be generated with very
little context. The sources are not munged beyond the standard ANSI C
preprocessor.
<a id="build.port" name="build.port">.build.port</a>: The portability requirement (.req.port) implies that the build
system must use only standard tools that will be available on all conceivable
target platforms. Experience of development environments on the Macintosh
(Metrowerks Codewarrior) and Windows NT (Visual C++) indicates that we cannot
assume much sophistication in the use of file structure by development
environments. The best that we can hope for is the ability to combine a fixed
list of source files, libraries, and predefined preprocessor symbols into a
single target.
<a id="build.maint" name="build.maint">.build.maint</a>: The maintainability requirement (.req.maint) implies that we
don't spend time trying to develop a set of tools to support anything more
complicated than the simple build function described above. The effort in
constructing and maintaining a portable system of this kind is considerable.
Such efforts have failed in EP.
IMPLEMENTATION
[ Now in impl.h.config, may symbols out of date. GavinM 1997-08-07 ]
<a id="impl" name="impl">.impl</a>: The two implementation files impl.h.config and impl.h.mpstd can be seen
as preprocessor programs which "accept" build parameters and "emit"
configuration parameters (.fig.impl). The build parameters are defined either
by the builder (in the case of target detection) or by the build function (in
the case of selecting the variety).
<a id="fig.impl" name="fig.impl">.fig.impl</a>:
build parameters configuration parameters
CONFIG_VAR_COOL --&gt; config.h --&gt; ASSERT_AND_CHECK, TELEMETRY, etc.
_WIN32 --&gt; mpstd.h --&gt; MPS_OS_W3, etc.
<a id="impl.dep" name="impl.dep">.impl.dep</a>: No source code, other than the directives in impl.h.config and
impl.h.mpstd, should depend on any build parameters. That is, identifiers
beginning "CONFIG_" should only appear in impl.h.config. Code may depend on
configuration parameters in certain, limited ways, as defined below (.conf).
Target Platform Detection
<a id="pf" name="pf">.pf</a>: The target platform is "detected" by the preprocessor directives in
impl.h.mpstd.
<a id="pf.form" name="pf.form">.pf.form</a>: This file consists of sets of directives of the form:
#elif &lt;conjunction of builder predefinitions&gt;
#define MPS_PF_&lt;platform code&gt;
#define MPS_OS_&lt;operating system code&gt;
#define MPS_ARCH_&lt;architecture code&gt;
#define MPS_BUILD_&lt;builder code&gt;
#define MPS_T_WORD &lt;word type&gt;
#define MPS_WORD_SHIFT &lt;word shift&gt;
#define MPS_PF_ALIGN &lt;minimum alignment&gt;
<a id="pf.detect" name="pf.detect">.pf.detect</a>: The conjunction of builder predefinitions is a constant expression
which detects the target platform. It is a logical AND of expressions which
look for preprocessor symbols defined by the build environment to indicate the
target. These must be accompanied by a reference to the build tool
documentation from which the symbols came. For example:
/* Visual C++ 2.0, Books Online, C/C++ Book, Preprocessor Reference, */
/* Chapter 1: The Preprocessor, Macros, Predefined
#elif defined(_MSC_VER) &amp;&amp; defined(_WIN32) &amp;&amp; defined(_M_IX86)
<a id="pf.codes" name="pf.codes">.pf.codes</a>: The declarations of the platform, operating system, architecture,
and builder codes define preprocessor macros corresponding the the target
detected (.pfm.detect). For example:
#define MPS_PF_W3I3MV
#define MPS_OS_W3
#define MPS_ARCH_I3
#define MPS_BUILD_MV
<a id="pf.word" name="pf.word">.pf.word</a>: The declaration of MPS_T_WORD defines the unsigned integral type
which corresponds, on the detected target, to the machine word. It is used to
defined the MPS Word type (design.mps.type.word). [Insert backwards ref
there.] For example:
#define MPS_T_WORD unsigned long
<a id="pf.word-width" name="pf.word-width">.pf.word-width</a>: The declaration of MPS_WORD_WIDTH defines the number of bits in
the type defined by MPS_T_WORD (.pf.word) on the target. For example:
#define MPS_WORD_WIDTH 32
<a id="pf.word-shift" name="pf.word-shift">.pf.word-shift</a>: The declaration of MPS_WORD_SHIFT defines the log to the base 2
of MPS_WORD_WIDTH. For example:
#define MPS_WORD_SHIFT 5
<a id="pf.pf-align" name="pf.pf-align">.pf.pf-align</a>: The declaration of MPS_PF_ALIGN defines the minimum alignment
which must be used for a memory block to permit any normal processor memory
access. In other words, it is the maximum alignment required by the processor
for normal memory access. For example:
#define MPS_PF_ALIGN 4
Target Varieties
<a id="var" name="var">.var</a>: The target variety is handled by preprocessor directives in
impl.h.config. <a id="var.form" name="var.form">.var.form</a>: The file contains sets of directives of the form:
#elif defined(CONFIG_VAR_DF)
#define MPS_VAR_DF
#define ASSERT_MPSI
#define ASSERT_MPM
etc.
<a id="var.detect" name="var.detect">.var.detect</a>: The configured variety is one of the variety preprocessor
definitions passed to the build function (.build.defs), e.g. CONFIG_VAR_DF.
[These are decoupled so that it's possible to tell the difference between
overridden settings etc. Explain.]
<a id="var.symbols" name="var.symbols">.var.symbols</a>: The directives should define whatever symbols are necessary to
control annotations. These symbols parameterize other parts of the code, such
as the declaration of assertions, etc. The symbols should all begin with the
prefix "MPS_VAR_".
[Tidy this up:]
Note, anything which can be configured, is configured, even if it's just
configured to "NONE" meaning nothing. This makes sure that you can't choose
something by omission. Where these symbols are used there will be a #error to
catch the unused case.
Exception: To allow simple building of the MPS with "cc -c mps.c" we choose
CONFIG_VAR_HOT by default.
[This is a general principle which applies to other configuration stuff too.]
SOURCE CODE CONFIGURATION
<a id="conf" name="conf">.conf</a>: This section describes how the configuration may affect the source code
of the MPS.
<a id="conf.limit" name="conf.limit">.conf.limit</a>: The form of dependency allowed is carefully limited to ensure that
code remains maintainable and portable (.req.impact).
<a id="conf.min" name="conf.min">.conf.min</a>: The dependency of code on configuration parameters should be kept to
a minimum in order to keep the system maintainable (.req.impact).
Configuration Parameters
<a id="conf.params" name="conf.params">.conf.params</a>: The compilation of a module is parameterized by:
MPS_ARCH_&lt;arch-code&gt;
MPS_OS_&lt;os-code&gt;
MPS_BUILDER_&lt;builder-code&gt;
MPS_PF_&lt;platform-code&gt;
Abstract and Concrete Module Interfaces
Basic principle: the caller must not be affected by configuration of a module.
This reduces complexity and dependency of configuration.
All callers use the same abstract interface. Caller code does not change.
Abstract interface includes:
- method definitions (logical function prototypes which may be macro methods)
- names of types
- names of constants
- names of structures and fields which form part of the interface, and
possibly their types, depending on the protocol defined
- the protocols
The abstract interface to a module may not be altered by a configuration
parameter. However, the concrete interface may vary.
Configuring Module Implementations
For example, this isn't allowed, because there is a change in the interface.
#if defined(PROT_FOO)
void ProtSpong(Foo foo, Bar bar);
#else
int ProtSpong(Bar bar, Foo foo);
#endif
This example shows how:
#ifdef PROTECTION
void ProtSync(Space space);
/* more decls. */
#else /* PROTECTION not */
#define ProtSync(space) NOOP
/* more decls. */
#endif /* PROTECTION */
or
#if defined(PROT_FOO)
typedef struct ProtStruct {
int foo;
} ProtStruct;
#define ProtSpong(prot) X((prot)-&gt;foo)
#elif defined(PROT_BAR)
typedef struct ProtStruct {
float bar;
} ProtStruct;
#define ProtSpong(prot) Y((prot)-&gt;bar)
#else
#error "No PROT_* configured."
#endif
Configuration parameters may not be used to vary implementations in .c files.
For example, this sort of thing:
int map(void *base, size_t size)
{
#if defined(MPS_OS_W3)
VirtualAlloc(foo, bar, base, size);
#elif defined(MPS_OS_SU)
mmap(base, size, frob);
#else
#error "No implementation of map."
#endif
}
This leads to extreme code spaghetti. In effect, it's a "candy machine
interface" on source code. This kind of thing should be done by having several
implementations of the same interface in separate source files. If this leads
to duplication of code then that code should be placed in a separate, common
module.
PROCEDURES
[Adding an architecture, etc.]
NOTES
What about constants?
To do:
- Renaming of some stuff.
- Introduce product selection.
- Change makefiles.
- Eliminate mpmconf.h by moving stuff to config.h.
- Update files to refer to this design document.
</pre>
<h2><a id="section-A" name="section-A">A. References</a></h2>
<!-- Template Entry
<table>
<tr valign="top">
<td>[<a id="ref-#REF#" name="ref-#REF#" href="#REF_URL#">#REF_NAME#</a>]</td>
<td>
"#REF_TITLE#";
#REF_AUTHOR#;
&lt;URL: <a href="#REF_URL#">#REF_URL#</a>&gt;;
#REF_DATE#.
</td>
</tr>
</table>
-->
<h2><a id="section-B" name="section-B">B. Document History</a></h2>
<table>
<tr valign="top">
<td>2002-06-07</td>
<td><a href="mailto:rb@ravenbrook.com">RB</a></td>
<td>Converted from MMInfo database design document.</td>
<td>2012-09-03</td>
<td><a href="mailto:rb@ravenbrook.com">RB</a></td>
<td>Updated for variety-reform branch, to remove untrue things, though the document could do with a rewrite.</td>
</tr>
</table>
<h2><a id="section-C" name="section-C">C. Copyright and License</a></h2>
<p> This document is copyright &copy; 1995-2002 <a href="http://www.ravenbrook.com/">Ravenbrook Limited</a>. All rights reserved. This is an open source license. Contact Ravenbrook for commercial licensing options. </p>
<p> Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: </p>
<ol>
<li> Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. </li>
<li> 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. </li>
<li> Redistributions in any form must be accompanied by information on how to obtain complete source code for the 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. </li>
</ol>
<p> <strong> 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. </strong> </p>
<hr />
<div align="center">
<p><code>$Id$</code></p>
<p>
<a href="/">Ravenbrook</a> /
<a href="/project/">Projects</a> /
<a href="/project/mps/">Memory Pool System</a> /
<a href="/project/mps/master/">Master Product Sources</a> /
<a href="/project/mps/master/design/">Design Documents</a>
</p>
</div>
</body>
</html>

View file

@ -111,22 +111,22 @@ modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
notice, this list of conditions and the following disclaimer.
2. 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.
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. 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.
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

View file

@ -129,7 +129,7 @@
<tr valign="top">
<td> <code><a href="config/">config/</a></code> </td>
<td> <code><a href="config">config/</a></code> </td>
<td> The design of MPS configuration </td>

View file

@ -124,7 +124,7 @@ Document History
Copyright and Licence
---------------------
Copyright (C) 2001-2012 Ravenbrook Limited. All rights reserved.
Copyright (C) 2001-2013 Ravenbrook Limited. All rights reserved.
<http://www.ravenbrook.com/>. This is an open source license. Contact
Ravenbrook for commercial licensing options.
@ -133,22 +133,22 @@ modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
notice, this list of conditions and the following disclaimer.
2. 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.
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. 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.
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