Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

576 lines
18 KiB

  1. /*++
  2. Copyright (c) 1989-1998 Microsoft Corporation
  3. Module Name:
  4. threads.h
  5. Abstract:
  6. This module is the header file for thread pools. Thread pools can be used for
  7. one time execution of tasks, for waits and for one shot or periodic timers.
  8. Author:
  9. Gurdeep Singh Pall (gurdeep) Nov 13, 1997
  10. Environment:
  11. The thread pool routines are statically linked in the caller's
  12. executable and are callable only from user mode. They make use of
  13. Nt system services.
  14. Revision History:
  15. Aug-19 lokeshs - modifications to thread pool apis.
  16. Rob Earhart (earhart) September 29, 2000
  17. Moved globals to threads.c
  18. Split up thread pools to seperate modules
  19. Moved module-specific interfaces to modules
  20. --*/
  21. //todo remove below
  22. #define DBG1 1
  23. // Structures used by the Thread pool
  24. // Timer structures
  25. // Timer Queues and Timer entries both use RTLP_GENERIC_TIMER structure below.
  26. // Timer Queues are linked using List.
  27. // Timers are attached to the Timer Queue using TimerList
  28. // Timers are linked to each other using List
  29. #define RTLP_TIMER RTLP_GENERIC_TIMER
  30. #define PRTLP_TIMER PRTLP_GENERIC_TIMER
  31. #define RTLP_TIMER_QUEUE RTLP_GENERIC_TIMER
  32. #define PRTLP_TIMER_QUEUE PRTLP_GENERIC_TIMER
  33. struct _RTLP_WAIT ;
  34. typedef struct _RTLP_GENERIC_TIMER {
  35. LIST_ENTRY List ; // All Timers and Queues are linked using this.
  36. ULONG DeltaFiringTime ; // Time difference in Milliseconds from the TIMER entry
  37. // just before this entry
  38. union {
  39. ULONG RefCount ; // Timer RefCount
  40. ULONG * RefCountPtr ; // Pointer to Wait->Refcount
  41. } ; // keeps count of async callbacks still executing
  42. ULONG State ; // State of timer: CREATED, DELETE, ACTIVE. DONT_FIRE
  43. union {
  44. // Used for Timer Queues
  45. struct {
  46. LIST_ENTRY TimerList ; // Timers Hanging off of the queue
  47. LIST_ENTRY UncancelledTimerList ;// List of one shot timers not cancelled
  48. // not used for wait timers
  49. #if DBG1
  50. ULONG NextDbgId;
  51. #endif
  52. } ;
  53. // Used for Timers
  54. struct {
  55. struct _RTLP_GENERIC_TIMER *Queue ;// Queue to which this timer belongs
  56. struct _RTLP_WAIT *Wait ; // Pointer to Wait event if timer is part of waits. else NULL
  57. ULONG Flags ; // Flags indicating special treatment for this timer
  58. PVOID Function ; // Function to call when timer fires
  59. PVOID Context ; // Context to pass to function when timer fires
  60. PACTIVATION_CONTEXT ActivationContext; // Activation context to activate around callbacks to Function
  61. ULONG Period ; // In Milliseconds. Used for periodic timers.
  62. LIST_ENTRY TimersToFireList;//placed in this list if the timer is fired
  63. HANDLE ImpersonationToken; // Token to use for callouts
  64. } ;
  65. } ;
  66. HANDLE CompletionEvent ; // Event signalled when the timer is finally deleted
  67. #if DBG1
  68. ULONG DbgId;
  69. ULONG ThreadId ;
  70. ULONG ThreadId2 ;
  71. #endif
  72. } RTLP_GENERIC_TIMER, *PRTLP_GENERIC_TIMER ;
  73. // Structures used by Wait Threads
  74. // Wait structure
  75. typedef struct _RTLP_WAIT {
  76. struct _RTLP_WAIT_THREAD_CONTROL_BLOCK *ThreadCB ;
  77. HANDLE WaitHandle ; // Object to wait on
  78. ULONG State ; // REGISTERED, ACTIVE,DELETE state flags
  79. ULONG RefCount ; // initially set to 1. When 0, then ready to be deleted
  80. HANDLE CompletionEvent ;
  81. struct _RTLP_GENERIC_TIMER *Timer ; // For timeouts on the wait
  82. ULONG Flags ; // Flags indicating special treatment for this wait
  83. PVOID Function ; // Function to call when wait completes
  84. PVOID Context ; // Context to pass to function
  85. ULONG Timeout ; // In Milliseconds.
  86. PACTIVATION_CONTEXT ActivationContext; // Activation context to activate around calls out to function
  87. HANDLE ImpersonationToken; // Token to use for callouts
  88. #if DBG1
  89. ULONG DbgId ;
  90. ULONG ThreadId ;
  91. ULONG ThreadId2 ;
  92. #endif
  93. } RTLP_WAIT, *PRTLP_WAIT ;
  94. // Wait Thread Control Block
  95. typedef struct _RTLP_WAIT_THREAD_CONTROL_BLOCK {
  96. LIST_ENTRY WaitThreadsList ;// List of all the thread control blocks
  97. HANDLE ThreadHandle ; // Handle for this thread
  98. ULONG ThreadId ; // Used to check if callback is in WaitThread
  99. ULONG NumWaits ; // Number of active waits + handles pending waits
  100. ULONG NumActiveWaits ; // Number of active waits (reflects ActiveWaitArray)
  101. ULONG NumRegisteredWaits ; // Number of waits that are registered
  102. HANDLE ActiveWaitArray[MAXIMUM_WAIT_OBJECTS] ;// Array used for waiting
  103. PRTLP_WAIT ActiveWaitPointers[MAXIMUM_WAIT_OBJECTS] ;// Array of pointers to active Wait blocks.
  104. HANDLE TimerHandle ; // Handle to the NT timer used for timeouts
  105. RTLP_TIMER_QUEUE TimerQueue;// Queue in which all timers are kept
  106. LARGE_INTEGER Current64BitTickCount ;
  107. LONGLONG Firing64BitTickCount ;
  108. RTL_CRITICAL_SECTION WaitThreadCriticalSection ;
  109. // Used for addition and deletion of waits
  110. } RTLP_WAIT_THREAD_CONTROL_BLOCK, *PRTLP_WAIT_THREAD_CONTROL_BLOCK ;
  111. // Structure used for attaching all I/O worker threads
  112. typedef struct _RTLP_IOWORKER_TCB {
  113. LIST_ENTRY List ; // List of IO Worker threads
  114. HANDLE ThreadHandle ; // Handle of this thread
  115. ULONG Flags ; // WT_EXECUTEINPERSISTENTIOTHREAD
  116. BOOLEAN LongFunctionFlag ;// Is the thread currently executing long fn
  117. } RTLP_IOWORKER_TCB, *PRTLP_IOWORKER_TCB ;
  118. typedef struct _RTLP_WAITWORKER {
  119. union {
  120. PRTLP_WAIT Wait ;
  121. PRTLP_TIMER Timer ;
  122. } ;
  123. BOOLEAN WaitThreadCallback ; //callback queued by Wait thread or Timer thread
  124. BOOLEAN TimerCondition ;//true if fired because wait timed out.
  125. } RTLP_ASYNC_CALLBACK, * PRTLP_ASYNC_CALLBACK ;
  126. // structure used for calling worker function
  127. typedef struct _RTLP_WORK {
  128. WORKERCALLBACKFUNC Function ;
  129. ULONG Flags ;
  130. PACTIVATION_CONTEXT ActivationContext;
  131. HANDLE ImpersonationToken;
  132. } RTLP_WORK, *PRTLP_WORK ;
  133. // Structure used for storing events. Note that Link is used as an
  134. // SLIST_ENTRY, however declaring it as such would unnecessarily pad
  135. // the RTLP_EVENT structure.
  136. typedef struct _RTLP_EVENT {
  137. SINGLE_LIST_ENTRY Link ;
  138. HANDLE Handle ;
  139. } RTLP_EVENT, *PRTLP_EVENT ;
  140. // Defines used in the thread pool
  141. #define THREAD_CREATION_DAMPING_TIME1 1000 // In Milliseconds. Time between starting successive threads.
  142. #define THREAD_CREATION_DAMPING_TIME2 15000 // In Milliseconds. Time between starting successive threads.
  143. #define THREAD_TERMINATION_DAMPING_TIME 10000 // In Milliseconds. Time between stopping successive threads.
  144. #define NEW_THREAD_THRESHOLD 7 // Number of requests outstanding before we start a new thread
  145. #define NEW_THREAD_THRESHOLD2 14
  146. #define MAX_WORKER_THREADS 1000 // Max effective worker threads
  147. #define INFINITE_TIME (ULONG)~0 // In milliseconds
  148. #define PSEUDO_INFINITE_TIME 0x80000000 // In milliseconds
  149. #define RTLP_MAX_TIMERS 0x00080000 // 524288 timers per process
  150. #define MAX_UNUSED_EVENTS 40
  151. #define NEEDS_IO_THREAD(Flags) (Flags & (WT_EXECUTEINIOTHREAD \
  152. | WT_EXECUTEINUITHREAD \
  153. | WT_EXECUTEINPERSISTENTIOTHREAD))
  154. // Macros
  155. #define ONE_MILLISECOND_TIMEOUT(TimeOut) { \
  156. TimeOut.LowPart = 0xffffd8f0 ; \
  157. TimeOut.HighPart = 0xffffffff ; \
  158. }
  159. #define HUNDRED_MILLISECOND_TIMEOUT(TimeOut) { \
  160. TimeOut.LowPart = 0xfff0bdc0 ; \
  161. TimeOut.HighPart = 0xffffffff ; \
  162. }
  163. #define ONE_SECOND_TIMEOUT(TimeOut) { \
  164. TimeOut.LowPart = 0xff676980 ; \
  165. TimeOut.HighPart = 0xffffffff ; \
  166. }
  167. #define USE_PROCESS_HEAP 1
  168. #define RtlpFreeTPHeap(Ptr) \
  169. RtlFreeHeap( RtlProcessHeap(), 0, (Ptr) )
  170. #define RtlpAllocateTPHeap(Size, Flags) \
  171. RtlAllocateHeap( RtlProcessHeap(), (Flags), (Size) )
  172. // used to allocate Wait thread
  173. #define ACQUIRE_GLOBAL_WAIT_LOCK() \
  174. RtlEnterCriticalSection (&WaitCriticalSection)
  175. #define RELEASE_GLOBAL_WAIT_LOCK() \
  176. RtlLeaveCriticalSection(&WaitCriticalSection)
  177. // taken before a timer/queue is deleted and when the timers
  178. // are being fired. Used to assure that no timers will be fired later.
  179. #define ACQUIRE_GLOBAL_TIMER_LOCK() \
  180. RtlEnterCriticalSection (&TimerCriticalSection)
  181. #define RELEASE_GLOBAL_TIMER_LOCK() \
  182. RtlLeaveCriticalSection(&TimerCriticalSection)
  183. // used in RtlpThreadPoolCleanup to find if a component is initialized
  184. #define IS_COMPONENT_INITIALIZED(StartedVariable, CompletedVariable, Flag) \
  185. {\
  186. LARGE_INTEGER TimeOut ; \
  187. Flag = FALSE ; \
  188. \
  189. if ( StartedVariable ) { \
  190. \
  191. if ( !CompletedVariable ) { \
  192. \
  193. ONE_MILLISECOND_TIMEOUT(TimeOut) ; \
  194. \
  195. while (!*((ULONG volatile *)&CompletedVariable)) \
  196. NtDelayExecution (FALSE, &TimeOut) ; \
  197. \
  198. if (CompletedVariable == 1) \
  199. Flag = TRUE ; \
  200. \
  201. } else { \
  202. Flag = TRUE ; \
  203. } \
  204. } \
  205. }
  206. // macro used to set dbg function/context
  207. #define DBG_SET_FUNCTION(Fn, Context) { \
  208. CallbackFn1 = CallbackFn2 ; \
  209. CallbackFn2 = (Fn) ; \
  210. Context1 = Context2 ; \
  211. Context2 = (Context ) ; \
  212. }
  213. // used to move the wait array
  214. /*
  215. VOID
  216. RtlpShiftWaitArray(
  217. PRTLP_WAIT_THREAD_CONTROL_BLOCK ThreadCB ThreadCB,
  218. ULONG SrcIndex,
  219. ULONG DstIndex,
  220. ULONG Count
  221. )
  222. */
  223. #define RtlpShiftWaitArray(ThreadCB, SrcIndex, DstIndex, Count) { \
  224. \
  225. RtlMoveMemory (&(ThreadCB)->ActiveWaitArray[DstIndex], \
  226. &(ThreadCB)->ActiveWaitArray[SrcIndex], \
  227. sizeof (HANDLE) * (Count)) ; \
  228. \
  229. RtlMoveMemory (&(ThreadCB)->ActiveWaitPointers[DstIndex],\
  230. &(ThreadCB)->ActiveWaitPointers[SrcIndex],\
  231. sizeof (HANDLE) * (Count)) ; \
  232. }
  233. // signature for timer and wait entries
  234. #define SET_WAIT_SIGNATURE(ptr) RtlInterlockedSetBitsDiscardReturn(&(ptr)->State, 0xfedc0100)
  235. #define SET_TIMER_SIGNATURE(ptr) RtlInterlockedSetBitsDiscardReturn(&(ptr)->State, 0xfedc0200)
  236. #define SET_TIMER_QUEUE_SIGNATURE(ptr) RtlInterlockedSetBitsDiscardReturn(&(ptr)->State, 0xfedc0300)
  237. #define IS_WAIT_SIGNATURE(ptr) (((ptr)->State & 0x00000f00) == 0x00000100)
  238. #define IS_TIMER_SIGNATURE(ptr) (((ptr)->State & 0x00000f00) == 0x00000200)
  239. #define CHECK_SIGNATURE(ptr) ASSERTMSG( InvalidSignatureMsg, \
  240. ((ptr)->State & 0xffff0000) == 0xfedc0000 )
  241. #define SET_DEL_SIGNATURE(ptr) RtlInterlockedSetBitsDiscardReturn(&(ptr)->State, 0x00009000)
  242. #define SET_DEL_PENDING_SIGNATURE(ptr) RtlInterlockedSetBitsDiscardReturn(&(ptr)->State, 0x00002000)
  243. #define CHECK_DEL_SIGNATURE(ptr) ASSERTMSG( InvalidDelSignatureMsg, \
  244. (((ptr)->State & 0xffff0000) == 0xfedc0000) \
  245. && ( ! ((ptr)->State & 0x00009000)) )
  246. #define CHECK_DEL_PENDING_SIGNATURE(ptr) ASSERTMSG( InvalidDelSignatureMsg, \
  247. (((ptr)->State & 0xffff0000) == 0xfedc0000) \
  248. && ( ! ((ptr)->State & 0x0000f000)) )
  249. #define IS_DEL_SIGNATURE_SET(ptr) ((ptr)->State & 0x00009000)
  250. #define IS_DEL_PENDING_SIGNATURE_SET(ptr) ((ptr)->State & 0x00002000)
  251. #define CLEAR_SIGNATURE(ptr) RtlInterlockedSetClearBits(&(ptr)->State, \
  252. 0xcdef0000, \
  253. 0xfedc0000 & ~(0xcdef0000))
  254. #define SET_DEL_TIMERQ_SIGNATURE(ptr) RtlInterlockedSetBitsDiscardReturn(&(ptr)->State, 0x00000a00)
  255. // debug prints
  256. #define RTLP_THREADPOOL_ERROR_MASK (0x01 | DPFLTR_MASK)
  257. #define RTLP_THREADPOOL_WARNING_MASK (0x02 | DPFLTR_MASK)
  258. #define RTLP_THREADPOOL_INFO_MASK (0x04 | DPFLTR_MASK)
  259. #define RTLP_THREADPOOL_TRACE_MASK (0x08 | DPFLTR_MASK)
  260. #define RTLP_THREADPOOL_VERBOSE_MASK (0x10 | DPFLTR_MASK)
  261. #if DBG
  262. extern CHAR InvalidSignatureMsg[];
  263. extern CHAR InvalidDelSignatureMsg[];
  264. #endif
  265. extern ULONG MaxThreads;
  266. extern BOOLEAN LdrpShutdownInProgress;
  267. NTSTATUS
  268. NTAPI
  269. RtlpStartThreadpoolThread(
  270. PUSER_THREAD_START_ROUTINE Function,
  271. PVOID Parameter,
  272. HANDLE *ThreadHandleReturn
  273. );
  274. extern PRTLP_EXIT_THREAD RtlpExitThreadFunc;
  275. #if DBG1
  276. extern PVOID CallbackFn1, CallbackFn2, Context1, Context2 ;
  277. #endif
  278. // Timer globals needed by worker
  279. extern ULONG StartedTimerInitialization ; // Used by Timer thread startup synchronization
  280. extern ULONG CompletedTimerInitialization ; // Used for to check if Timer thread is initialized
  281. extern HANDLE TimerThreadHandle;
  282. VOID
  283. RtlpAsyncWaitCallbackCompletion(
  284. IN PVOID Context
  285. );
  286. NTSTATUS
  287. RtlpInitializeTimerThreadPool (
  288. ) ;
  289. NTSTATUS
  290. RtlpTimerCleanup(
  291. VOID
  292. );
  293. NTSYSAPI
  294. NTSTATUS
  295. NTAPI
  296. RtlpWaitCleanup(
  297. VOID
  298. );
  299. NTSYSAPI
  300. NTSTATUS
  301. NTAPI
  302. RtlpWorkerCleanup(
  303. VOID
  304. );
  305. NTSYSAPI
  306. VOID
  307. NTAPI
  308. RtlpThreadCleanup (
  309. VOID
  310. );
  311. VOID
  312. RtlpResetTimer (
  313. HANDLE TimerHandle,
  314. ULONG DueTime,
  315. PRTLP_WAIT_THREAD_CONTROL_BLOCK ThreadCB
  316. ) ;
  317. BOOLEAN
  318. RtlpInsertInDeltaList (
  319. PLIST_ENTRY DeltaList,
  320. PRTLP_GENERIC_TIMER NewTimer,
  321. ULONG TimeRemaining,
  322. ULONG *NewFiringTime
  323. ) ;
  324. BOOLEAN
  325. RtlpRemoveFromDeltaList (
  326. PLIST_ENTRY DeltaList,
  327. PRTLP_GENERIC_TIMER Timer,
  328. ULONG TimeRemaining,
  329. ULONG* NewFiringTime
  330. ) ;
  331. BOOLEAN
  332. RtlpReOrderDeltaList (
  333. PLIST_ENTRY DeltaList,
  334. PRTLP_GENERIC_TIMER Timer,
  335. ULONG TimeRemaining,
  336. ULONG* NewFiringTime,
  337. ULONG ChangedFiringTime
  338. ) ;
  339. NTSTATUS
  340. RtlpDeactivateWait (
  341. PRTLP_WAIT Wait,
  342. BOOLEAN OkayToFreeTheTimer
  343. ) ;
  344. VOID
  345. RtlpDeleteWait (
  346. PRTLP_WAIT Wait
  347. ) ;
  348. VOID
  349. RtlpProcessTimeouts (
  350. PRTLP_WAIT_THREAD_CONTROL_BLOCK ThreadCB
  351. ) ;
  352. ULONG
  353. RtlpGetTimeRemaining (
  354. HANDLE TimerHandle
  355. ) ;
  356. #define THREAD_TYPE_WORKER 1
  357. #define THREAD_TYPE_IO_WORKER 2
  358. VOID
  359. RtlpDeleteTimer (
  360. PRTLP_TIMER Timer
  361. ) ;
  362. PRTLP_EVENT
  363. RtlpGetWaitEvent (
  364. VOID
  365. ) ;
  366. VOID
  367. RtlpFreeWaitEvent (
  368. PRTLP_EVENT Event
  369. ) ;
  370. VOID
  371. RtlpDoNothing (
  372. PVOID NotUsed1,
  373. PVOID NotUsed2,
  374. PVOID NotUsed3
  375. ) ;
  376. VOID
  377. RtlpExecuteWorkerRequest (
  378. NTSTATUS Status,
  379. PVOID Context,
  380. PVOID ActualFunction
  381. ) ;
  382. NTSTATUS
  383. RtlpWaitForEvent (
  384. HANDLE Event,
  385. HANDLE ThreadHandle
  386. ) ;
  387. NTSTATUS
  388. RtlpCaptureImpersonation(
  389. IN LOGICAL RequestDuplicateAccess,
  390. OUT PHANDLE Token
  391. );
  392. VOID
  393. RtlpRestartImpersonation(
  394. IN HANDLE Token
  395. );
  396. NTSYSAPI
  397. NTSTATUS
  398. NTAPI
  399. RtlThreadPoolCleanup (
  400. ULONG Flags
  401. ) ;
  402. VOID
  403. RtlpWaitOrTimerCallout(WAITORTIMERCALLBACKFUNC Function,
  404. PVOID Context,
  405. BOOLEAN TimedOut,
  406. PACTIVATION_CONTEXT ActivationContext,
  407. HANDLE ImpersonationToken,
  408. PRTL_CRITICAL_SECTION const *LocksHeld);
  409. VOID
  410. RtlpApcCallout(APC_CALLBACK_FUNCTION Function,
  411. NTSTATUS Status,
  412. PVOID Context1,
  413. PVOID Context2);
  414. VOID
  415. RtlpWorkerCallout(WORKERCALLBACKFUNC Function,
  416. PVOID Context,
  417. PACTIVATION_CONTEXT ActivationContext,
  418. HANDLE ImpersonationToken);
  419. // Waits and timers may specify that their callbacks must execute
  420. // within worker threads of various types. This can cause a problem
  421. // if those worker threads are unavailable. RtlpAcquireWorker
  422. // guarantees that at least one worker thread of the appropriate type
  423. // will be available to handle callbacks until a matching call to
  424. // RtlpReleaseWorker is made.
  425. NTSTATUS
  426. RtlpAcquireWorker(ULONG Flags);
  427. VOID
  428. RtlpReleaseWorker(ULONG Flags);
  429. //to make sure that a wait is not deleted before being registered
  430. #define STATE_REGISTERED 0x0001
  431. //set when wait registered. Removed when one shot wait fired.
  432. //when deregisterWait called, tells whether to be removed from ActiveArray
  433. //If timer active, then have to remove it from delta list and reset the timer.
  434. #define STATE_ACTIVE 0x0002
  435. //when deregister wait is called(RefCount may be >0)
  436. #define STATE_DELETE 0x0004
  437. //set when cancel timer called. The APC will clean it up.
  438. #define STATE_DONTFIRE 0x0008
  439. //set when one shot timer fired.
  440. #define STATE_ONE_SHOT_FIRED 0x0010