Jump to content

DevHlp Block: Difference between revisions

From EDM2
No edit summary
 
(One intermediate revision by the same user not shown)
Line 15: Line 15:
:0 - Block is interruptible
:0 - Block is interruptible
: 1 - Block is noninterruptible
: 1 - Block is noninterruptible
;''&Error'' ([[FARPOINTER]]): Far Pointer to error returned
;''&Error'' (FARPOINTER): Far Pointer to error returned
: 1 - Block timed out
: 1 - Block timed out
: 2 - Block interrupted by control-C
: 2 - Block interrupted by control-C


==Remarks==
==Remarks==
Line 32: Line 31:


==Example Code==
==Example Code==
if (Block(WriteID,blockcount, 0, &err))
if (Block(WriteID,blockcount, 0, &err))
       if (err == 2) // interrupted
       if (err == 2) // interrupted
             return(RPDONE|RPERR|ERROR_CHAR_CALL_INTERRUPTED);
             return(RPDONE|RPERR|ERROR_CHAR_CALL_INTERRUPTED);

Latest revision as of 15:25, 22 May 2025

Block This Thread From Running

The Block DevHlp blocks the current requesting thread and removes it from the run queue until it is released by a call to the Run DevHlp.

Block Mode
Kernel

Syntax

Block(BlockID, Timeout, Flag, &Error)

Parameters

BlockID (ULONG) - input
ID used for Block and subsequent Run
Timeout (ULONG) - input
Timeout in milliseconds or -1L Block forever
Flag (USHORT)- input
0 - Block is interruptible
1 - Block is noninterruptible
&Error (FARPOINTER)
Far Pointer to error returned
1 - Block timed out
2 - Block interrupted by control-C

Remarks

The return from the Block call indicates whether the wake-up occurred as the result of a Run DevHlp call or an expiration of the time limit. Block removes the current thread from the run queue, allowing any other waiting threads to run. The thread blocked in the device driver is reactivated and Block returns when Run 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 an acceptable convention is to use the address of the Request Packet that made the request.

Since the device driver may be Blocked in one mode and Run in the other, using the address of the Request Packet is the best choice, as this bimodal address is valid in either mode. It is up to the device driver writer to insure that the Block was woken up by the correct mechanism, and not accidentally. To avoid a deadlock condition by getting a Run before the Block call is completed, the device driver should disable interrupts before issuing the Block. The Block DevHlp re-enables the interrupts.

A timeout value of -1 means that Block waits indefinitely until Run is called. Only the Strategy sections of the device driver can call Block, but Run can be called by the Strategy section, interrupt handler, or timer handler. When using Block to block a thread, the device driver can specify whether or not the Block may be interrupted. If the Block is interruptible, then the kernel can abort the blocked thread and return from the Block without using a corresponding Run. In general, the Block should be marked as interruptible so that a signal such as a control C will UnBlock the thread.

The Block call will return when the thread has been run, when the timeout has expired, or if the thread was UnBlock by a signal, such as a control C. If the Block returns with a 1, the Block has timed out. If the Block returns a 2, the Block was interrupted. If the Block returns a 0, or valid return, then the Block was released by a call to the Run DevHlp, and the device driver should take the appropriate action.


Example Code

if (Block(WriteID,blockcount, 0, &err))
     if (err == 2) // interrupted
           return(RPDONE|RPERR|ERROR_CHAR_CALL_INTERRUPTED);
     if (err == 1)
           return (RPDONE|RPERR|ERROR_NOT_READY);