Like user-mode threads in a Win32 application, system threads may need to suspend their execution until some other condition has been satisfied. This section describes the basic synchronization techniques available to system threads. Time SynchronizationThe simplest kind of synchronization involves stopping a thread's execution until a specific time interval elapses. Although Timer objects, described later in this chapter, can be used, the kernel provides a convenient function, KeDelayExecutionThread (illustrated in Table 14.3) that is easier to use.
General SynchronizationSystem threads can synchronize their activities in more general ways by waiting for dispatcher objects. Thread synchronization depends on the fact that a dispatcher object is always in either the signaled or nonsignaled state. When a thread asks to wait for a nonsignaled dispatcher object, the thread's execution stops until the object becomes signaled. (Waiting for a dispatcher object that is already Signaled is a no-op.) There are two different functions that can be used to wait for a dispatcher object. KeWaitForSingleObjectThis function, described in Table 14.4, puts the calling thread into a wait state until a specific dispatcher object is set to the signaled state.
Optionally, a timeout value may be specified that causes the thread to awaken even if the dispatcher object is nonsignaled. If the timeout argument is NULL, KeWaitForSingleObject waits indefinitely. KeWaitForMultipleObjectsThis function, described in Table 14.5, puts the calling thread into a wait state until any or all of a group of dispatcher objects are set to the signaled state. Again, a timeout value for the wait may be specified.
Be aware that there are limits on how many objects the thread can wait for at one time. Each thread has a built-in array of Wait blocks that it uses for concurrent wait operations. The thread can use this array to wait for up to THREAD_WAIT_OBJECTS number of objects. If the number THREAD_WAIT_ OBJECTS is insufficient, a driver-supplied array of Wait blocks must be included in the call to KeWaitForMultipleObjects. Regardless, the number of objects waited upon cannot exceed MAXIMUM_WAIT_OBJECTS. The KeWaitForXxx functions may be called from either PASSIVE_ LEVEL or DISPATCH_LEVEL IRQL. However, from DISPATCH_LEVEL IRQL, a zero timeout value must be specified. At DISPATCH_LEVEL IRQL, the calls are effectively used as a polling mechanism for Signaled objects.
|