9.2.5. Kernel Calls for Process Management
The best way to find out what a kernel or operating system really does is to examine its interface, that is, the system calls it provides to its users. In this section we will look at the most important Chorus kernel calls available to system processes. Calls of less importance and protected calls available only to kernel threads will be omitted.
| Call | Description |
|---|---|
| actorCreate | Create a new process |
| actorDelete | Remove a process |
| actorStop | Stop a process, put its threads in STOPPED state |
| actorStart | Restart a process from STOPPED state |
| actorPriority | Get or set a process' priority |
| actorExcept | Get or set the port used for exception handling |
Fig. 9-8. Selected process calls supported by the Chorus kernel.
Let us start with the process calls, listed in Fig. 9-8. ActorCreate creates a new process and returns that process' capability to the caller. The new process inherits the priority, protection identifier, and exception port of the parent process. Parameters specify whether the new process is to be a user, system, or kernel process, and tell what state it is to start in. Just after creation, the new process is empty, with no threads and no regions and only one port, the default port. Note that actorCreate represents a major orthographic advance over UNIX: "Create" is spelled with an "e" at the end.
The actorDelete call kills a process. The process to be killed is specified by a capability passed as a parameter. ActorStop freezes a process, putting all of its threads into STOPPED state. The threads can only run again when an actorStart call is made. A process may stop itself. These calls are typically used for debugging. For example, if a thread hits a breakpoint, the debugger can use actorStop to stop the process' other threads.
The actorPriority call allows a process to read the priority of another process, and optionally, to reset it to a new value. Although Chorus is generally location transparent, it is not perfect. Some calls, including this one, work only when the target process is on the caller's machine. In other words, it is not possible to get or reset the priority of a distant process.
ActorExcept is used to get or change the exception port for the caller or some other process for which the caller has a capability. It can also be used to remove the exception port, in which case if an exception has to be sent to the process, the process is killed instead.
The next group of kernel calls relate to threads, and are shown in Fig. 9-9. ThreadCreate and threadDelete create and delete threads in some process (not necessarily the caller's), respectively. Parameters to threadCreate specify the privilege level, initial status, priority, entry point, and stack pointer.
| Call | Description |
|---|---|
| threadCreate | Create a new thread |
| threadDelete | Delete a thread |
| threadSuspend | Suspend a thread |
| threadResume | Restart a suspended thread |
| threadPriority | Get or set a thread's priority |
| threadLoad | Get a thread's context pointer |
| threadStore | Set a thread's context pointer |
| threadContext | Get or set a thread's execution context |
Fig. 9-9. Selected thread calls supported by the Chorus kernel.
ThreadSuspend and threadResume stop and then restart threads in the target process. ThreadPriority returns the target thread's current relative priority, and optionally resets it to a value given as a parameter.
Our last three calls are used to manage a thread's private context. The threadLoad and threadStore calls load and set the current software context register, respectively. This register points to the thread's context, including its private variables. The threadContext call optionally copies the thread's old context to a buffer, and optionally sets the new context from another buffer.
The synchronization operations are given in Fig. 9-10. Calls are provided for initializing, acquiring, and releasing both mutexes and semaphores. These all work in the usual way.
| Call | Description |
|---|---|
| mutexInit | Initialize a mutex |
| mutexGet | Try to acquire a mutex |
| mutexRel | Release a mutex |
| semInit | Initialize a semaphore |
| semP | Do a DOWN on a semaphore |
| semV | Do an UP on a semaphore |
Fig. 9-10. Selected synchronization calls supported by the Chorus kernel.
9.3. MEMORY MANAGEMENT IN CHORUS
Memory management in Chorus borrows many ideas from Mach. However, it also contains some ideas not present in Mach. In this section we will describe the basic concepts and how they are used.
9.3.1. Regions and Segments
The main concepts behind memory management in Chorus are regions and segments. A region is a contiguous range of virtual address, for example, 1024 to 6143. In theory, a region can begin at any virtual address and end at any virtual address, but to do anything useful, a region should be page aligned and have a length equal to some whole number of pages. All bytes in a region must have the same protection characteristics (e.g., read-only). Regions are a property of processes, and all the threads in a process see the same regions. Two regions in the same process may not overlap.