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

timersup.c File Reference

#include "ki.h"

Go to the source code of this file.

Functions

LOGICAL FASTCALL KiInsertTimerTable (LARGE_INTEGER Interval, LARGE_INTEGER CurrentTime, IN PRKTIMER Timer)
LOGICAL FASTCALL KiInsertTreeTimer (IN PRKTIMER Timer, IN LARGE_INTEGER Interval)
LOGICAL FASTCALL KiReinsertTreeTimer (IN PRKTIMER Timer, IN ULARGE_INTEGER DueTime)


Function Documentation

LOGICAL FASTCALL KiInsertTimerTable LARGE_INTEGER  Interval,
LARGE_INTEGER  CurrentTime,
IN PRKTIMER  Timer
 

Definition at line 185 of file timersup.c.

References _KTIMER::DueTime, Index, KiComputeTimerTableIndex(), KiMaximumSearchCount, KiRemoveTreeTimer, KiTimerTableListHead, and TRUE.

Referenced by KiInsertTreeTimer(), and KiReinsertTreeTimer().

00193 : 00194 00195 This function inserts a timer object in the timer table. 00196 00197 N.B. This routine assumes that the dispatcher data lock has been acquired. 00198 00199 Arguments: 00200 00201 Interval - Supplies the relative timer before the timer is to expire. 00202 00203 CurrentTime - supplies the current interrupt time. 00204 00205 Timer - Supplies a pointer to a dispatcher object of type timer. 00206 00207 Return Value: 00208 00209 If the timer is inserted in the timer tree, than a value of TRUE is 00210 returned. Otherwise, a value of FALSE is returned. 00211 00212 --*/ 00213 00214 { 00215 00216 ULONG Index; 00217 PLIST_ENTRY ListHead; 00218 PLIST_ENTRY NextEntry; 00219 PRKTIMER NextTimer; 00220 ULONG SearchCount; 00221 00222 // 00223 // Compute the timer table index and set the timer expiration time. 00224 // 00225 00226 Index = KiComputeTimerTableIndex(Interval, CurrentTime, Timer); 00227 00228 // 00229 // If the timer is due before the first entry in the computed list 00230 // or the computed list is empty, then insert the timer at the front 00231 // of the list and check if the timer has already expired. Otherwise, 00232 // insert then timer in the sorted order of the list searching from 00233 // the back of the list forward. 00234 // 00235 // N.B. The sequence of operations below is critical to avoid the race 00236 // condition that exists between this code and the clock interrupt 00237 // code that examines the timer table lists to detemine when timers 00238 // expire. 00239 // 00240 00241 ListHead = &KiTimerTableListHead[Index]; 00242 NextEntry = ListHead->Blink; 00243 00244 #if DBG 00245 00246 SearchCount = 0; 00247 00248 #endif 00249 00250 while (NextEntry != ListHead) { 00251 00252 // 00253 // Compute the maximum search count. 00254 // 00255 00256 #if DBG 00257 00258 SearchCount += 1; 00259 if (SearchCount > KiMaximumSearchCount) { 00260 KiMaximumSearchCount = SearchCount; 00261 } 00262 00263 #endif 00264 00265 NextTimer = CONTAINING_RECORD(NextEntry, KTIMER, TimerListEntry); 00266 if (((Timer->DueTime.HighPart == NextTimer->DueTime.HighPart) && 00267 (Timer->DueTime.LowPart >= NextTimer->DueTime.LowPart)) || 00268 (Timer->DueTime.HighPart > NextTimer->DueTime.HighPart)) { 00269 InsertHeadList(NextEntry, &Timer->TimerListEntry); 00270 return TRUE; 00271 } 00272 00273 NextEntry = NextEntry->Blink; 00274 } 00275 00276 // 00277 // The computed list is empty or the timer is due to expire before 00278 // the first entry in the list. Insert the entry in the computed 00279 // timer table list, then check if the timer has expired. 00280 // 00281 // Note that it is critical that the interrupt time not be captured 00282 // until after the timer has been completely inserted into the list. 00283 // 00284 // Otherwise, the clock interrupt code can think the list is empty, 00285 // and the code here that checks if the timer has expired will use 00286 // a stale interrupt time. 00287 // 00288 00289 InsertHeadList(ListHead, &Timer->TimerListEntry); 00290 KiQueryInterruptTime(&CurrentTime); 00291 if (((Timer->DueTime.HighPart == (ULONG)CurrentTime.HighPart) && 00292 (Timer->DueTime.LowPart <= CurrentTime.LowPart)) || 00293 (Timer->DueTime.HighPart < (ULONG)CurrentTime.HighPart)) { 00294 00295 // 00296 // The timer is due to expire before the current time. Remove the 00297 // timer from the computed list, set its status to Signaled, set 00298 // its inserted state to FALSE, and 00299 // 00300 00301 KiRemoveTreeTimer(Timer); 00302 Timer->Header.SignalState = TRUE; 00303 } 00304 00305 return Timer->Header.Inserted; 00306 } }

LOGICAL FASTCALL KiInsertTreeTimer IN PRKTIMER  Timer,
IN LARGE_INTEGER  Interval
 

Definition at line 42 of file timersup.c.

References FALSE, KiInsertTimerTable(), and TRUE.

Referenced by KeDelayExecutionThread(), KeRemoveQueue(), KeSetTimerEx(), KeWaitForMultipleObjects(), KeWaitForSingleObject(), and KiTimerListExpire().

00049 : 00050 00051 This function inserts a timer object in the timer queue. 00052 00053 N.B. This routine assumes that the dispatcher data lock has been acquired. 00054 00055 Arguments: 00056 00057 Timer - Supplies a pointer to a dispatcher object of type timer. 00058 00059 Interval - Supplies the absolute or relative time at which the time 00060 is to expire. 00061 00062 Return Value: 00063 00064 If the timer is inserted in the timer tree, than a value of TRUE is 00065 returned. Otherwise, a value of FALSE is returned. 00066 00067 --*/ 00068 00069 { 00070 00071 LARGE_INTEGER CurrentTime; 00072 LARGE_INTEGER SystemTime; 00073 LARGE_INTEGER TimeDifference; 00074 00075 // 00076 // Clear the signal state of timer if the timer period is zero and set 00077 // the inserted state to TRUE. 00078 // 00079 00080 Timer->Header.Inserted = TRUE; 00081 Timer->Header.Absolute = FALSE; 00082 if (Timer->Period == 0) { 00083 Timer->Header.SignalState = FALSE; 00084 } 00085 00086 // 00087 // If the specified interval is not a relative time (i.e., is an absolute 00088 // time), then convert it to relative time. 00089 // 00090 00091 if (Interval.HighPart >= 0) { 00092 KiQuerySystemTime(&SystemTime); 00093 TimeDifference.QuadPart = SystemTime.QuadPart - Interval.QuadPart; 00094 00095 // 00096 // If the resultant relative time is greater than or equal to zero, 00097 // then the timer has already expired. 00098 // 00099 00100 if (TimeDifference.HighPart >= 0) { 00101 Timer->Header.SignalState = TRUE; 00102 Timer->Header.Inserted = FALSE; 00103 return FALSE; 00104 } 00105 00106 Interval = TimeDifference; 00107 Timer->Header.Absolute = TRUE; 00108 } 00109 00110 // 00111 // Get the current interrupt time, insert the timer in the timer table, 00112 // and return the inserted state. 00113 // 00114 00115 KiQueryInterruptTime(&CurrentTime); 00116 return KiInsertTimerTable(Interval, CurrentTime, Timer); 00117 }

LOGICAL FASTCALL KiReinsertTreeTimer IN PRKTIMER  Timer,
IN ULARGE_INTEGER  DueTime
 

Definition at line 121 of file timersup.c.

References FALSE, KiInsertTimerTable(), and TRUE.

Referenced by KeSetSystemTime().

00128 : 00129 00130 This function reinserts a timer object in the timer queue. 00131 00132 N.B. This routine assumes that the dispatcher data lock has been acquired. 00133 00134 Arguments: 00135 00136 Timer - Supplies a pointer to a dispatcher object of type timer. 00137 00138 DueTime - Supplies the absolute time the timer is to expire. 00139 00140 Return Value: 00141 00142 If the timer is inserted in the timer tree, than a value of TRUE is 00143 returned. Otherwise, a value of FALSE is returned. 00144 00145 --*/ 00146 00147 { 00148 00149 LARGE_INTEGER CurrentTime; 00150 LARGE_INTEGER Interval; 00151 00152 // 00153 // Clear the signal state of timer if the timer period is zero and set 00154 // the inserted state to TRUE. 00155 // 00156 00157 Timer->Header.Inserted = TRUE; 00158 if (Timer->Period == 0) { 00159 Timer->Header.SignalState = FALSE; 00160 } 00161 00162 // 00163 // Compute the interval between the current time and the due time. 00164 // If the resultant relative time is greater than or equal to zero, 00165 // then the timer has already expired. 00166 // 00167 00168 KiQueryInterruptTime(&CurrentTime); 00169 Interval.QuadPart = CurrentTime.QuadPart - DueTime.QuadPart; 00170 if (Interval.QuadPart >= 0) { 00171 Timer->Header.SignalState = TRUE; 00172 Timer->Header.Inserted = FALSE; 00173 return FALSE; 00174 } 00175 00176 // 00177 // Insert the timer in the timer table and return the inserted state. 00178 // 00179 00180 return KiInsertTimerTable(Interval, CurrentTime, Timer); 00181 }


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