Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

timerobj.c File Reference

#include "ki.h"

Go to the source code of this file.

Defines

#define ASSERT_TIMER(E)

Functions

VOID KeInitializeTimer (IN PKTIMER Timer)
VOID KeInitializeTimerEx (IN PKTIMER Timer, IN TIMER_TYPE Type)
VOID KeClearTimer (IN PKTIMER Timer)
BOOLEAN KeCancelTimer (IN PKTIMER Timer)
BOOLEAN KeReadStateTimer (IN PKTIMER Timer)
BOOLEAN KeSetTimer (IN PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
BOOLEAN KeSetTimerEx (IN PKTIMER Timer, IN LARGE_INTEGER DueTime, IN LONG Period OPTIONAL, IN PKDPC Dpc OPTIONAL)
ULONGLONG KeQueryTimerDueTime (IN PKTIMER Timer)
PVOID KeCheckForTimer (IN PVOID BlockStart, IN ULONG BlockSize)


Define Documentation

#define ASSERT_TIMER  ) 
 

Value:

{ \ ASSERT(((E)->Header.Type == TimerNotificationObject) || \ ((E)->Header.Type == TimerSynchronizationObject)); \ }

Definition at line 37 of file timerobj.c.

Referenced by KeCancelTimer(), KeClearTimer(), KeQueryTimerDueTime(), KeReadStateTimer(), and KeSetTimerEx().


Function Documentation

BOOLEAN KeCancelTimer IN PKTIMER  Timer  ) 
 

Definition at line 157 of file timerobj.c.

References ASSERT, ASSERT_TIMER, DISPATCH_LEVEL, FALSE, KiLockDispatcherDatabase, KiRemoveTreeTimer, and KiUnlockDispatcherDatabase().

Referenced by ExpDeleteTimer(), ExTimerRundown(), NtCancelTimer(), NtSetTimer(), and Win32kNtUserCleanup().

00163 : 00164 00165 This function cancels a timer that was previously set to expire at 00166 a specified time. If the timer is not currently set, then no operation 00167 is performed. Canceling a timer does not set the state of the timer to 00168 Signaled. 00169 00170 Arguments: 00171 00172 Timer - Supplies a pointer to a dispatcher object of type timer. 00173 00174 Return Value: 00175 00176 A boolean value of TRUE is returned if the the specified timer was 00177 currently set. Else a value of FALSE is returned. 00178 00179 --*/ 00180 00181 { 00182 00183 BOOLEAN Inserted; 00184 KIRQL OldIrql; 00185 00186 ASSERT_TIMER(Timer); 00187 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 00188 00189 // 00190 // Raise IRQL to dispatcher level, lock the dispatcher database, and 00191 // capture the timer inserted status. If the timer is currently set, 00192 // then remove it from the timer list. 00193 // 00194 00195 KiLockDispatcherDatabase(&OldIrql); 00196 Inserted = Timer->Header.Inserted; 00197 if (Inserted != FALSE) { 00198 KiRemoveTreeTimer(Timer); 00199 } 00200 00201 // 00202 // Unlock the dispatcher database, lower IRQL to its previous value, and 00203 // return boolean value that signifies whether the timer was set of not. 00204 // 00205 00206 KiUnlockDispatcherDatabase(OldIrql); 00207 return Inserted; 00208 }

PVOID KeCheckForTimer IN PVOID  BlockStart,
IN ULONG  BlockSize
 

Definition at line 467 of file timerobj.c.

References BlockSize, _KDPC::DeferredRoutine, _KTIMER::Dpc, End, Index, KeBugCheckEx(), KiLockDispatcherDatabase, KiTimerTableListHead, KiUnlockDispatcherDatabase(), NULL, Start, and TIMER_TABLE_SIZE.

Referenced by ExFreePoolSanityChecks(), MmUnloadSystemImage(), and VerifierKeInitializeTimerEx().

00473 : 00474 00475 This function is used for debugging by checking all timers 00476 to see if any is in the memory block passed. If so, the 00477 system stops at a debug breakpoint. 00478 00479 Arguments: 00480 00481 MemoryBlock - Base address to check for timer 00482 00483 BlockSize - Size (in bytes) to check in memory block 00484 00485 Return Value: 00486 00487 The address of the currently active timer. 00488 00489 --*/ 00490 { 00491 ULONG Index; 00492 PLIST_ENTRY ListHead; 00493 PLIST_ENTRY NextEntry; 00494 KIRQL OldIrql; 00495 PKTIMER Timer; 00496 PUCHAR Address; 00497 PUCHAR Start; 00498 PUCHAR End; 00499 00500 // 00501 // Compute the ending memory location. 00502 // 00503 00504 Start = (PUCHAR)BlockStart; 00505 End = Start + BlockSize; 00506 00507 // 00508 // Raise IRQL to dispatcher level and lock dispatcher database. 00509 // 00510 00511 KiLockDispatcherDatabase(&OldIrql); 00512 00513 // 00514 // Run the entire timer database and check for any timers in 00515 // the memory block 00516 // 00517 00518 Index = 0; 00519 do { 00520 ListHead = &KiTimerTableListHead[Index]; 00521 NextEntry = ListHead->Flink; 00522 while (NextEntry != ListHead) { 00523 Timer = CONTAINING_RECORD(NextEntry, KTIMER, TimerListEntry); 00524 Address = (PUCHAR)Timer; 00525 NextEntry = NextEntry->Flink; 00526 00527 // 00528 // Check this timer object is not in the range. 00529 // In each of the following, we check that the object 00530 // does not overlap the range, for example, if the timer 00531 // object (in this first check), starts one dword before 00532 // the range being checked, we have an overlap and should 00533 // stop. 00534 // 00535 00536 if ((Address > (Start - sizeof(KTIMER))) && 00537 (Address < End)) { 00538 KeBugCheckEx(TIMER_OR_DPC_INVALID, 00539 0x0, 00540 (ULONG_PTR)Address, 00541 (ULONG_PTR)Start, 00542 (ULONG_PTR)End); 00543 } 00544 00545 if (Timer->Dpc) { 00546 00547 // 00548 // Check the timer's DPC object isn't in the range. 00549 // 00550 00551 Address = (PUCHAR)Timer->Dpc; 00552 if ((Address > (Start - sizeof(KDPC))) && 00553 (Address < End)) { 00554 KeBugCheckEx(TIMER_OR_DPC_INVALID, 00555 0x1, 00556 (ULONG_PTR)Address, 00557 (ULONG_PTR)Start, 00558 (ULONG_PTR)End); 00559 } 00560 00561 // 00562 // Check the timer's DPC routine is not in the range. 00563 // 00564 00565 Address = (PUCHAR)Timer->Dpc->DeferredRoutine; 00566 if (Address >= Start && Address < End) { 00567 KeBugCheckEx(TIMER_OR_DPC_INVALID, 00568 0x2, 00569 (ULONG_PTR)Address, 00570 (ULONG_PTR)Start, 00571 (ULONG_PTR)End); 00572 } 00573 } 00574 } 00575 00576 Index += 1; 00577 } while(Index < TIMER_TABLE_SIZE); 00578 00579 00580 // 00581 // Unlock the dispatcher database and lower IRQL to its previous value 00582 // 00583 00584 KiUnlockDispatcherDatabase(OldIrql); 00585 return NULL; 00586 } }

VOID KeClearTimer IN PKTIMER  Timer  ) 
 

Definition at line 124 of file timerobj.c.

References ASSERT_TIMER.

00130 : 00131 00132 This function clears the signal state of an timer object. 00133 00134 Arguments: 00135 00136 Event - Supplies a pointer to a dispatcher object of type timer. 00137 00138 Return Value: 00139 00140 None. 00141 00142 --*/ 00143 00144 { 00145 00146 ASSERT_TIMER(Timer); 00147 00148 // 00149 // Clear signal state of timer object. 00150 // 00151 00152 Timer->Header.SignalState = 0; 00153 return; 00154 }

VOID KeInitializeTimer IN PKTIMER  Timer  ) 
 

Definition at line 43 of file timerobj.c.

References KeInitializeTimerEx().

Referenced by CcInitializeCacheManager(), CmpWorker(), ExpWorkerThreadBalanceManager(), IopErrorLogQueueRequest(), KdInitSystem(), KeBalanceSetManager(), KeInitializeThread(), MiInitializeSpecialPoolCriteria(), RawInputThread(), and VdmpDelayInterrupt().

00049 : 00050 00051 This function initializes a kernel timer object. 00052 00053 Arguments: 00054 00055 Timer - Supplies a pointer to a dispatcher object of type timer. 00056 00057 Return Value: 00058 00059 None. 00060 00061 --*/ 00062 00063 { 00064 00065 // 00066 // Initialize extended timer object with a type of notification and a 00067 // period of zero. 00068 // 00069 00070 KeInitializeTimerEx(Timer, NotificationTimer); 00071 return; 00072 }

VOID KeInitializeTimerEx IN PKTIMER  Timer,
IN TIMER_TYPE  Type
 

Definition at line 75 of file timerobj.c.

References FALSE, NULL, and TimerNotificationObject.

Referenced by IoInitSystem(), IovpInternalDeferredCompletion(), KeInitializeTimer(), MmInitSystem(), NtCreateTimer(), RawInputThread(), and VerifierKeInitializeTimerEx().

00082 : 00083 00084 This function initializes an extended kernel timer object. 00085 00086 Arguments: 00087 00088 Timer - Supplies a pointer to a dispatcher object of type timer. 00089 00090 Type - Supplies the type of timer object; NotificationTimer or 00091 SynchronizationTimer; 00092 00093 Return Value: 00094 00095 None. 00096 00097 --*/ 00098 00099 { 00100 // 00101 // Initialize standard dispatcher object header and set initial 00102 // state of timer. 00103 // 00104 00105 Timer->Header.Type = TimerNotificationObject + Type; 00106 Timer->Header.Inserted = FALSE; 00107 Timer->Header.Size = sizeof(KTIMER) / sizeof(LONG); 00108 Timer->Header.SignalState = FALSE; 00109 00110 #if DBG 00111 00112 Timer->TimerListEntry.Flink = NULL; 00113 Timer->TimerListEntry.Blink = NULL; 00114 00115 #endif 00116 00117 InitializeListHead(&Timer->Header.WaitListHead); 00118 Timer->DueTime.QuadPart = 0; 00119 Timer->Period = 0; 00120 return; 00121 }

ULONGLONG KeQueryTimerDueTime IN PKTIMER  Timer  ) 
 

Definition at line 410 of file timerobj.c.

References ASSERT_TIMER, KiLockDispatcherDatabase, and KiUnlockDispatcherDatabase().

Referenced by ExGetNextWakeTime().

00416 : 00417 00418 This function returns the InterruptTime at which the timer is 00419 pending. 0 is returned if the timer is not pending. 00420 00421 N.B. This function may only be called by the system sleep code. 00422 00423 Arguments: 00424 00425 Timer - Supplies a pointer to a dispatcher object of type timer. 00426 00427 Return Value: 00428 00429 Returns the amount of time remaining on the timer, or 0 if the 00430 timer is not pending. 00431 00432 --*/ 00433 00434 { 00435 00436 KIRQL OldIrql; 00437 LARGE_INTEGER InterruptTime; 00438 ULONGLONG DueTime; 00439 00440 ASSERT_TIMER(Timer); 00441 00442 // 00443 // Raise IRQL to dispatcher level and lock dispatcher database. 00444 // 00445 00446 KiLockDispatcherDatabase(&OldIrql); 00447 00448 // 00449 // If the timer is currently pending, compute its due time 00450 // 00451 00452 DueTime = 0; 00453 if (Timer->Header.Inserted) { 00454 DueTime = Timer->DueTime.QuadPart; 00455 } 00456 00457 // 00458 // Unlock the dispatcher database and lower IRQL to its previous 00459 // value, and return the due time 00460 // 00461 00462 KiUnlockDispatcherDatabase(OldIrql); 00463 return DueTime; 00464 }

BOOLEAN KeReadStateTimer IN PKTIMER  Timer  ) 
 

Definition at line 211 of file timerobj.c.

References ASSERT_TIMER.

Referenced by NtCancelTimer(), NtQueryTimer(), and NtSetTimer().

00217 : 00218 00219 This function reads the current signal state of a timer object. 00220 00221 Arguments: 00222 00223 Timer - Supplies a pointer to a dispatcher object of type timer. 00224 00225 Return Value: 00226 00227 The current signal state of the timer object. 00228 00229 --*/ 00230 00231 { 00232 00233 ASSERT_TIMER(Timer); 00234 00235 // 00236 // Return current signal state of timer object. 00237 // 00238 00239 return (BOOLEAN)Timer->Header.SignalState; 00240 }

BOOLEAN KeSetTimer IN PKTIMER  Timer,
IN LARGE_INTEGER  DueTime,
IN PKDPC Dpc  OPTIONAL
 

Definition at line 243 of file timerobj.c.

References KeSetTimerEx().

Referenced by CcCanIWrite(), CcScheduleLazyWriteScan(), CmpLazyFlush(), ExpWorkerThreadBalanceManager(), InternalSetTimer(), IopErrorLogQueueRequest(), KdpTimeSlipWork(), KeBalanceSetManager(), TimersProc(), and VdmpDelayInterrupt().

00251 : 00252 00253 This function sets a timer to expire at a specified time. If the timer is 00254 already set, then it is implicitly canceled before it is set to expire at 00255 the specified time. Setting a timer causes its due time to be computed, 00256 its state to be set to Not-Signaled, and the timer object itself to be 00257 inserted in the timer list. 00258 00259 Arguments: 00260 00261 Timer - Supplies a pointer to a dispatcher object of type timer. 00262 00263 DueTime - Supplies an absolute or relative time at which the timer 00264 is to expire. 00265 00266 Dpc - Supplies an optional pointer to a control object of type DPC. 00267 00268 Return Value: 00269 00270 A boolean value of TRUE is returned if the the specified timer was 00271 currently set. Else a value of FALSE is returned. 00272 00273 --*/ 00274 00275 { 00276 00277 // 00278 // Set the timer with a period of zero. 00279 // 00280 00281 return KeSetTimerEx(Timer, DueTime, 0, Dpc); 00282 }

BOOLEAN KeSetTimerEx IN PKTIMER  Timer,
IN LARGE_INTEGER  DueTime,
IN LONG Period  OPTIONAL,
IN PKDPC Dpc  OPTIONAL
 

Definition at line 285 of file timerobj.c.

References ASSERT, ASSERT_TIMER, DISPATCH_LEVEL, _KTIMER::Dpc, FALSE, _KTIMER::Header, KeInsertQueueDpc(), KiInsertTreeTimer(), KiLockDispatcherDatabase, KiRemoveTreeTimer, KiUnlockDispatcherDatabase(), KiWaitTest(), NULL, _KTIMER::Period, TIMER_EXPIRE_INCREMENT, and _DISPATCHER_HEADER::WaitListHead.

Referenced by IoInitSystem(), IovpInternalDeferredCompletion(), KeSetTimer(), MiInitializeSpecialPoolCriteria(), MiInsertPageInList(), MiModifiedPageWriterWorker(), and NtSetTimer().

00294 : 00295 00296 This function sets a timer to expire at a specified time. If the timer is 00297 already set, then it is implicitly canceled before it is set to expire at 00298 the specified time. Setting a timer causes its due time to be computed, 00299 its state to be set to Not-Signaled, and the timer object itself to be 00300 inserted in the timer list. 00301 00302 Arguments: 00303 00304 Timer - Supplies a pointer to a dispatcher object of type timer. 00305 00306 DueTime - Supplies an absolute or relative time at which the timer 00307 is to expire. 00308 00309 Period - Supplies an optional period for the timer in milliseconds. 00310 00311 Dpc - Supplies an optional pointer to a control object of type DPC. 00312 00313 Return Value: 00314 00315 A boolean value of TRUE is returned if the the specified timer was 00316 currently set. Else a value of FALSE is returned. 00317 00318 --*/ 00319 00320 { 00321 00322 BOOLEAN Inserted; 00323 LARGE_INTEGER Interval; 00324 KIRQL OldIrql; 00325 LARGE_INTEGER SystemTime; 00326 00327 ASSERT_TIMER(Timer); 00328 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 00329 00330 // 00331 // Raise IRQL to dispatcher level and lock dispatcher database. 00332 // 00333 00334 KiLockDispatcherDatabase(&OldIrql); 00335 00336 // 00337 // Capture the timer inserted status and if the timer is currently 00338 // set, then remove it from the timer list. 00339 // 00340 00341 Inserted = Timer->Header.Inserted; 00342 if (Inserted != FALSE) { 00343 KiRemoveTreeTimer(Timer); 00344 } 00345 00346 // 00347 // Clear the signal state, set the period, set the DPC address, and 00348 // insert the timer in the timer tree. If the timer is not inserted 00349 // in the timer tree, then it has already expired and as many waiters 00350 // as possible should be continued, and a DPC, if specified should be 00351 // queued. 00352 // 00353 // N.B. The signal state must be cleared in case the period is not 00354 // zero. 00355 // 00356 00357 Timer->Header.SignalState = FALSE; 00358 Timer->Dpc = Dpc; 00359 Timer->Period = Period; 00360 if (KiInsertTreeTimer((PRKTIMER)Timer, DueTime) == FALSE) { 00361 if (IsListEmpty(&Timer->Header.WaitListHead) == FALSE) { 00362 KiWaitTest(Timer, TIMER_EXPIRE_INCREMENT); 00363 } 00364 00365 // 00366 // If a DPC is specfied, then call the DPC routine. 00367 // 00368 00369 if (Dpc != NULL) { 00370 KiQuerySystemTime(&SystemTime); 00371 KeInsertQueueDpc(Timer->Dpc, 00372 ULongToPtr(SystemTime.LowPart), 00373 ULongToPtr(SystemTime.HighPart)); 00374 } 00375 00376 // 00377 // If the timer is periodic, then compute the next interval time 00378 // and reinsert the timer in the timer tree. 00379 // 00380 // N.B. Even though the timer insertion is relative, it can still 00381 // fail if the period of the timer elapses in between computing 00382 // the time and inserting the timer in the table. If this happens, 00383 // try again. 00384 // 00385 00386 if (Period != 0) { 00387 Interval.QuadPart = Int32x32To64(Timer->Period, - 10 * 1000); 00388 while (!KiInsertTreeTimer(Timer, Interval)) { 00389 ; 00390 } 00391 } 00392 } 00393 00394 // 00395 // Unlock the dispatcher database and lower IRQL to its previous 00396 // value. 00397 // 00398 00399 KiUnlockDispatcherDatabase(OldIrql); 00400 00401 // 00402 // Return boolean value that signifies whether the timer was set of 00403 // not. 00404 // 00405 00406 return Inserted; 00407 }


Generated on Sat May 15 19:45:46 2004 for test by doxygen 1.3.7