next up previous contents index
Next: Examining Processes Up: The OS Interface: Processes Previous: Creating Processes

Terminating Processes

 

This subsection describes the different ways a process may terminate, and the procedure (WaitForChild) used by a parent process to find out about the termination of a child process.

                  A process can terminate normally or abnormally. It terminates normally by calling the Modula-2+ HALT procedure. (Running off the end or returning from the main program is equivalent to calling HALT(0)). It terminates abnormally by making a fatal error, such as raising an exception for which there is no handler, or by receiving a signal for which the default action of termination is in force (see page [*]).

           When a process terminates abnormally, the operating system may write a file named `core' in the working directory that contains an image of the state of the process suitable for post mortem debugging (see DebugCore(1) and adb(1)). A core image is written if a process terminates because of making a fatal error or because of receiving one of the signals whose default action is defined as termination with a core image (see page [*]).

     

TYPE
  WReason = (Stopped, Killed, Exited);
  ExitStatus = [0 .. 255];
  WStatus = RECORD
    CASE reason: WReason OF
    | Stopped: wStopSig: Signal;
    | Killed: wTermSig: Signal; wCoreDump: BOOLEAN;
    | Exited: wRetCode: ExitStatus;
    END;
  END;

        A WStatus record contains information about why a process terminated or stopped; it is returned by the WaitForChild procedure, described below. The wStopSig field indicates which signal cause the process to stop. The wTermSig field indicates which signal caused the process to terminate; this is set to SigIll if the process terminates because of a fatal error. The wRetCode field contains the value passed to HALT. (HALT performs clean-up of the Modula-2+ runtime environment, and then calls OSSpecial.Exit.)

  

TYPE
  RUsage = RECORD
    userTime, systemTime: Time.T;
  END;

An RUsage record contains a summary of execution time of a process. The userTime field is the sum of the CPU times of all threads in the process.

Taos note: CPU time spent executing an intramachine remote procedure call (such as to an OS procedure) is charged to the userTime of the calling thread. The systemTime field is the CPU time spent in the Taos address space by the thread that is dedicated to watching for Ultrix-style kernel calls and other traps from this process. There are also helper threads in the Taos address space that do work for various client address spaces but whose CPU time is not included in the userTime or systemTime of those clients.

Ultrix note: The systemTime field is the CPU time spent by the system executing kernel calls for this process.

  

PROCEDURE WaitForChild(
    pid: PID;
    VAR (* OUT *) rUsage: RUsage;
    waitForStoppedChild: BOOLEAN := FALSE)
    : WStatus
  RAISES {Error, Alerted}; (* BadPIDEC *)

  WaitForChild waits for the process with the specified process identifier to terminate. If waitForStoppedChild is TRUE, WaitForChild also waits for the process to stop. WaitForChild always returns status; if the process terminated, WaitForChild also returns resource usage of the child and its descendants. A process should eventually call WaitForChild with the process identifier of each process it has started with relationship equal to Child (see the StartProcess procedure, page [*]). A process should not call WaitForChild with the process identifier of any other processes (including ones it has started with relationship equal to Orphan); if it does, WaitForChild raises BadPIDEC. WaitForChild is alertable.


next up previous contents index
Next: Examining Processes Up: The OS Interface: Processes Previous: Creating Processes
Paul McJones
8/28/1997