test: timersup.c File Reference

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 }