PREVIOUS

Chapter 2. Runtime Environments

The variable combination of compiler, hardware platform, and the desire to write objects that are compatible with both UNIX(tm) and KeyKOS has led to the development of several runtime environments. The most commonly used environment is known as the "Standard" or full function environment.

The standard environment uses a Virtual Copy Segment for the memory of a domain. Some compilers do not separate the memory of the C program into Read/Only (code and static data) and Read/Write (global variables) so the program must be loaded into memory that is not shared with other programs. In order to maximize sharing potential, a Virtual Copy Segment is used. Any time that the program modifies a page in the VCS for the first time, a copy of that page is made. This allows the maximum sharing possible while preserving the full function of the C language. There is no standard UNIX(TM) FORK() function in this environment, though there are several implementations available by special arrangement.

An alternate environment is available that does not use a Virtual Copy segment for the memory. That environment excludes the use of global read/write variables but does provide a FORK() function. This environment is referred to as the "Early Object" environment.

Standard Full Function Environment

Programs using the Full Function Environment may use the Key Cache if the "KJUMP" option was used on the preprocessor command.

Before a user's C domain can be executed, the run-time environment must be set up. This set up is done by the CSTART routine (in USER.SYS.KKOSCLIB.CSTART), where the execution begins. This routine initializes memory management including the run-time stack and the global register area. It also initializes the starting address of the memory from which dynamic memory allocation can take place.

The user, however, must supply sufficient space for the run-time stack, global register area, and the area for dynamic memory allocation if dynamic memory allocation routines (malloc, calloc, realloc) are being used. If using the Binder, the user must supply a text deck with the name STACK. Otherwise, the stack and dynamic memory allocation are provided by default.

The size of the run-time stack is 32K by default. All auto variables, parameters, and register save areas for the C program are allocated from this stack. The stack size can be adjusted by changing the value of _staksize in the SETUP C source file and recompiling it. The new SETUP object file must then be included with the C program when linking in order to replace the default version (found in USER.SYS.KKOSCLIB. when linking in KeyKOS).

The same considerations apply to the size of the global register area and dynamic memory allocation area, which can also be changed in the SETUP C source file. The default size for the global register area is 0K and the default size for dynamic memory allocation is 8M.

To destroy a domain using this environment, control should be transferred to a special KeyKOS epilogue automatically linked in. This can be achieved either by returning from the main() function, or calling the exit() function from anywhere in the program. The epilogue will release all of the memory regardless of the environment in which the object was linked.

Early Object Environment

The Early Object environment was developed to support the C programming language and some UNIX(TM) functions for the objects that are use to supply the function needed to support the more complex Full Function Environment. The basic characteristics of this environment are: It is the nature of most KeyKOS objects that the "main" program does not return except when the object is requesting self destruction. Therefore the stack of the "main" program can be used for read/write variables that must be available to all functions in the object. The standard way of doing this is to describe a structure for the working variables and allocate the structure as a automatic variable of the "main" program. A pointer to this structure is passed to all functions that need to reference these variables.

The current Key invocation macros (KALL, KC, etc) assume that there is a global structure that describes the Entry and Exit blocks for the invocation. This choice was dictated by the need to set up the Entry and Exit blocks at different places in the program. In the Early Object environment there is no read/write global storage; therefore, each function that does any Key invocations must allocate a local structure for the (KALL, KC, etc) macros. This places some restrictions on the use of LDEXBL and LDENBL macros. The same function that uses LDEXBL and LDENBL must also do RETJUMP(). If the return of a function alters the Entry or Exit block used, the return code of the function must be used by the calling function to set up the Entry and Exit blocks.

The header "KEYKOS1 H" must be included as the first header in the source. This header defines the Entry and Exit block structures and some KeyKOS constants. Each function that does any Key invocations must include the "KEYKOS2 H" header in the variable declaration section of the function. This header defines the Entry and Exit blocks for use by that function. Later versions of the KCPP pre-processor will undoubtedly alter this requirement.

The program must be linked with CFSTART rather than CSTART. CFSTART is an environment initializer (a replacement for CSTART) that allocates a stack for the program and invokes the program at the function FACTORY(ordercode,ordinal) passing the ordercode on the factory requester key and the ordinal specified by the builder.

Features of the Early Object Environment