Next: Trace Library Up: Thread Library Previous: Locking Operations

Usage Rules

Scheduling and Preemption

The currently executing thread gives up control by either terminating or executing a semWait operation. In other words, the x-kernel does not preempt threads; threads voluntarily give up control of the processor. However, because each protocol is assumed to be an independent component, protocols are written to assume that control may be given up when a higher or lower level protocol is invoked. Therefore, all protocol-protocol operations are considered to have the potential to cause a thread switch, and all data structures must be ``secured'' before calling such operations.

Blocking

Although the x-kernel advocates a ``thread-per-message'' model, and it provides primitives for blocking threads, as a general rule, threads should not block except when waiting for a reply in an RPC-like protocol. In most other cases, should a thread (message) not be able to proceed, it should put the message in a protocol-dependent queue and return. Later, another thread can pick the message up out of the queue and continue processing it.

For example, when an incoming thread/message arrives in IP and discovers that it is just one fragment of a larger datagram, rather than blocking the thread and waiting for the other fragments to arrive, the thread should insert the fragment into a reassembly buffer and return. The thread that delivers the last fragment will then reassemble the fragments into a single datagram and continue.

External Threads

Where the x-kernel is embedded in another operating system, there may be asynchronous threads representing device drivers or user requests that want to enter the x-kernel. These threads must, in general, acquire the x-kernel master lock (i.e., enter the x-kernel monitor) with xk_master_lock before performing any x-kernel operations, including other thread synchronization operations. (This isn't necessary for normal x-kernel threads because threads started by evSchedule acquire the master lock automatically when they start running.) Unless a call is explicitly documented otherwise, threads may not make x-kernel system or library calls without holding the master lock.

A thread acquires and releases the master x-kernel lock with the following operations.

void xk_master_lock ( void )

void xk_master_unlock ( void )

Note that normal protocols should not use these operations. The only place that they are meaningful is in anchor protocols, such as device drivers and application-level interface, that have to transition between the x-kernel and the host OS. Also note that this interface is not part of the official x-kernel interface; it is internal to the current implementation of the x-kernel.

Thread Turnaround

Protocols should refrain from taking threads which are shepherding outgoing messages down the protocol stack and turning them around to accompany messages traveling up the protocol stack. Since protocols are allowed to reverse thread direction from incoming to outgoing, allowing turnaround from outgoing to incoming could lead to a thread caught in a recursive loop. If an outgoing thread needs to send a message back up, it should start a new thread to do this. The push routine of the ethernet protocol ( /usr/xkernel/protocols/eth) has an example of how this is done.

Multiprocessor Support

To date, we do not have significant experience running the x-kernel on a multiprocessor. We have introduced locking operations that are useful in certain situations on a uniprocessor, and while these operations might extend to an MP environment, we cannot be certain that they will. Moreover, we certainly expect that the implementation of both the locking and the semaphore operations will need to change in an MP environment, even if the interface remains the same.

It should be noted that the x-kernel, as currently implemented, is MP-safe, although probably not MP-performant. This is because all threads executing in the x-kernel must first acquire a master lock; i.e., the x-kernel is currently implemented as a single monitor. Our experience suggests, however, that this implementation is reasonably efficient for a small number of processors.



Next: Trace Library Up: Thread Library Previous: Locking Operations


Tue Nov 29 16:28:56 MST 1994