Go backward to Process Control Block Structure
Go up to Process Management
Go forward to Internal Process Manipulation Routines

The createproc Primitive

There will actually be only one system primitive directly related to implementing the process abstraction in your kernel. This is the "createproc" procedure. This primitive should take parameters describing a process to be created and enter the process on the ready list so that it can begin to execute.

In a full fledged operating system (and in more complete kernel), the creation of a process is accompanied by the automatic allocation of the resources the process needs. For example, the system might search its list of PCB's to find a free PCB that could be allocated to the new process. It might also allocate memory for the process' local data and stack.

In AMUK, the kernel will do no dynamic allocation. If a process A wishes to create a new process, it is up to process A to find space for the process' stack and PCB and pass the addresses of these regions when it invokes createproc.

Other parameter values one might want to pass to createproc include values like the process' priority and name. These values will eventually be stored in the new process' PCB. Since the process calling createproc will have to pass the address of the space for the PCB as a parameter to createproc anyway, a natural approach to designing the interface for createproc is to have the caller pass createproc the address of the new process' PCB with the PCB fields for the process' name and priority already filled in. This is the approach we will use. Accordingly, in our system, createproc will take relatively few parameters. The header for the function is shown below:


createproc(descriptor,processcode,processparm)
struct pcb *descriptor;
int (*processcode)();
int processparm;
The "descriptor" should be a pointer to a block of memory the system can use to hold the new process' PCB. The first four fields of the PCB ("name", "priority", "SPvalue" and "PSvalue") should be set before createproc is invoked. The value of "SPvalue" should be equal to the address of the last word of the space allocated for the process' stack. The value of PSvalue should be 0, 1 or 3 depending on whether this process is to run with all interrupts enabled, terminal interrupts disabled or all interrupts disabled.

The "processcode" parameter will be a pointer to a function that contains the code to be executed by the process. That is, when the process gets started, it should begin by calling this function. If the function ever returns, the system should consider the process terminated.

The function identified by "processcode" should expect one integer parameter. The value passed for this parameter is determined by the "processparm" parameter. This makes it possible to have several processes run the same code but act differently based on the value passed for "processparm" when the process is created. For example, you might have one function containing the code for a terminal output driver process but need to have one process controlling each terminal. If the function passed as "processcode" when creating these processes expects the terminal number as a parameter, this can be arranged by passing distinct values ranging from 0 to 4 for "processparm" when creating these processes.

I should warn you that the code you write to initialize a new process' state will be fairly tricky. Normally, processes are only suspended when they call the equivalent of the reschedule primitive discussed in class. Thus, when a process is dispatched it is normally safe to have it execute a return from "reschedule". To make this possible for a newly created process you will have to explicitly set its SP and FP registers and several words on its stack to make it appear that the process was executing a call to reschedule.



Prev Up Next