Update: With a real-time scheduler in the kernel only a call that provides the ability to obtain information about the last time block (probably only how long it was) and the ability to yield the processor to a specified process is needed.
CHAOS includes a dumb scheduler which alternates the runable processes in the system in a round-robin fashion in short periods of time. It has no priorities nor any sort of accounting nor does it attempt to distribute the CPU power to the processes in a fair way. Such a simple thing can be programmed in less than one kilobyte and is good enough for several dozens of applications, including desktops and servers with low or medium load.
This simple scheduler is there to avoid problems with a multiprocess kernel without a scheduler. In that case the kernel would be required to wait for the process to give the CPU back to the kernel before it can give it to the other process. If the process never gives the CPU back (because it is in an infinite loop), the kernel has no chance to run other processes and the result would be an uninterruptible hang. This is called cooperative multitasking and in general is not apropiate for multiserver microkernel operating systems.
However the default CHAOS scheduler contains a facility that allows the system designer to write its own sophisticated and feature-rich scheduling server implementing priorities, fair CPU scheduling and other fancy things. Of course, special kernel right is required to gain access to this scheduling control facility, as it gives the process enough control above the CPU to be able to seriously harm the system stability. This access is represented by a handle (called scheduling handle) connected to the CHAOS internal scheduler, which allows it to monitor the process states and to control which process will be the next one to be (re)launched on the CPU.
The reason of splitting this functionality out of the kernel and having it in a separate scheduler server is the variability of scheduling needs in various enviroments. For example a factory needs a scheduler which is able to give the CPU to certain tasks as quickly as possible when they become runable to avoid a disaster. At the other side, there are various research networks with computers connected to clusters and performing computations whose priorities are different. Even when we want to give more CPU power to higher priority computations than the lower ones, we also want even the lowest priority computations keep running. These different needs require different schedulers specialized to various scheduling patterns. With a scheduler built into the kernel it would be difficult or nearly impossible to create or maintain a pool of useful schedulers, which implies an unnecessary reduction of user's freedom.
The customized process scheduling is done by a scheduler thread. A thread becomes a scheduler thread by listening for messages on the scheduling handle. Only one thread at a time can be listening on the scheduling handle (if another thread tries to listen there in that time, it will get an access error). The execution priority of such a thread is raised so when it becomes runable (due to a message posted to the scheduling handle), it gets CPU immediately and then runs until it becomes nonrunable. During that time it can do anything that is required to determine the next thread to be scheduled. Once the thread is chosen, its TID is transmitted to the scheduler handle (if a TID of nonrunnable thread is given here, the CPU is returned back to the scheduler thread with a message saying that the kernel wants a runable thread) and the scheduler thread listens the handle again thus passing control to the newly specified thread.
There can be only one scheduling thread so when another thread listens the scheduling handle, it becomes a scheduling thread (this can happen when the original scheduling thread falls asleep for example due to an attempt to listen on a handle other than the scheduling handle) and the original scheduling thread loses its scheduling thread status.
The CHAOS transmits into the scheduling handle (if there is such a handle) all thread state changes such as a thread becoming runable so the scheduler server can be aware of these changes. Also the timeslice clocking messages generated by the CHAOS scheduler are transmitted there to allow the scheduler thread to maintain the fiction of multiple proceses running on single CPU concurrently.
If the scheduler thread dies or stops being a scheduler thread without any other thread starting to be a scheduler thread (by closing all scheduler handles for example), the default CHAOS scheduler operation is resumed.