ReactOS 0.4.17-dev-1281-g065abb3
workitem.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS USB Host Controller Extension
3 * LICENSE: MIT (https://spdx.org/licenses/MIT)
4 * PURPOSE: Forward progress work items
5 * COPYRIGHT: Copyright 2026 Justin Miller <justin.miller@reactos.org>
6 */
7
8#include "ucx01000.h"
9
10#define NDEBUG
11#include <debug.h>
12
13static IO_WORKITEM_ROUTINE_EX UcxWorkItemIoRoutine;
14
20{
22
24 if (Item == NULL)
25 {
26 DPRINT1("Controller %p work item allocation failed\n", Controller);
27 return NULL;
28 }
29
31 if (Item->IoWorkItem == NULL)
32 {
33 DPRINT1("Controller %p IO work item allocation failed for %p\n", Controller, DeviceObject);
35 return NULL;
36 }
37
38 Item->Controller = Controller;
39 Item->DeviceObject = DeviceObject;
42 Item->NeedsFlush = (Flags & UCXHUB_WORKITEM_FLAG_NEEDS_FLUSH) != 0;
43
44 return Item;
45}
46
48VOID
50{
53}
54
55VOID
60{
62
63 NT_ASSERT(!this->Queued && Routine == NULL);
64
65 Routine = NewRoutine;
67 this->Queued = TRUE;
68
69 if (NeedsFlush)
70 {
71 SpinLockGuard Guard(&Lock);
72
75 }
76
77 if (UcxDriver.IoTryQueueWorkItem != NULL)
79
80 if (Queued)
81 return;
82
83 /* The worker pool is out of threads; fall back to the controller's own thread */
85 {
87 }
88 else
89 {
90 DPRINT("Work item %p sent to controller %p system thread\n", this, Controller);
91 Controller->QueueOnWorkerThread(this);
92 }
93}
94
96VOID
98{
99 PAGED_CODE();
100
101 if (!NeedsFlush)
102 {
103 DPRINT1("Flush on work item %p allocated without flush support\n", this);
105 return;
106 }
107
109
110 /* The runner signals Idle while holding the lock; let it leave */
111 SpinLockGuard Guard(&Lock);
112}
113
114VOID
116{
117 PUCXHUB_WORKITEM_ROUTINE RunRoutine;
119 PVOID RunContext;
121
122 Queued = FALSE;
123 RunRoutine = Routine;
124 RunContext = RoutineContext;
125 Routine = NULL;
127
128 /* Keeps the owner of the device object loaded across its own callback */
131 RunRoutine(Object, RunContext, this);
133
134 /* Without flush support the routine may already have freed the item */
135 if (Flush)
136 {
137 SpinLockGuard Guard(&Lock);
138
139 if (--RunningCount == 0)
141 }
142}
143
144static
145VOID
146NTAPI
151{
154
155 ((UcxWorkItem*)Context)->Run();
156}
#define PAGED_CODE()
unsigned char BOOLEAN
Definition: actypes.h:127
#define DPRINT1
Definition: precomp.h:8
_In_ D3DDDI_VIDEO_PRESENT_TARGET_ID _In_ ULONG _In_ ULONG Flags
Definition: dispmprt.h:245
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
InitializeListHead & UcxDriver
Definition: driver.cpp:138
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define NonPagedPool
Definition: env_spec_w32.h:307
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
_In_ FLT_SET_CONTEXT_OPERATION _In_ PFLT_CONTEXT NewContext
Definition: fltkernel.h:1468
UCXHUB_WORKITEM_ROUTINE * PUCXHUB_WORKITEM_ROUTINE
Definition: hubucx.h:228
enum _UCXHUB_WORKITEM_ENQUEUE_OPTIONS UCXHUB_WORKITEM_ENQUEUE_OPTIONS
@ UcxHubWorkItemForwardProgressNotRequired
Definition: hubucx.h:217
#define UCXHUB_WORKITEM_FLAG_NEEDS_FLUSH
Definition: hubucx.h:212
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
Definition: iowork.c:64
PIO_WORKITEM NTAPI IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
Definition: iowork.c:75
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
Definition: kse.h:81
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
static PVOID ExAllocatePoolZero(ULONG PoolType, SIZE_T NumberOfBytes, ULONG Tag)
Definition: precomp.h:45
#define KernelMode
Definition: asm.h:38
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
@ NotificationEvent
NTKRNLVISTAAPI VOID NTAPI IoQueueWorkItemEx(_Inout_ PIO_WORKITEM IoWorkItem, _In_ PIO_WORKITEM_ROUTINE_EX WorkerRoutine, _In_ WORK_QUEUE_TYPE QueueType, _In_opt_ __drv_aliasesMem PVOID Context)
Definition: io.c:55
#define DPRINT
Definition: sndvol32.h:73
static PUCXHUB_WORKITEM Allocate(_In_ UcxController *Controller, _In_ PDEVICE_OBJECT DeviceObject, _In_ ULONG Flags)
Definition: workitem.cpp:16
PVOID RoutineContext
Definition: hostctl.h:55
PUCXHUB_WORKITEM_ROUTINE Routine
Definition: hostctl.h:54
VOID Enqueue(_In_ PUCXHUB_WORKITEM_ROUTINE NewRoutine, _In_opt_ PVOID NewContext, _In_ UCXHUB_WORKITEM_ENQUEUE_OPTIONS Options)
Definition: workitem.cpp:56
ULONG RunningCount
Definition: hostctl.h:57
PDEVICE_OBJECT DeviceObject
Definition: hostctl.h:52
KEVENT Idle
Definition: hostctl.h:58
BOOLEAN NeedsFlush
Definition: hostctl.h:59
BOOLEAN Queued
Definition: hostctl.h:60
UcxController * Controller
Definition: hostctl.h:51
#define NTAPI
Definition: typedefs.h:36
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ PUCX_CONTROLLER_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ UCXCONTROLLER * Controller
#define UCX_POOL_TAG
Definition: ucxutil.h:11
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
_In_ WDFCOLLECTION _In_ WDFOBJECT Item
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2061
_In_ PWDFDEVICE_INIT _In_ PWDF_REMOVE_LOCK_OPTIONS Options
Definition: wdfdevice.h:3540
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:127
static IO_WORKITEM_ROUTINE_EX UcxWorkItemIoRoutine
Definition: workitem.cpp:13
@ DelayedWorkQueue
Definition: extypes.h:190
_In_ PVOID IoObject
Definition: iotypes.h:467
#define IO_NO_INCREMENT
Definition: iotypes.h:598
_In_opt_ PVOID _In_ PIO_WORKITEM IoWorkItem
Definition: iotypes.h:521
@ Executive
Definition: ketypes.h:467
#define ObDereferenceObject
Definition: obfuncs.h:203
#define ObReferenceObject
Definition: obfuncs.h:204
#define NT_ASSERT
Definition: rtlfuncs.h:3334