Process Stacks

Introduction

Each process requires its own stack, which is usually declared directly in the module that implements the process:

CONST StackSize = 1024;
VAR stack: ARRAY StackSize OF BYTE;

Processes.Init will then set up the stack for the underlying coroutine, which works on absolute addresses.

PROCEDURE Init*(p: Process; code: ProcCode; stack: ARRAY OF BYTE; stackHotSize, ptype, prio: INTEGER; id: ARRAY OF CHAR);

The Initial Stack

When the Oberon system starts, it does not have yet any notion of processes, and uses the stack area as defined via the boot loader and module Kernel for the start-up sequence. In EPO, this stack is the only one ever needed and used, in order to execute commands and tasks.

This initial stack is located between the bottom of the heap space and the top of the module memory.

Stack Reallocation

At first sight, after system start-up, in Oberon RTS this initial stack could in principle be reclaimed and used as module memory, or even as heap space. As we need a stack for command execution anyway, a simpler solution was chosen, which does not require any changes to the Inner Core, and leaves the overall memory layout unchanged and compliant with EPO and Project Oberon.

After the system start-up is completed, before control is handed over to the scheduler, the initial stack is allocated as follows:

  • the top section of the main stack is allocated to the scheduling process
  • the stack area below the scheduler stack is allocated to process cmd

As we are allocating stack memory at absolute addresses here, we use Processes.InitRaw to set up process cmd:

PROCEDURE InitRaw*(p: Process; code: ProcCode; stackAddr, stackSize, stackHotSize, ptype, prio: INTEGER; id: ARRAY OF CHAR);

This solution allocates close to the same stack space to handling commands and uploads as it would in EPO. The scheduler only needs 512 bytes of stack space.

Other Processes

Processes.InitRaw could in principle be used for any control process, for example to implement a different stack scheme, where all process stacks are kept in a contiguous memory space, in lieu of distributing them across the corresponding modules.

Using SYSTEM.ADR it would be possible to only have Processes.InitRaw, and omit Processes.Init from the API. However, application-level control processes should not require to use SYSTEM.