Table of Contents

Enum ThreadWaitReason

Namespace
Typhon.Profiler
Assembly
Typhon.Profiler.dll

Reason a thread left the CPU at a context-switch point. Hand-rolled mirror of Windows' KWAIT_REASON kernel enum (a.k.a. KTHREAD::WaitReason), captured by the ETW scheduling pump from CSwitchTraceData.OldThreadWaitReason and carried on ThreadContextSwitch records.

public enum ThreadWaitReason : byte

Fields

DelayExecution = 4

Delay-execution wait (e.g. KeDelayExecutionThread).

Executive = 0

Waiting on a generic kernel object (event, mutex, semaphore, I/O completion). Most common "I'm blocked" reason.

FreePage = 1

Backing pages need to be brought in before the thread can run.

MaximumWaitReason = 37

Sentinel for values outside the kernel range observed at runtime — surfaces "unknown reason" in the viewer.

PageIn = 2

Page-in for code/data is in flight.

PoolAllocation = 3

System allocation / mapping operation in progress.

Suspended = 5

Suspended via SuspendThread / debugger break-in.

UserRequest = 6

Explicit user-mode wait (Sleep, WaitForSingleObject, etc.).

WrCalloutStack = 25

Calling out — heap manager / debugger callout in progress.

WrCpuRateControl = 24

CPU rate-control throttle.

WrDelayExecution = 11

Wr-prefixed mirror of DelayExecution.

WrDispatchInt = 31

Dispatch interrupt — switched via DPC/dispatch.

WrExecutive = 7

Wr-prefixed mirror of Executive — currently blocked on a kernel object.

WrFastMutex = 34

Fast-mutex (FMUTEX) blocking.

WrFreePage = 8

Wr-prefixed mirror of FreePage.

WrGuardedMutex = 35

Guarded mutex blocking — guarded regions disable APC delivery while held.

WrKernel = 26

Kernel mutex blocking.

WrKeyedEvent = 21

Push-lock acquire (lightweight reader/writer lock).

WrLpcReceive = 16

LPC (Local Procedure Call) receive — waiting for a request.

WrLpcReply = 17

LPC reply wait — waiting for the responder.

WrMutex = 29

Kernel mutex blocking (KMUTEX).

WrPageIn = 9

Wr-prefixed mirror of PageIn — paging stall.

WrPageOut = 19

Page-write completion.

WrPoolAllocation = 10

Wr-prefixed mirror of PoolAllocation.

WrPreempted = 32

Preempted by a higher-priority thread.

WrProcessInSwap = 23

Processor-affinity / hot-removal pause.

WrPushLock = 28

Push-lock (ERESOURCE-style fast lock) blocking.

WrQuantumEnd = 30

Quantum end — the thread used up its scheduling quantum. Pure CPU pressure indicator.

WrQueue = 15

Queue wait — typically a threadpool worker waiting for work, or an IO completion port.

WrRendezvous = 20

Lazy-mapping operation in progress.

WrResource = 27

Resource manager I/O wait.

WrRundown = 36

Object-rundown protection wait.

WrSpare0 = 14

Spare slot from the kernel definition; retained for wire stability.

WrSuspended = 12

Wr-prefixed mirror of Suspended.

WrTerminated = 22

Terminated — thread is exiting.

WrUserRequest = 13

Wr-prefixed mirror of UserRequest — explicit user-mode wait.

WrVirtualMemory = 18

Waiting for virtual-memory commit / fault resolution.

WrYieldExecution = 33

Voluntary SwitchToThread / Yield.

Remarks

Wire stability: numeric values are part of the .typhon-trace file format — never renumber. Mirror of the kernel enum as of Windows 11 24H2; newer Windows builds may append entries (e.g. WrPhysicalFault) that we do not currently mirror. Out-of-range values land on MaximumWaitReason at decode time so the viewer can still display the slice with an "unknown reason" label.

Naming: Microsoft uses two conventions in the same enum. Unprefixed names (e.g. Executive, UserRequest) describe the kernel object family the thread is transitioning into a wait on. Wr-prefixed variants (e.g. WrExecutive, WrUserRequest) describe the kernel object family the thread is currently blocked on while in the Wait state. In practice the pairs are observed together as (threadState, waitReason) tuples; the viewer collapses them into a single label.

Most informative values for the viewer: