include vmm.inc
VMMCall _BlockOnID, <ThreadID, Flags>
Records the identifier (ID) to be used to block the current thread. The actual blockage of a thread is signaled with _SignalID. Uses the C calling convention. Uses flags.
Value | Meaning |
---|---|
Block_Enable_Ints | Service interrupts in the virtual machine even if it does not currently have interrupts enabled. This forces interrupts to be enabled. This value is only relevant if either Block_Svc_Ints or Block_Svc_If_Ints is set. |
Block_Svc_If_Ints_Locked | Service interrupts in the virtual machine even if the virtual machine is blocked, and the VMStat_V86IntsLocked flag is set. |
Block_Svc_Ints | Service interrupts in the virtual machine even if the virtual machine is blocked. |
Block_Thread_Idle | Consider the thread to be idle if it blocks for the critical section. |
Typically, the ThreadID consists of 32-bit linear address of something related to the object being blocked on, because that helps ensure uniqueness. When the same ID is passed to SignalID, the blocked thread reawakens. When a thread reawakens, it must check whether the wakeup was valid or spurious.
This service always blocks the current thread on the ID passed. Multiple threads may block on the same ID. When the ID is signaled with _SignalID all of the threads currently blocked on the ID will unblock.
Block IDs are not guaranteed to be unique to the caller; an unrelated piece of code may signal the ID in order to awaken a thread that it has blocked and cause this one to be spuriously awakened. Therefore when this service returns the caller must check for a spurious wake up and call _BlockOnID again if this has occurred. Typically a user maintained flag is used for this. The flag is set before calling _BlockOnID the first time and cleared when _SignalID is called.
The Block ID is traditionally the address of an object somehow related to the reason why the virtual device needs to block. Be aware of race conditions that may occur if _BlockOnID is called after the ID is signaled. For example, if a virtual device initiates an operation, it may be that the operation completes and the Block ID is signaled before the virtual device gets to call _BlockOnID to wait for the signal. The virtual device ends up blocking waiting for a signal that has already arrived.
_SignalID