Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenclock.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Kernel 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: ntoskrnl/ke/clock.c 00005 * PURPOSE: System Clock Support 00006 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) 00007 */ 00008 00009 /* INCLUDES ******************************************************************/ 00010 00011 #include <ntoskrnl.h> 00012 #define NDEBUG 00013 #include <debug.h> 00014 00015 /* GLOBALS *******************************************************************/ 00016 00017 LARGE_INTEGER KeBootTime; 00018 ULONGLONG KeBootTimeBias; 00019 volatile KSYSTEM_TIME KeTickCount = { 0, 0, 0 }; 00020 ULONG KeMaximumIncrement; 00021 ULONG KeMinimumIncrement; 00022 ULONG KeTimeIncrement; 00023 00024 /* PRIVATE FUNCTIONS *********************************************************/ 00025 00026 VOID 00027 NTAPI 00028 KeSetSystemTime(IN PLARGE_INTEGER NewTime, 00029 OUT PLARGE_INTEGER OldTime, 00030 IN BOOLEAN FixInterruptTime, 00031 IN PLARGE_INTEGER HalTime OPTIONAL) 00032 { 00033 TIME_FIELDS TimeFields; 00034 KIRQL OldIrql, OldIrql2; 00035 LARGE_INTEGER DeltaTime; 00036 PLIST_ENTRY ListHead, NextEntry; 00037 PKTIMER Timer; 00038 PKSPIN_LOCK_QUEUE LockQueue; 00039 LIST_ENTRY TempList, TempList2; 00040 ULONG Hand, i; 00041 00042 /* Sanity checks */ 00043 ASSERT((NewTime->HighPart & 0xF0000000) == 0); 00044 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 00045 00046 /* Check if this is for the HAL */ 00047 if (HalTime) RtlTimeToTimeFields(HalTime, &TimeFields); 00048 00049 /* Set affinity to this CPU, lock the dispatcher, and raise IRQL */ 00050 KeSetSystemAffinityThread(1); 00051 OldIrql = KiAcquireDispatcherLock(); 00052 KeRaiseIrql(HIGH_LEVEL, &OldIrql2); 00053 00054 /* Query the system time now */ 00055 KeQuerySystemTime(OldTime); 00056 00057 /* Set the new system time (ordering of these operations is critical) */ 00058 SharedUserData->SystemTime.High2Time = NewTime->HighPart; 00059 SharedUserData->SystemTime.LowPart = NewTime->LowPart; 00060 SharedUserData->SystemTime.High1Time = NewTime->HighPart; 00061 00062 /* Check if this was for the HAL and set the RTC time */ 00063 if (HalTime) ExCmosClockIsSane = HalSetRealTimeClock(&TimeFields); 00064 00065 /* Calculate the difference between the new and the old time */ 00066 DeltaTime.QuadPart = NewTime->QuadPart - OldTime->QuadPart; 00067 00068 /* Update system boot time */ 00069 KeBootTime.QuadPart += DeltaTime.QuadPart; 00070 KeBootTimeBias = KeBootTimeBias + DeltaTime.QuadPart; 00071 00072 /* Lower IRQL back */ 00073 KeLowerIrql(OldIrql2); 00074 00075 /* Check if we need to adjust interrupt time */ 00076 if (FixInterruptTime) ASSERT(FALSE); 00077 00078 /* Setup a temporary list of absolute timers */ 00079 InitializeListHead(&TempList); 00080 00081 /* Loop current timers */ 00082 for (i = 0; i < TIMER_TABLE_SIZE; i++) 00083 { 00084 /* Loop the entries in this table and lock the timers */ 00085 ListHead = &KiTimerTableListHead[i].Entry; 00086 LockQueue = KiAcquireTimerLock(i); 00087 NextEntry = ListHead->Flink; 00088 while (NextEntry != ListHead) 00089 { 00090 /* Get the timer */ 00091 Timer = CONTAINING_RECORD(NextEntry, KTIMER, TimerListEntry); 00092 NextEntry = NextEntry->Flink; 00093 00094 /* Is it absolute? */ 00095 if (Timer->Header.Absolute) 00096 { 00097 /* Remove it from the timer list */ 00098 KiRemoveEntryTimer(Timer); 00099 00100 /* Insert it into our temporary list */ 00101 InsertTailList(&TempList, &Timer->TimerListEntry); 00102 } 00103 } 00104 00105 /* Release the lock */ 00106 KiReleaseTimerLock(LockQueue); 00107 } 00108 00109 /* Setup a temporary list of expired timers */ 00110 InitializeListHead(&TempList2); 00111 00112 /* Loop absolute timers */ 00113 while (TempList.Flink != &TempList) 00114 { 00115 /* Get the timer */ 00116 Timer = CONTAINING_RECORD(TempList.Flink, KTIMER, TimerListEntry); 00117 RemoveEntryList(&Timer->TimerListEntry); 00118 00119 /* Update the due time and handle */ 00120 Timer->DueTime.QuadPart -= DeltaTime.QuadPart; 00121 Hand = KiComputeTimerTableIndex(Timer->DueTime.QuadPart); 00122 Timer->Header.Hand = (UCHAR)Hand; 00123 00124 /* Lock the timer and re-insert it */ 00125 LockQueue = KiAcquireTimerLock(Hand); 00126 if (KiInsertTimerTable(Timer, Hand)) 00127 { 00128 /* Remove it from the timer list */ 00129 KiRemoveEntryTimer(Timer); 00130 00131 /* Insert it into our temporary list */ 00132 InsertTailList(&TempList2, &Timer->TimerListEntry); 00133 } 00134 00135 /* Release the lock */ 00136 KiReleaseTimerLock(LockQueue); 00137 } 00138 00139 /* Process expired timers. This releases the dispatcher lock. */ 00140 KiTimerListExpire(&TempList2, OldIrql); 00141 00142 /* Revert affinity */ 00143 KeRevertToUserAffinityThread(); 00144 } 00145 00146 /* PUBLIC FUNCTIONS **********************************************************/ 00147 00148 /* 00149 * @implemented 00150 */ 00151 ULONG 00152 NTAPI 00153 KeQueryTimeIncrement(VOID) 00154 { 00155 /* Return the increment */ 00156 return KeMaximumIncrement; 00157 } 00158 00159 /* 00160 * @implemented 00161 */ 00162 #undef KeQueryTickCount 00163 VOID 00164 NTAPI 00165 KeQueryTickCount(IN PLARGE_INTEGER TickCount) 00166 { 00167 /* Loop until we get a perfect match */ 00168 for (;;) 00169 { 00170 /* Read the tick count value */ 00171 TickCount->HighPart = KeTickCount.High1Time; 00172 TickCount->LowPart = KeTickCount.LowPart; 00173 if (TickCount->HighPart == KeTickCount.High2Time) break; 00174 YieldProcessor(); 00175 } 00176 } 00177 00178 #ifndef _M_AMD64 00179 /* 00180 * @implemented 00181 */ 00182 VOID 00183 NTAPI 00184 KeQuerySystemTime(OUT PLARGE_INTEGER CurrentTime) 00185 { 00186 /* Loop until we get a perfect match */ 00187 for (;;) 00188 { 00189 /* Read the time value */ 00190 CurrentTime->HighPart = SharedUserData->SystemTime.High1Time; 00191 CurrentTime->LowPart = SharedUserData->SystemTime.LowPart; 00192 if (CurrentTime->HighPart == 00193 SharedUserData->SystemTime.High2Time) break; 00194 YieldProcessor(); 00195 } 00196 } 00197 00198 /* 00199 * @implemented 00200 */ 00201 ULONGLONG 00202 NTAPI 00203 KeQueryInterruptTime(VOID) 00204 { 00205 LARGE_INTEGER CurrentTime; 00206 00207 /* Loop until we get a perfect match */ 00208 for (;;) 00209 { 00210 /* Read the time value */ 00211 CurrentTime.HighPart = SharedUserData->InterruptTime.High1Time; 00212 CurrentTime.LowPart = SharedUserData->InterruptTime.LowPart; 00213 if (CurrentTime.HighPart == 00214 SharedUserData->InterruptTime.High2Time) break; 00215 YieldProcessor(); 00216 } 00217 00218 /* Return the time value */ 00219 return CurrentTime.QuadPart; 00220 } 00221 #endif 00222 00223 /* 00224 * @implemented 00225 */ 00226 VOID 00227 NTAPI 00228 KeSetTimeIncrement(IN ULONG MaxIncrement, 00229 IN ULONG MinIncrement) 00230 { 00231 /* Set some Internal Variables */ 00232 KeMaximumIncrement = MaxIncrement; 00233 KeMinimumIncrement = max(MinIncrement, 10000); 00234 KeTimeAdjustment = MaxIncrement; 00235 KeTimeIncrement = MaxIncrement; 00236 KiTickOffset = MaxIncrement; 00237 } 00238 00239 NTSTATUS 00240 NTAPI 00241 NtQueryTimerResolution(OUT PULONG MinimumResolution, 00242 OUT PULONG MaximumResolution, 00243 OUT PULONG ActualResolution) 00244 { 00245 UNIMPLEMENTED; 00246 return STATUS_NOT_IMPLEMENTED; 00247 } 00248 00249 NTSTATUS 00250 NTAPI 00251 NtSetTimerResolution(IN ULONG DesiredResolution, 00252 IN BOOLEAN SetResolution, 00253 OUT PULONG CurrentResolution) 00254 { 00255 UNIMPLEMENTED; 00256 return STATUS_NOT_IMPLEMENTED; 00257 } 00258 00259 /* EOF */ Generated on Thu May 24 2012 04:21:24 for ReactOS by
1.7.6.1
|