ReactOS 0.4.16-dev-340-g0540c21
FxInterruptThreadpool Class Reference

#include <fxinterruptthreadpoolum.hpp>

Inheritance diagram for FxInterruptThreadpool:
Collaboration diagram for FxInterruptThreadpool:

Public Member Functions

 FxInterruptThreadpool (PFX_DRIVER_GLOBALS FxDriverGlobals)
 
 ~FxInterruptThreadpool ()
 
PTP_CALLBACK_ENVIRON GetCallbackEnvironment (VOID)
 
PTP_WAIT CreateThreadpoolWait (__in PTP_WAIT_CALLBACK pfnwa, __inout_opt PVOID Context)
 
HRESULT UpdateThreadPoolThreadLimits (_In_ ULONG InterruptCount)
 

Static Public Member Functions

static HRESULT _CreateAndInit (_In_ PFX_DRIVER_GLOBALS DriverGlobals, _Out_ FxInterruptThreadpool **ppThreadpool)
 

Private Member Functions

HRESULT Initialize ()
 
- Private Member Functions inherited from FxGlobalsStump
 FxGlobalsStump (__in PFX_DRIVER_GLOBALS FxDriverGlobals)
 
PFX_DRIVER_GLOBALS GetDriverGlobals (VOID)
 
- Private Member Functions inherited from FxStump
PVOID operator new (__in size_t Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals)
 
PVOID operator new (__in size_t Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in POOL_TYPE PoolType)
 
VOID operator delete (__in PVOID pointer)
 
PVOID operator new[] (__in size_t Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals)
 
VOID operator delete[] (__in PVOID pointer)
 
 FxStump (VOID)
 

Private Attributes

PTP_POOL m_Pool
 
TP_CALLBACK_ENVIRON m_CallbackEnvironment
 
ULONG m_MinimumThreadCount
 

Detailed Description

Definition at line 31 of file fxinterruptthreadpoolum.hpp.

Constructor & Destructor Documentation

◆ FxInterruptThreadpool()

FxInterruptThreadpool::FxInterruptThreadpool ( PFX_DRIVER_GLOBALS  FxDriverGlobals)

Definition at line 36 of file fxinterruptthreadpoolum.cpp.

38 :
39 FxGlobalsStump(FxDriverGlobals),
40 m_Pool(NULL),
42{
43 InitializeThreadpoolEnvironment(&m_CallbackEnvironment);
44}
TP_CALLBACK_ENVIRON m_CallbackEnvironment
#define NULL
Definition: types.h:112
#define MINIMUM_THREAD_COUNT_DEFAULT

◆ ~FxInterruptThreadpool()

FxInterruptThreadpool::~FxInterruptThreadpool ( )

Definition at line 46 of file fxinterruptthreadpoolum.cpp.

47{
48 //
49 // close pool
50 //
51 if (m_Pool != NULL) {
52 CloseThreadpool(m_Pool);
53 m_Pool = NULL;
54 }
55
56 DestroyThreadpoolEnvironment(&m_CallbackEnvironment);
57}

Member Function Documentation

◆ _CreateAndInit()

HRESULT FxInterruptThreadpool::_CreateAndInit ( _In_ PFX_DRIVER_GLOBALS  DriverGlobals,
_Out_ FxInterruptThreadpool **  ppThreadpool 
)
static

Definition at line 60 of file fxinterruptthreadpoolum.cpp.

64{
65 HRESULT hr;
67
68 FX_VERIFY_WITH_NAME(INTERNAL, CHECK_NOT_NULL(ppThreadpool),
69 DriverGlobals->Public.DriverName);
70
71 *ppThreadpool = NULL;
72
74 if (pool == NULL)
75 {
79 "FxInterruptThreadpool creation failed, "
80 "%!hresult!", hr);
81 return hr;
82 }
83
84 hr = pool->Initialize();
85
86 if (SUCCEEDED(hr))
87 {
88 *ppThreadpool = pool;
89 }
90 else {
91 delete pool;
92 }
93
94 return hr;
95}
#define TRACINGPNP
Definition: dbgtrace.h:67
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
FX_VERIFY_WITH_NAME(DRIVER(BadArgument, TODO), CHECK(ERROR_STRING_HW_ACCESS_NOT_ALLOWED,(pDevice->IsDirectHardwareAccessAllowed()==TRUE)), DriverGlobals->DriverName)
DriverGlobals
#define SUCCEEDED(hr)
Definition: intsafe.h:50
HRESULT hr
Definition: shlfolder.c:183
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27

◆ CreateThreadpoolWait()

PTP_WAIT FxInterruptThreadpool::CreateThreadpoolWait ( __in PTP_WAIT_CALLBACK  pfnwa,
__inout_opt PVOID  Context 
)
inline

Definition at line 80 of file fxinterruptthreadpoolum.hpp.

84 {
85 return ::CreateThreadpoolWait(pfnwa, Context, &m_CallbackEnvironment);
86 }

◆ GetCallbackEnvironment()

PTP_CALLBACK_ENVIRON FxInterruptThreadpool::GetCallbackEnvironment ( VOID  )
inline

Definition at line 72 of file fxinterruptthreadpoolum.hpp.

75 {
77 }

◆ Initialize()

HRESULT FxInterruptThreadpool::Initialize ( )
private

Definition at line 98 of file fxinterruptthreadpoolum.cpp.

100{
101 HRESULT hr = S_OK;
102 DWORD error;
103 BOOL bRet;
104
105 //
106 // Create a thread pool using win32 APIs
107 //
108 m_Pool = CreateThreadpool(NULL);
109 if (m_Pool == NULL)
110 {
115 "Threadpool creation failed, %!winerr!", error);
116 return hr;
117 }
118
119 //
120 // Set maximum thread count to equal the total number of interrupts.
121 // Set minimum thread count (persistent threads) to equal the lower of
122 // number of interrupt and number of processors.
123 //
124 // We want minimum number of persistent threads to be at least equal to the
125 // number of interrupt objects so that there is no delay in servicing the
126 // interrupt if there are processors available (the delay can come due to
127 // thread pool delay in allocating and initializing a new thread). However,
128 // there is not much benefit in having more persistent threads than
129 // processors, as threads would have to wait for processor to become
130 // available anyways. Therefore, we chose to have the number of persistent
131 // equal to the Min(number of interrupts, number of processors).
132 //
133 // In the current design, if there are more interrupts than
134 // processors, as soon as one thread finishes servicing the interrupt, both
135 // the thread and processor will be available to service the next queued
136 // interrupt. Note that thread pool will queue all the waits and will
137 // satisfy them in a FIFO manner.
138 //
139 // Since we don't know the number of interrupts in the beginning, we will
140 // start with one and update it when we know the actual number of interrupts
141 // after processing driver's OnPrepareHardware callback.
142 //
143 // Note on interrupt servicing:
144 // When fx connects the interrupt, it queues an event-based wait block
145 // to thread pool for each interrupt, so that the interrupt can get serviced
146 // using one of the thread pool threads when the auto-reset event shared
147 // with reflector is set by reflector in the DpcForIsr routine queued by Isr.
148 // While the interrupt is being serviced by one of the threads, no wait block
149 // is queued to thread pool for that interrupt, so arrival of same interrupt
150 // signals the event in DpcForIsr but doesn't cause new threads to pick up
151 // the servicing. Note that other interrupts still have their wait blocks
152 // queued so they will be serviced as they arrive.
153 //
154 // When previous servicing is over (i.e. the ISR callback has been
155 // invoked and it has returned), Fx queues another wait block to thread pool
156 // for that interrupt. If the event is already signalled, it would result in
157 // the same thread (or another) picking up servicing immediately.
158 //
159 // This means the interrupt ISR routine can never run concurrently
160 // for same interrupt. Therefore, there is no need to have more than one
161 // thread for each interrupt.
162 //
163 SetThreadpoolThreadMaximum(m_Pool, 1);
164
165 //
166 // Create one persistent thread since atleast one interrupt is the most
167 // likely scenario. We will update this number to have either the same
168 // number of threads as there are interrupts, or the number of
169 // processors on the machine.
170 //
171 bRet = SetThreadpoolThreadMinimum(m_Pool, m_MinimumThreadCount);
172 if (bRet == FALSE) {
177 "%!FUNC!: Failed to set minimum threads (%d) in threadpool,"
178 " %!winerr!", m_MinimumThreadCount, error);
179 goto cleanup;
180 }
181
182 //
183 // Associate thread pool with callback environment.
184 //
185 SetThreadpoolCallbackPool(&m_CallbackEnvironment, m_Pool);
186
187cleanup:
188
189 if (FAILED(hr)) {
190 CloseThreadpool(m_Pool);
191 m_Pool = NULL;
192 }
193
194 return hr;
195}
#define FALSE
Definition: types.h:117
static void cleanup(void)
Definition: main.c:1335
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
#define error(str)
Definition: mkdosfs.c:1605
PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxstump.hpp:98
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92

◆ UpdateThreadPoolThreadLimits()

HRESULT FxInterruptThreadpool::UpdateThreadPoolThreadLimits ( _In_ ULONG  InterruptCount)

Definition at line 198 of file fxinterruptthreadpoolum.cpp.

201{
202 BOOL bRet;
203 HRESULT hr = S_OK;
204 SYSTEM_INFO sysInfo;
205 ULONG minThreadCount = 0;
206 ULONG procs;
207 DWORD error;
208
209 FX_VERIFY(INTERNAL, CHECK_NOT_NULL(m_Pool));
210
211 //
212 // if there are more than one interrupts then we need to update minimum
213 // thread count.
214 //
215 if (m_MinimumThreadCount >= InterruptCount) {
216 //
217 // nothing to do
218 //
219 return S_OK;
220 }
221
222 //
223 // We want to have number of minimum persistent threads
224 // = Min(number of interrupts, number of processors).
225 // See comments in Initialize routine for details.
226 //
227 GetSystemInfo(&sysInfo);
228 procs = sysInfo.dwNumberOfProcessors;
229
230 minThreadCount = min(InterruptCount, procs);
231
232 if (m_MinimumThreadCount < minThreadCount) {
233 //
234 // Set threadpool min
235 //
236 bRet = SetThreadpoolThreadMinimum(m_Pool, minThreadCount);
237 if (bRet == FALSE) {
242 "Failed to set minimum threads in threadpool,"
243 " TP_POOL 0x%p to %d %!winerr!", m_Pool, minThreadCount,
244 error);
245 return hr;
246 }
247
248 m_MinimumThreadCount = minThreadCount;
249 }
250
251 //
252 // set thread pool max to max number of interrupts
253 //
254 SetThreadpoolThreadMaximum(m_Pool, InterruptCount);
255
258 "Threads in thread pool TP_POOL 0x%p updated"
259 " to Max %d Min %d threads", m_Pool,
260 InterruptCount, minThreadCount);
261
262 return hr;
263}
VOID WINAPI GetSystemInfo(IN LPSYSTEM_INFO lpSystemInfo)
Definition: sysinfo.c:143
FX_VERIFY(INTERNAL, CHECK_NOT_NULL(LoaderInterface->pIWudfHost))
#define min(a, b)
Definition: monoChain.cc:55
DWORD dwNumberOfProcessors
Definition: winbase.h:1202
uint32_t ULONG
Definition: typedefs.h:59

Member Data Documentation

◆ m_CallbackEnvironment

TP_CALLBACK_ENVIRON FxInterruptThreadpool::m_CallbackEnvironment
private

◆ m_MinimumThreadCount

ULONG FxInterruptThreadpool::m_MinimumThreadCount
private

Definition at line 49 of file fxinterruptthreadpoolum.hpp.

Referenced by Initialize(), and UpdateThreadPoolThreadLimits().

◆ m_Pool

PTP_POOL FxInterruptThreadpool::m_Pool
private

The documentation for this class was generated from the following files: