ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

clock.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.