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