00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #define DBG1 1
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #define RTLP_TIMER RTLP_GENERIC_TIMER
00045 #define PRTLP_TIMER PRTLP_GENERIC_TIMER
00046
00047 #define RTLP_TIMER_QUEUE RTLP_GENERIC_TIMER
00048 #define PRTLP_TIMER_QUEUE PRTLP_GENERIC_TIMER
00049
00050
struct _RTLP_WAIT ;
00051
00052 typedef struct _RTLP_GENERIC_TIMER {
00053
00054 LIST_ENTRY
List ;
00055 ULONG
DeltaFiringTime ;
00056
00057
union {
00058 ULONG
RefCount ;
00059 ULONG *
RefCountPtr ;
00060 } ;
00061
00062 ULONG
State ;
00063
00064
union {
00065
00066
00067
00068
struct {
00069
00070 LIST_ENTRY
TimerList ;
00071 LIST_ENTRY
UncancelledTimerList ;
00072
00073
#if DBG1
00074 ULONG
NextDbgId;
00075
#endif
00076
00077 } ;
00078
00079
00080
00081
struct {
00082 struct _RTLP_GENERIC_TIMER *
Queue ;
00083 struct _RTLP_WAIT *
Wait ;
00084 ULONG
Flags ;
00085 PVOID
Function ;
00086 PVOID
Context ;
00087 ULONG
Period ;
00088 LIST_ENTRY
TimersToFireList;
00089 } ;
00090 } ;
00091
00092 HANDLE
CompletionEvent ;
00093
00094
#if DBG1
00095 ULONG
DbgId;
00096 ULONG
ThreadId ;
00097 ULONG
ThreadId2 ;
00098
#endif
00099
00100 }
RTLP_GENERIC_TIMER, *
PRTLP_GENERIC_TIMER ;
00101
00102
#if DBG1
00103 ULONG
NextTimerDbgId;
00104 ULONG
NextWaitDbgId;
00105
#endif
00106
00107
00108
00109
00110
00111
00112 typedef struct _RTLP_WAIT {
00113
00114 struct _RTLP_WAIT_THREAD_CONTROL_BLOCK *
ThreadCB ;
00115 HANDLE
WaitHandle ;
00116 ULONG
State ;
00117 ULONG
RefCount ;
00118 HANDLE
CompletionEvent ;
00119 struct _RTLP_GENERIC_TIMER *
Timer ;
00120 ULONG
Flags ;
00121 PVOID
Function ;
00122 PVOID
Context ;
00123 ULONG
Timeout ;
00124
#if DBG1
00125 ULONG
DbgId ;
00126 ULONG
ThreadId ;
00127 ULONG
ThreadId2 ;
00128
#endif
00129
00130 }
RTLP_WAIT, *
PRTLP_WAIT ;
00131
00132
00133
00134
00135 typedef struct _RTLP_WAIT_THREAD_CONTROL_BLOCK {
00136
00137 LIST_ENTRY
WaitThreadsList ;
00138
00139 HANDLE
ThreadHandle ;
00140 ULONG
ThreadId ;
00141
00142 ULONG
NumWaits ;
00143 ULONG
NumActiveWaits ;
00144 HANDLE
ActiveWaitArray[64] ;
00145 PRTLP_WAIT ActiveWaitPointers[64] ;
00146 HANDLE
TimerHandle ;
00147 RTLP_TIMER_QUEUE TimerQueue;
00148 RTLP_TIMER TimerBlocks[63] ;
00149
00150 LIST_ENTRY
FreeTimerBlocks ;
00151
00152 LARGE_INTEGER
Current64BitTickCount ;
00153 LONGLONG
Firing64BitTickCount ;
00154
00155 RTL_CRITICAL_SECTION
WaitThreadCriticalSection ;
00156
00157
00158 }
RTLP_WAIT_THREAD_CONTROL_BLOCK, *
PRTLP_WAIT_THREAD_CONTROL_BLOCK ;
00159
00160
00161
00162
00163 typedef struct _RTLP_IOWORKER_TCB {
00164
00165 LIST_ENTRY
List ;
00166 HANDLE
ThreadHandle ;
00167 ULONG
Flags ;
00168 BOOLEAN
LongFunctionFlag ;
00169 }
RTLP_IOWORKER_TCB, *
PRTLP_IOWORKER_TCB ;
00170
00171 typedef struct _RTLP_WAITWORKER {
00172
union {
00173 PRTLP_WAIT Wait ;
00174 PRTLP_TIMER Timer ;
00175 } ;
00176 BOOLEAN
WaitThreadCallback ;
00177 BOOLEAN
TimerCondition ;
00178 }
RTLP_ASYNC_CALLBACK, *
PRTLP_ASYNC_CALLBACK ;
00179
00180
00181
00182
00183
00184 typedef struct _RTLP_WORK {
00185
00186 WORKERCALLBACKFUNC
Function ;
00187 ULONG
Flags ;
00188
00189 }
RTLP_WORK, *
PRTLP_WORK ;
00190
00191
00192
00193
00194
00195 typedef struct _RTLP_EVENT {
00196
00197 LIST_ENTRY
List ;
00198 HANDLE
Handle ;
00199
00200 }
RTLP_EVENT, *
PRTLP_EVENT ;
00201
00202
00203
00204
00205
00206 ULONG
StartedTPInitialization ;
00207 ULONG
CompletedTPInitialization;
00208
00209 ULONG
StartedWorkerInitialization ;
00210 ULONG
CompletedWorkerInitialization ;
00211
00212 ULONG
StartedWaitInitialization ;
00213 ULONG
CompletedWaitInitialization ;
00214
00215 ULONG
StartedTimerInitialization ;
00216 ULONG
CompletedTimerInitialization ;
00217
00218 ULONG
StartedEventCacheInitialization ;
00219 ULONG
CompletedEventCacheInitialization;
00220
00221 HANDLE
TimerThreadHandle ;
00222 ULONG
TimerThreadId ;
00223
00224 ULONG
NumIOWorkerThreads ;
00225 ULONG
NumWorkerThreads ;
00226 ULONG
NumMinWorkerThreads ;
00227 ULONG
NumIOWorkRequests ;
00228 ULONG
NumLongIOWorkRequests ;
00229 ULONG
NumWorkRequests ;
00230 ULONG
NumLongWorkRequests ;
00231 ULONG
NumExecutingWorkerThreads ;
00232 ULONG
TotalExecutedWorkRequests ;
00233 ULONG
OldTotalExecutedWorkRequests ;
00234 HANDLE
WorkerThreadTimerQueue ;
00235 ULONG
WorkerThreadTimerQueueInit ;
00236
00237 HANDLE
WorkerThreadTimer ;
00238
00239 ULONG
NumUnusedEvents ;
00240
00241 ULONG
LastThreadCreationTickCount ;
00242
00243 LIST_ENTRY
IOWorkerThreads ;
00244 PRTLP_IOWORKER_TCB PersistentIOTCB ;
00245 HANDLE
WorkerCompletionPort ;
00246
00247 LIST_ENTRY
WaitThreads ;
00248 LIST_ENTRY
EventCache ;
00249
00250
00251 LIST_ENTRY
TimerQueues ;
00252 HANDLE
TimerHandle ;
00253 ULONG
NumTimerQueues ;
00254
00255 RTL_CRITICAL_SECTION
WorkerCriticalSection ;
00256 RTL_CRITICAL_SECTION
WaitCriticalSection ;
00257 RTL_CRITICAL_SECTION
TimerCriticalSection ;
00258 RTL_CRITICAL_SECTION
EventCacheCriticalSection ;
00259
00260 RTLP_START_THREAD
RtlpStartThread ;
00261 PRTLP_START_THREAD
RtlpStartThreadFunc =
RtlpStartThread ;
00262 RTLP_EXIT_THREAD
RtlpExitThread ;
00263 PRTLP_EXIT_THREAD
RtlpExitThreadFunc =
RtlpExitThread ;
00264
00265
#if DBG1
00266 PVOID
CallbackFn1,
CallbackFn2,
Context1,
Context2 ;
00267
#endif
00268
00269
00270
00271
00272 #define THREAD_CREATION_DAMPING_TIME1 1000 // In Milliseconds. Time between starting successive threads.
00273 #define THREAD_CREATION_DAMPING_TIME2 5000 // In Milliseconds. Time between starting successive threads.
00274 #define THREAD_TERMINATION_DAMPING_TIME 10000 // In Milliseconds. Time between stopping successive threads.
00275 #define NEW_THREAD_THRESHOLD 7 // Number of requests outstanding before we start a new thread
00276 #define MAX_WORKER_THREADS 1000 // Max effective worker threads
00277 #define INFINITE_TIME (ULONG)~0 // In milliseconds
00278 #define RTLP_MAX_TIMERS 0x00080000 // 524288 timers per process
00279 #define MAX_UNUSED_EVENTS 40
00280
00281
00282
00283
00284
00285 #define ONE_MILLISECOND_TIMEOUT(TimeOut) { \
00286
TimeOut.LowPart = 0xffffd8f0 ; \
00287
TimeOut.HighPart = 0xffffffff ; \
00288
}
00289
00290 #define HUNDRED_MILLISECOND_TIMEOUT(TimeOut) { \
00291
TimeOut.LowPart = 0xfff0bdc0 ; \
00292
TimeOut.HighPart = 0xffffffff ; \
00293
}
00294
00295 #define ONE_SECOND_TIMEOUT(TimeOut) { \
00296
TimeOut.LowPart = 0xff676980 ; \
00297
TimeOut.HighPart = 0xffffffff ; \
00298
}
00299
00300 #define USE_PROCESS_HEAP 1
00301
00302 #define RtlpFreeTPHeap(Ptr) \
00303
RtlFreeHeap( RtlProcessHeap(), 0, (Ptr) )
00304
00305 #define RtlpAllocateTPHeap(Size, Flags) \
00306
RtlAllocateHeap( RtlProcessHeap(), (Flags), (Size) )
00307
00308
00309
00310 #define ACQUIRE_GLOBAL_WAIT_LOCK() \
00311
RtlEnterCriticalSection (&WaitCriticalSection)
00312
00313 #define RELEASE_GLOBAL_WAIT_LOCK() \
00314
RtlLeaveCriticalSection(&WaitCriticalSection)
00315
00316
00317
00318
00319
00320 #define ACQUIRE_GLOBAL_TIMER_LOCK() \
00321
RtlEnterCriticalSection (&TimerCriticalSection)
00322
00323 #define RELEASE_GLOBAL_TIMER_LOCK() \
00324
RtlLeaveCriticalSection(&TimerCriticalSection)
00325
00326
00327
00328 #define IS_COMPONENT_INITIALIZED(StartedVariable, CompletedVariable, Flag) \
00329
{\
00330
LARGE_INTEGER TimeOut ; \
00331
Flag = FALSE ; \
00332
\
00333
if ( StartedVariable ) { \
00334
\
00335
if ( !CompletedVariable ) { \
00336
\
00337
ONE_MILLISECOND_TIMEOUT(TimeOut) ; \
00338
\
00339
while (!(volatile ULONG) CompletedVariable) \
00340
NtDelayExecution (FALSE, &TimeOut) ; \
00341
\
00342
if (CompletedVariable == 1) \
00343
Flag = TRUE ; \
00344
\
00345
} else { \
00346
Flag = TRUE ; \
00347
} \
00348
} \
00349
}
00350
00351
00352
00353
00354 #define DBG_SET_FUNCTION(Fn, Context) { \
00355
CallbackFn1 = CallbackFn2 ; \
00356
CallbackFn2 = (Fn) ; \
00357
Context1 = Context2 ; \
00358
Context2 = (Context ) ; \
00359
}
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 #define RtlpShiftWaitArray(ThreadCB, SrcIndex, DstIndex, Count) { \
00373
\
00374
RtlCopyMemory (&(ThreadCB)->ActiveWaitArray[DstIndex], \
00375
&(ThreadCB)->ActiveWaitArray[SrcIndex], \
00376
sizeof (HANDLE) * (Count)) ; \
00377
\
00378
RtlCopyMemory (&(ThreadCB)->ActiveWaitPointers[DstIndex],\
00379
&(ThreadCB)->ActiveWaitPointers[SrcIndex],\
00380
sizeof (HANDLE) * (Count)) ; \
00381
}
00382
00383 LARGE_INTEGER
Last64BitTickCount ;
00384 LARGE_INTEGER
Resync64BitTickCount ;
00385 LARGE_INTEGER
Firing64BitTickCount ;
00386
00387 #define RtlpGetResync64BitTickCount() Resync64BitTickCount.QuadPart
00388 #define RtlpSetFiring64BitTickCount(Timeout) \
00389
Firing64BitTickCount.QuadPart = (Timeout)
00390
00391
00392
00393
00394
00395 #define SET_SIGNATURE(ptr) (ptr)->State |= 0xfedc0000
00396 #define CHECK_SIGNATURE(ptr) ASSERT( ((ptr)->State & 0xffff0000) == 0xfedc0000 )
00397 #define SET_DEL_SIGNATURE(ptr) ((ptr)->State |= 0xfedcb000)
00398 #define CHECK_DEL_SIGNATURE(ptr) ASSERT( (((ptr)->State & 0xffff0000) == 0xfedc0000) \
00399
&& ( ! ((ptr)->State & 0x0000f000)) )
00400 #define CLEAR_SIGNATURE(ptr) ((ptr)->State = ((ptr)->State & 0x0000ffff) | 0xcdef0000)
00401 #define SET_DEL_TIMERQ_SIGNATURE(ptr) ((ptr)->State |= 0x00000a00)
00402
00403
00404
00405
00406 #define DPRN0 (DPRN & 0x1)
00407 #define DPRN1 (DPRN & 0x2)
00408 #define DPRN2 (DPRN & 0x4)
00409 #define DPRN3 (DPRN & 0x8)
00410 #define DPRN4 (DPRN & 0x10)
00411
00412
00413
00414
00415
00416
NTSTATUS
00417
RtlpInitializeWorkerThreadPool (
00418 ) ;
00419
00420
NTSTATUS
00421
RtlpInitializeWaitThreadPool (
00422 ) ;
00423
00424
NTSTATUS
00425
RtlpInitializeTimerThreadPool (
00426 ) ;
00427
00428
NTSTATUS
00429
RtlpStartThread (
00430 IN PUSER_THREAD_START_ROUTINE Function,
00431 OUT HANDLE *ThreadHandle
00432 ) ;
00433
00434 LONG
00435
RtlpWaitThread (
00436 IN PVOID WaitHandle
00437 ) ;
00438
00439 LONG
00440
RtlpWorkerThread (
00441 PVOID NotUsed
00442 ) ;
00443
00444 LONG
00445
RtlpIOWorkerThread (
00446 PVOID NotUsed
00447 ) ;
00448
00449 LONG
00450
RtlpTimerThread (
00451 PVOID NotUsed
00452 ) ;
00453
00454
VOID
00455
RtlpAddTimerQueue (
00456 PVOID Queue
00457 ) ;
00458
00459
VOID
00460
RtlpAddTimer (
00461 PRTLP_TIMER Timer
00462 ) ;
00463
00464
VOID
00465
RtlpResetTimer (
00466 HANDLE TimerHandle,
00467 ULONG DueTime,
00468 PRTLP_WAIT_THREAD_CONTROL_BLOCK ThreadCB
00469 ) ;
00470
00471
00472
VOID
00473
RtlpFireTimersAndReorder (
00474 PRTLP_TIMER_QUEUE Queue,
00475 ULONG *NewFiringTime,
00476 PLIST_ENTRY TimersToFireList
00477 ) ;
00478
00479
VOID
00480
RtlpFireTimers (
00481 PLIST_ENTRY TimersToFireList
00482 ) ;
00483
00484
VOID
00485
RtlpInsertTimersIntoDeltaList (
00486 PLIST_ENTRY NewTimerList,
00487 PLIST_ENTRY DeltaTimerList,
00488 ULONG TimeRemaining,
00489 ULONG *NewFiringTime
00490 ) ;
00491
00492 BOOLEAN
00493
RtlpInsertInDeltaList (
00494 PLIST_ENTRY DeltaList,
00495 PRTLP_GENERIC_TIMER NewTimer,
00496 ULONG TimeRemaining,
00497 ULONG *NewFiringTime
00498 ) ;
00499
00500 BOOLEAN
00501
RtlpRemoveFromDeltaList (
00502 PLIST_ENTRY DeltaList,
00503 PRTLP_GENERIC_TIMER Timer,
00504 ULONG TimeRemaining,
00505 ULONG* NewFiringTime
00506 ) ;
00507
00508 BOOLEAN
00509
RtlpReOrderDeltaList (
00510 PLIST_ENTRY DeltaList,
00511 PRTLP_GENERIC_TIMER Timer,
00512 ULONG TimeRemaining,
00513 ULONG* NewFiringTime,
00514 ULONG ChangedFiringTime
00515 ) ;
00516
00517
00518
VOID
00519
RtlpAddWait (
00520 PRTLP_WAIT Wait
00521 ) ;
00522
00523
NTSTATUS
00524
RtlpDeregisterWait (
00525 PRTLP_WAIT Wait,
00526 HANDLE PartialCompletionEvent,
00527 PULONG StatusPtr
00528 ) ;
00529
00530
NTSTATUS
00531
RtlpDeactivateWait (
00532 PRTLP_WAIT Wait
00533 ) ;
00534
00535
VOID
00536
RtlpDeleteWait (
00537 PRTLP_WAIT Wait
00538 ) ;
00539
00540
VOID
00541
RtlpProcessWaitCompletion (
00542 PRTLP_WAIT Wait,
00543 ULONG ArrayIndex
00544 ) ;
00545
00546
VOID
00547
RtlpProcessTimeouts (
00548 PRTLP_WAIT_THREAD_CONTROL_BLOCK ThreadCB
00549 ) ;
00550
00551 ULONG
00552
RtlpGetTimeRemaining (
00553 HANDLE TimerHandle
00554 ) ;
00555
00556
00557
VOID
00558
RtlpServiceTimer (
00559 PVOID NotUsedArg,
00560 ULONG NotUsedLowTimer,
00561 LONG NotUsedHighTimer
00562 ) ;
00563
00564 ULONG
00565
RtlpGetQueueRelativeTime (
00566 PRTLP_TIMER_QUEUE Queue
00567 ) ;
00568
00569
VOID
00570
RtlpCancelTimer (
00571 PRTLP_TIMER TimerToCancel
00572 ) ;
00573
00574
VOID
00575
RtlpCancelTimerEx (
00576 PRTLP_TIMER Timer,
00577 BOOLEAN DeletingQueue
00578 ) ;
00579
00580
VOID
00581
RtlpDeactivateTimer (
00582 PRTLP_TIMER_QUEUE Queue,
00583 PRTLP_TIMER Timer
00584 ) ;
00585
00586
00587
NTSTATUS
00588
RtlpDeleteTimerQueue (
00589 PRTLP_TIMER_QUEUE Queue
00590 ) ;
00591
00592
VOID
00593
RtlpDeleteTimerQueueComplete (
00594 PRTLP_TIMER_QUEUE Queue
00595 ) ;
00596
00597 LONGLONG
00598
Rtlp64BitTickCount(
00599 ) ;
00600
00601
NTSTATUS
00602
RtlpFindWaitThread (
00603 PRTLP_WAIT_THREAD_CONTROL_BLOCK *ThreadCB
00604 ) ;
00605
00606
VOID
00607
RtlpExecuteIOWorkItem (
00608 PVOID Function,
00609 PVOID Context,
00610 PVOID NotUsed
00611 ) ;
00612
00613
VOID
00614
RtlpExecuteLongIOWorkItem (
00615 PVOID Function,
00616 PVOID Context,
00617 PVOID NotUsed
00618 ) ;
00619
00620
NTSTATUS
00621
RtlpQueueIOWorkerRequest (
00622 WORKERCALLBACKFUNC Function,
00623 PVOID Context,
00624 ULONG Flags
00625 ) ;
00626
00627
NTSTATUS
00628
RtlpStartWorkerThread (
00629 ) ;
00630
00631
NTSTATUS
00632
RtlpStartIOWorkerThread (
00633 ) ;
00634
00635
VOID
00636
RtlpWorkerThreadTimerCallback(
00637 PVOID Context,
00638 BOOLEAN NotUsed
00639 ) ;
00640
00641
NTSTATUS
00642
RtlpQueueWorkerRequest (
00643 WORKERCALLBACKFUNC Function,
00644 PVOID Context,
00645 ULONG Flags
00646 ) ;
00647
00648
00649 #define THREAD_TYPE_WORKER 1
00650 #define THREAD_TYPE_IO_WORKER 2
00651
00652 BOOLEAN
00653
RtlpDoWeNeedNewWorkerThread (
00654 ULONG ThreadType
00655 ) ;
00656
00657
VOID
00658
RtlpUpdateTimer (
00659 PRTLP_TIMER Timer,
00660 PRTLP_TIMER UpdatedTimer
00661 ) ;
00662
00663
VOID
00664
RtlpDeleteTimer (
00665 PRTLP_TIMER Timer
00666 ) ;
00667
00668
PRTLP_EVENT
00669
RtlpGetWaitEvent (
00670 VOID
00671 ) ;
00672
00673
VOID
00674
RtlpFreeWaitEvent (
00675 PRTLP_EVENT Event
00676 ) ;
00677
00678
VOID
00679
RtlpInitializeEventCache (
00680 VOID
00681 ) ;
00682
00683
VOID
00684
RtlpFreeWaitEvent (
00685 PRTLP_EVENT Event
00686 ) ;
00687
00688
PRTLP_EVENT
00689
RtlpGetWaitEvent (
00690 VOID
00691 ) ;
00692
00693
VOID
00694
RtlpDeleteWaitAPC (
00695 PRTLP_WAIT_THREAD_CONTROL_BLOCK ThreadCB,
00696 PRTLP_WAIT Wait,
00697 HANDLE Handle
00698 ) ;
00699
00700
VOID
00701
RtlpDoNothing (
00702 PVOID NotUsed1,
00703 PVOID NotUsed2,
00704 PVOID NotUsed3
00705 ) ;
00706
00707
VOID
00708
RtlpExecuteWorkerRequest (
00709 NTSTATUS Status,
00710 PVOID Context,
00711 PVOID ActualFunction
00712 ) ;
00713
00714
NTSTATUS
00715
RtlpInitializeTPHeap (
00716 ) ;
00717
00718
NTSTATUS
00719
RtlpWaitForEvent (
00720 HANDLE Event,
00721 HANDLE ThreadHandle
00722 ) ;
00723
00724
VOID
00725
RtlpThreadCleanup (
00726 ) ;
00727
00728
VOID
00729
RtlpWorkerThreadCleanup (
00730 NTSTATUS Status,
00731 PVOID NotUsed,
00732 PVOID NotUsed2
00733 ) ;
00734
00735 PVOID
00736
RtlpForceAllocateTPHeap(
00737 ULONG dwSize,
00738 ULONG dwFlags
00739 );
00740
00741
VOID
00742
RtlpWorkerThreadInitializeTimers(
00743 PVOID Context
00744 );
00745
00746
00747 NTSYSAPI
00748
NTSTATUS
00749 NTAPI
00750
RtlThreadPoolCleanup (
00751 ULONG Flags
00752 ) ;
00753
00754
00755 #define STATE_REGISTERED 0x0001
00756
00757
00758
00759
00760 #define STATE_ACTIVE 0x0002
00761
00762
00763 #define STATE_DELETE 0x0004
00764
00765
00766 #define STATE_DONTFIRE 0x0008
00767
00768
00769 #define STATE_ONE_SHOT_FIRED 0x0010