Jump to content

DevHelp ProcRun: Difference between revisions

From EDM2
Created page with "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 i..."
 
No edit summary
 
(One intermediate revision by the same user not shown)
Line 1: Line 1:
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.  
{{DISPLAYTITLE:DevHelp_ProcRun}}
This service is the companion routine to ProcBlock. When ProcRun is called, it awakens all the threads that were blocked for this particular event identifier.  


==Syntax==
==Syntax==
===C===
===C===
<PRE>
<PRE>
USHORT APIENTRY DevHelp_ProcBlock( ULONG EventId,
USHORT APIENTRY DevHelp_ProcRun( ULONG   EventId,
                                  ULONG  WaitTime,
                                PUSHORT AwakeCount)
                                  USHORT IntWaitFlag)
</PRE>
</PRE>


===Assembler===
===Assembler===
<PRE>
<PRE>
MOV  BX,event_id_low        ; Low word of event id
MOV  BX,event_id_low        ; Low word of event identifier.
MOV  AX,event_id_high        ; High word of event id
MOV  AX,event_id_high        ; High word of event identifier.
MOV  DI,time_limit_high      ; Timeout interval in milliseconds
MOV  DL,DevHlp_ProcRun
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]
CALL  [Device_Help]
Line 24: Line 19:
==Parameters==
==Parameters==
===C===
===C===
; EventId (ULONG) : Event identifier - an arbitrary 32-bit value.
; EventId (ULONG): Event identifier.
: 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.


; AwakeCount (PUSHORT)  :  Count of threads awakened to be returned.
===Assembler===
===Assembler===
<PRE>
<PRE>
MOV  BX,event_id_low        ; Low word of event id
MOV  BX,event_id_low        ; Low word of event identifier.
MOV  AX,event_id_high        ; High word of event id
MOV  AX,event_id_high        ; High word of event identifier.
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
</PRE>
</PRE>


Line 47: Line 31:


===C===
===C===
Success Indicator: Returns awake code.
Success Indicator: 0


Possible errors:
Possible errors: None.
              WAIT_INTERRUPTED
              WAIT_TIMED_OUT


===Assembler===
===Assembler===
<PRE>
<PRE>
   'C' Clear if event wakeup.
   AX = Count of threads awakened.
  '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.
  'Z'  Set or clear according to the contents of AX.
</PRE>
</PRE>


==Remarks==
==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.
ProcRun returns immediately to its caller; the awakened threads are run at the next available opportunity. ProcRun is often called at interrupt time. See ProcBlock for a more detailed discussion of blocking and running threads.  
 
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==
==Example Code==
Line 89: Line 50:
#include  "dhcalls.h"
#include  "dhcalls.h"


USHORT APIENTRY DevHelp_ProcBlock( ULONG EventId,
USHORT APIENTRY DevHelp_ProcRun( ULONG   EventId,
                                  ULONG  WaitTime,
                                PUSHORT AwakeCount)
                                  USHORT IntWaitFlag)
</PRE>
</PRE>



Latest revision as of 03:23, 23 May 2025

This service is the companion routine to ProcBlock. When ProcRun is called, it awakens all the threads that were blocked for this particular event identifier.

Syntax

C

USHORT APIENTRY DevHelp_ProcRun( ULONG   EventId,
                                 PUSHORT AwakeCount)

Assembler

MOV   BX,event_id_low         ; Low word of event identifier.
MOV   AX,event_id_high        ; High word of event identifier.
MOV   DL,DevHlp_ProcRun

CALL  [Device_Help]

Parameters

C

EventId (ULONG)
Event identifier.
AwakeCount (PUSHORT)
Count of threads awakened to be returned.

Assembler

MOV   BX,event_id_low         ; Low word of event identifier.
MOV   AX,event_id_high        ; High word of event identifier.

Return Code

C

Success Indicator: 0

Possible errors: None.

Assembler

   AX = Count of threads awakened.

   'Z'  Set or clear according to the contents of AX.

Remarks

ProcRun returns immediately to its caller; the awakened threads are run at the next available opportunity. ProcRun is often called at interrupt time. See ProcBlock for a more detailed discussion of blocking and running threads.

Example Code

C

#include  "dhcalls.h"

USHORT APIENTRY DevHelp_ProcRun( ULONG   EventId,
                                 PUSHORT AwakeCount)

Related Functions