10
CHAPTER 2.
µ
C++ TRANSLATOR
2.4 µC++ Kernel
After a µC++ program is translated and compiled, a runtime concurrency library is linked in with the resulting pro-
gram, called the µC++ kernel. There are two versions of the µC++ kernel: the unikernel, which is designed to use a
single processor (in effect, there is only one virtual processor); and the multikernel, which is designed to use several
processors. Thus, the unikernel is sensibly used on systems with a single hardware processor or when kernel threads
are unavailable; the multikernel is sensibly used on systems that have multiple hardware processors and when kernel
threads are available. Table 2.2 shows the situations where each kernel can be used. The unikernel can be used in a
system with multiple hardware processors and kernel threads but does not take advantage of either of these capabili-
ties. The multikernel can be used on a system with a single hardware processor and kernel threads but performs less
efficiently than the unikernel because it uses multiprocessor techniques unnecessarily.
no kernel threads kernel threads
single unikernel, yes unikernel, yes
processor
multikernel, no multikernel, yes, but inefficient
multiple unikernel, yes unikernel, yes, but no parallelism
processors multikernel, no multikernel, yes
Table 2.2: When to Use the Unikernel and Multikernel
Each of the µC++ kernels has a debugging version, which performs a number of runtime checks. For example,
the µC++ kernel provides no support for automatic growth of stack space for coroutines and tasks because this would
require compiler support. The debugging version checks for stack overflow whenever context switches occur among
coroutines and tasks, which catches many stack overflows; however, stack overflow can still occur if insufficient
stack area is provided, which can cause an immediate error or unexplainable results. Many other runtime checks are
performed in the debugging version. After a program is debugged, the non-debugging version can be used to increase
performance.
2.5 Using the µC++ Translator
To use the concurrency extensions in a C++ program, include the file:
#include <uC++.h>
at the beginning of each source file needing access to µC++,
and it must appear before all other include files.
2.5.1 Compiling a µC++ Program
The u++ command is used to compile a µC++ program. This command works just like the GNU g++ [
Tie90] command
for compiling C++ programs, e.g.:
u++ [C++ options] yourprogram.C [assembler and loader files]
The following additional options are available for the u++ command:
-debug The program is linked with the debugging version of the unikernel or multikernel. The debug version
performs runtime checks to help during the debugging phase of a µC++ program, but substantially slows the ex-
ecution of the program. The runtime checks should only be removed after the program is completely debugged.
This option is the default.
-nodebug The program is linked with the non-debugging version of the unikernel or multikernel, so the execution
of the program is faster.
However, no runtime checks or asserts are performed so errors usually result in
abnormal program termination.
-yield When a program is translated, a random number of context switches occur at the beginning of each member
routine so that during execution on a uniprocessor there is a better simulation of parallelism. (This non-
determinism in execution is in addition to random context switching due to pre-emptive scheduling, see Sec-
tion
8.4.1, p. 115). The extra yields of execution can help during the debugging phase of a µC++ program, but
substantially slows the execution of the program.
-noyield Additional context switches are not inserted in member routines. This option is the default.