class DpcRunner
Defined at line 54 of file ../../zircon/kernel/include/kernel/dpc.h
A DpcRunner is responsible for running queued Dpcs. Under the hood, a given runner may manage
multiple independent queues of Dpcs.
Each cpu maintains a DpcRunner, in its percpu structure.
Public Methods
void InitForCurrentCpu ()
Initializes this DpcRunner for the current cpu.
The calling thread must have hard-affinity to exactly one CPU.
Defined at line 43 of file ../../zircon/kernel/kernel/dpc.cc
zx_status_t Shutdown (zx_instant_mono_t deadline)
Begins the DpcRunner shutdown process.
Shutting down a DpcRunner is a two-phase process. This is the first phase. See
|TransitionOffCpu| for the second phase.
This method:
- tells the owning cpu's DpcRunner's thread to stop servicing its queue then
- waits, up to |deadline|, for it to finish any in-progress DPC and join
Because this method blocks until the thread has terminated, it is critical that the caller
not hold any locks that might be needed by any previously queued DPCs. Otheriwse, deadlock may
occur.
Upon successful completion, this DpcRunner may contain unexecuted DPCs and new ones may be
added by |Enqueue|. However, they will not execute (on any cpu) until |TransitionOffCpu| is
called.
Once |Shutdown| has completed successfully, finish the shutdown process by calling
|TransitionOffCpu| on some cpu other than the owning cpu.
If |Shutdown| fails, this DpcRunner is left in an undefined state and
|TransitionOffCpu| must not be called.
Defined at line 71 of file ../../zircon/kernel/kernel/dpc.cc
void TransitionOffCpu (DpcRunner & source)
Moves queued Dpcs from |source| to this DpcRunner.
This is the second phase of Dpc shutdown. See |Shutdown|.
This must only be called after |Shutdown| has completed successfully.
This must only be called on the current cpu.
Defined at line 79 of file ../../zircon/kernel/kernel/dpc.cc
zx_status_t Enqueue (Dpc & dpc, QueueType type)
Enqueue |dpc| in the specified queue |type| and signal its worker thread to execute it.
|Enqueue| will not block, but it may wait briefly for a spinlock.
|Enqueue| may return before or after the Dpc has executed. It is the
caller's responsibility to ensure that a queued Dpc object is not destroyed
prior to its execution.
Note: it is important that the thread calling Enqueue() not be holding its
own lock if there is _any_ possibility that the DPC thread could be
involved in a PI interaction with the thread who is performing the enqueue
operation.
Returns ZX_ERR_ALREADY_EXISTS if |dpc| is already queued.
Defined at line 93 of file ../../zircon/kernel/kernel/dpc.cc
Enumerations
enum QueueType
| Name | Value |
|---|---|
| General | 0 |
| LowLatency | 1 |
Dpc are placed into different queues depending on their ServiceLevel. One queue for those that
need to execute with |LowLatency| (e.g. signaling a TimerDispatcher from interrupt context).
The other queue (|General|) is for the rest.
|LowLatency| Dpcs are executed by a thread with a high-bandwidth scheduler profile so take
care to avoid creating undesirable PI interactions. In other words, don't use |LowLatency|
unless you really need to, and be sure that the Dpc won't hold likely-to-be-contested locks for
a significant amount of time. See also https://fxbug.dev/395669867.
|General| Dpcs are serviced by a thread with a default scheduler profile.
Defined at line 104 of file ../../zircon/kernel/include/kernel/dpc.h