ReactOS  0.4.15-dev-3295-gaa8fc87
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 }
FxGlobalsStump(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
Definition: fxstump.hpp:90
TP_CALLBACK_ENVIRON m_CallbackEnvironment
#define NULL
Definition: types.h:112
#define MINIMUM_THREAD_COUNT_DEFAULT

Referenced by _CreateAndInit().

◆ ~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 }
TP_CALLBACK_ENVIRON m_CallbackEnvironment
#define NULL
Definition: types.h:112

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 }
HRESULT hr
Definition: shlfolder.c:183
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
DriverGlobals
FX_VERIFY_WITH_NAME(DRIVER(BadArgument, TODO), CHECK(ERROR_STRING_HW_ACCESS_NOT_ALLOWED,(pDevice->IsDirectHardwareAccessAllowed()==TRUE)), DriverGlobals->DriverName)
if SUCCEEDED(hr)
LONG HRESULT
Definition: typedefs.h:79
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define TRACINGPNP
Definition: dbgtrace.h:67
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
FxInterruptThreadpool(PFX_DRIVER_GLOBALS FxDriverGlobals)

◆ 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  }
TP_CALLBACK_ENVIRON m_CallbackEnvironment

◆ GetCallbackEnvironment()

PTP_CALLBACK_ENVIRON FxInterruptThreadpool::GetCallbackEnvironment ( VOID  )
inline

Definition at line 72 of file fxinterruptthreadpoolum.hpp.

75  {
76  return &m_CallbackEnvironment;
77  }
TP_CALLBACK_ENVIRON m_CallbackEnvironment

◆ 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  {
111  error = GetLastError();
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) {
173  error = GetLastError();
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 
187 cleanup:
188 
189  if (FAILED(hr)) {
190  CloseThreadpool(m_Pool);
191  m_Pool = NULL;
192  }
193 
194  return hr;
195 }
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
HRESULT hr
Definition: shlfolder.c:183
#define error(str)
Definition: mkdosfs.c:1605
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
LONG HRESULT
Definition: typedefs.h:79
unsigned long DWORD
Definition: ntddk_ex.h:95
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define TRACINGPNP
Definition: dbgtrace.h:67
#define S_OK
Definition: intsafe.h:52
TP_CALLBACK_ENVIRON m_CallbackEnvironment
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
char * cleanup(char *str)
Definition: wpickclick.c:99
PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxstump.hpp:98

◆ 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) {
238  error = GetLastError();
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 }
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
HRESULT hr
Definition: shlfolder.c:183
#define error(str)
Definition: mkdosfs.c:1605
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
FX_VERIFY(INTERNAL, CHECK_NOT_NULL(LoaderInterface->pIWudfHost))
LONG HRESULT
Definition: typedefs.h:79
unsigned long DWORD
Definition: ntddk_ex.h:95
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define TRACINGPNP
Definition: dbgtrace.h:67
#define S_OK
Definition: intsafe.h:52
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
VOID WINAPI GetSystemInfo(IN LPSYSTEM_INFO lpSystemInfo)
Definition: sysinfo.c:142
#define min(a, b)
Definition: monoChain.cc:55
DWORD dwNumberOfProcessors
Definition: winbase.h:1159
unsigned int ULONG
Definition: retypes.h:1
PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxstump.hpp:98

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: