DevHelp_ProcBlock
This service prevents the thread executing in the physical device driver from executing ("puts it to sleep") until either a call to the DevHlp_ProcRun is issued on the event identifier, or a timeout occurs.
Syntax
C
USHORT APIENTRY DevHelp_ProcBlock( ULONG EventId, ULONG WaitTime, USHORT IntWaitFlag)
Assembler
MOV BX,event_id_low ; Low word of event id MOV AX,event_id_high ; High word of event id MOV DI,time_limit_high ; Timeout interval in milliseconds MOV CX,time_limit_low ; ( = -1 if to never timeout) MOV DH,interruptible_flag ; Tells if sleep is interruptible ; 0 = interruptible ; 1 = non-interruptible MOV DL,DevHlp_ProcBlock CALL [Device_Help]
Parameters
C
- EventId (ULONG)
- Event identifier - an arbitrary 32-bit value.
- The standard convention for ProcBlock/ProcRun operations is to use the address of some structure or memory cell associated with the reason for blocking and running. For example, a thread blocking until some resource is cleared normally blocks on the address of ownership flag for that resource.
- WaitTime (ULONG)
- Timeout interval in milliseconds.
- -1 = wait forever.
- IntWaitFlag (USHORT)
- Tells if sleep is interruptible.
- 0 = interruptible, 1 = non-interruptible.
Assembler
MOV BX,event_id_low ; Low word of event id MOV AX,event_id_high ; High word of event id MOV DI,time_limit_high ; Timeout interval in milliseconds MOV CX,time_limit_low ; ( = -1 if to never timeout) MOV DH,interruptible_flag ; Tells if sleep is interruptible ; 0 = interruptible ; 1 = non-interruptible
Return Code
C
Success Indicator: Returns awake code.
Possible errors:
WAIT_INTERRUPTED WAIT_TIMED_OUT
Assembler
'C' Clear if event wakeup. 'C' Set if unusual wakeup. 'Z' Set if wakeup due to timeout. 'Z' Clear if sleep was interrupted. AL = Awake code, non-zero if unusual wakeup.
Remarks
The return from the call to ProcBlock indicates whether the "wakeup" occurred as the result of a call to ProcRun or an expiration of the time limit. ProcBlock removes the current thread from the ProcRun queue and starts executing some other thread. The thread blocked in the physical device driver is reactivated and ProcBlock returns when ProcRun is called with the same event identifier, when the time limit expires, or when the thread is signalled.
The event identifier is an arbitrary 32-bit value, but a convention must be followed to coordinate with the thread issuing the ProcRun function. The standard convention for ProcBlock/ProcRun operations is to use the address of some structure or memory cell associated with the reason for blocking and running. For example, a thread blocking until some resource is cleared normally blocks on the address of the ownership flag for that resource.
The ProcBlock/ProcRun mechanism is so designed that it cannot guarantee immunity from a faulty wakeup by some other thread in the system running a 32-bit key value (which happens to match the key of some unrelated blocking thread). The goal is to choose keys that have a high likelihood of being unique. However, users of ProcBlock/ProcRun must always check the reason for the wakeup to make sure that the event actually took place, and that the wakeup was not accidental.
When calling ProcBlock, it is important to use the sequence:
Disable Interrupts while (need to wait) Block (value) Disable Interrupts
Interrupts must be turned off before checking the condition (for example, I/O done, resource freed). This is necessary to avoid a deadlock caused by getting an interrupt-time ProcRun call before completing the call to ProcBlock. ProcBlock re-enables the interrupts. Note the use of the WHILE clause. It is essential to recheck the awaited condition and, if necessary, re-disable interrupts and call ProcBlock again. The convention of using an address as an event identifier should prevent double use of an identifier. A time limit of -1 means that ProcBlock waits indefinitely until ProcRun is called. ProcBlock can be called only by the task-time portion of a physical device driver.
When using ProcBlock to block a thread, the driver can specify whether the sleep can be interrupted. If the sleep is interruptible, then the kernel can abort the blocked thread and return from the ProcBlock, without using a corresponding ProcRun. In general, the sleep should be marked as interruptible unless the sleep duration is expected to be short (that is, less than a second).
If the return from the ProcBlock indicates that the sleep was interrupted, some internal event occurred that requires attention (such as a signal, process death, or some other forced action). The device driver should respond by performing any necessary cleanup, setting the error code in the status field of the request packet, setting the done bit, and returning the request packet to the kernel.
Example Code
C
#include "dhcalls.h" USHORT APIENTRY DevHelp_ProcBlock( ULONG EventId, ULONG WaitTime, USHORT IntWaitFlag)