2. Generic modules

2.1. Introduction

.intro: This is the design of generic modules in the MPS.

.readership: Any MPS developer; anyone porting the MPS to a new platform.

.overview: Generic modules provide implementations of functional modules using only the features of the Standard C Library. These implementations are partially functional or non-functional, but provide a basis for ports of the MPS to new platforms.

.name: The name “ANSI” for the generic modules is historical: the C language was originally standardized by the American National Standards Institute, and so Standard C used to be known as “ANSI C”.

2.2. Requirements

.req.port: The MPS must be portable to new platforms. (Otherwise we can’t meet the needs of customers using new platforms.)

.req.port.rapid: The MPS should be portable to new platforms rapidly.

.req.port.rapid.expert: An expert MPS developer (who may be a novice on the new platform) should be able to get a minimally useful implementation of the MPS running on a new platform within a few hours.

.req.port.rapid.novice: A novice MPS developer (who is an expert on the new platform) should be able to get the MPS running on a new platform within a few days.

2.3. Design

.sol.modules: Features of the MPS which can benefit from platform-specific implementations are divided into functional modules, with clean interfaces to the MPS and to each other. See .mod for a list of these modules. (This helps meet .req.port by isolating the platform dependencies, and it helps meet .req.port.rapid because a porter can mix and match implementations, using existing implementations where possible.)

.sol.generic: Each functional module has a generic implementation using only features of the Standard C Library. (This helps meet .req.port.rapid because the MPS can be ported in stages, starting with the generic modules and porting the modules needed to meet the most urgent requirements. The generic implementations help meet .req.port.rapid.novice by providing clear and illustrative examples.)

.sol.fallback: The interfaces to the modules are designed to make it possible to implement .sol.generic. When a platform-specific feature is needed to meet performance (or other attribute) requirements, the interface also makes it possible to meet the functional requirements while missing the attribute requirements. See .sol.fallback.example for an example. (This helps meet .req.port.rapid by allowing the generic implementations to meet many or most of the functional requirements.)

.sol.fallback.example: The MPS normally uses incremental collection to meet requirements on pause times, but this requires barriers. The interface to the protection module is designed to make it possible to write an implementation without barriers, via the function ProtSync() that synchronizes the mutator with the collector.

.sol.test: There are makefiles for the pseudo-platforms anangc, ananll and ananmv that compile and test the generic implementations. See design.mps.config.opt for the configuration options used to implement these platforms. (This supports .req.port.rapid by making sure that the generic implementations are working when it is time to use them.)

2.4. Modules

.mod: This section lists the functional modules in the MPS.

.mod.lock: Locks. See design.mps.lock.

.mod.prmc: Mutator context. See design.mps.prmc.

.mod.prot: Memory protection. See design.mps.prot.

.mod.sp: Stack probe. See design.mps.sp.

.mod.ss: Stack scanning. See design.mps.stack-scan.

.mod.th: Thread manager. See design.mps.thread-manager.

.mod.vm: Virtual mapping. See design.mps.vm.

2.5. Limitations of generic implementations

.lim: This section summarizes the limitations of the generic implementations of the function modules.

.lim.lock: Requires a single-threaded mutator (see design.mps.lock.impl.an).

.lim.prmc: Does not support single-stepping of accesses (see design.mps.prmc.impl.an.fault) and requires a single-threaded mutator (see design.mps.prmc.impl.an.suspend).

.lim.prot: Does not support incremental collection (see design.mps.prot.impl.an.sync) and is not compatible with implementations of the mutator context module that support single-stepping of accesses (see design.mps.prot.impl.an.sync.issue).

.lim.sp: Only suitable for use with programs that do not handle stack overflow faults, or do not call into the MPS from the handler (see design.mps.sp.issue.an).

.lim.stack-scan: Assumes that the stack grows downwards and that setjmp() reliably captures the registers (see design.mps.stack-scan.sol.stack.platform).

.lim.th: Requires a single-threaded mutator (see design.mps.thread-manager.impl.an.single).

.lim.vm: Maps all reserved addresses into main memory (see design.mps.vm.impl.an.reserve), thus using more main memory than a platform-specific implementation.