ReactOS 0.4.17-dev-116-ga4b6fe9
clock.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/ke/clock.c
5 * PURPOSE: System Clock Support
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7 */
8
9/* INCLUDES ******************************************************************/
10
11#include <ntoskrnl.h>
12#define NDEBUG
13#include <debug.h>
14
15/* GLOBALS *******************************************************************/
16
19volatile KSYSTEM_TIME KeTickCount = { 0, 0, 0 };
23
24/* PRIVATE FUNCTIONS *********************************************************/
25
26VOID
29 OUT PLARGE_INTEGER OldTime,
30 IN BOOLEAN FixInterruptTime,
32{
34 KIRQL OldIrql, OldIrql2;
35 LARGE_INTEGER DeltaTime;
36 PLIST_ENTRY ListHead, NextEntry;
38 PKSPIN_LOCK_QUEUE LockQueue;
39 LIST_ENTRY TempList, TempList2;
40 ULONG Hand, i;
41
42 /* Sanity checks */
43 ASSERT((NewTime->HighPart & 0xF0000000) == 0);
45
46 /* Check if this is for the HAL */
47 if (HalTime) RtlTimeToTimeFields(HalTime, &TimeFields);
48
49 /* Set affinity to this CPU, lock the dispatcher, and raise IRQL */
52 KeRaiseIrql(HIGH_LEVEL, &OldIrql2);
53
54 /* Query the system time now */
55 KeQuerySystemTime(OldTime);
56
57 /* Set the new system time (ordering of these operations is critical) */
58 KiWriteSystemTime(&SharedUserData->SystemTime, *NewTime);
59
60 /* Check if this was for the HAL and set the RTC time */
62
63 /* Calculate the difference between the new and the old time */
64 DeltaTime.QuadPart = NewTime->QuadPart - OldTime->QuadPart;
65
66 /* Update system boot time */
67 KeBootTime.QuadPart += DeltaTime.QuadPart;
69
70 /* Lower IRQL back */
71 KeLowerIrql(OldIrql2);
72
73 /* Check if we need to adjust interrupt time */
74 if (FixInterruptTime) ASSERT(FALSE);
75
76 /* Setup a temporary list of absolute timers */
77 InitializeListHead(&TempList);
78
79 /* Loop current timers */
80 for (i = 0; i < TIMER_TABLE_SIZE; i++)
81 {
82 /* Loop the entries in this table and lock the timers */
83 ListHead = &KiTimerTableListHead[i].Entry;
84 LockQueue = KiAcquireTimerLock(i);
85 NextEntry = ListHead->Flink;
86 while (NextEntry != ListHead)
87 {
88 /* Get the timer */
89 Timer = CONTAINING_RECORD(NextEntry, KTIMER, TimerListEntry);
90 NextEntry = NextEntry->Flink;
91
92 /* Is it absolute? */
93 if (Timer->Header.Absolute)
94 {
95 /* Remove it from the timer list */
97
98 /* Insert it into our temporary list */
99 InsertTailList(&TempList, &Timer->TimerListEntry);
100 }
101 }
102
103 /* Release the lock */
104 KiReleaseTimerLock(LockQueue);
105 }
106
107 /* Setup a temporary list of expired timers */
108 InitializeListHead(&TempList2);
109
110 /* Loop absolute timers */
111 while (TempList.Flink != &TempList)
112 {
113 /* Get the timer */
114 Timer = CONTAINING_RECORD(TempList.Flink, KTIMER, TimerListEntry);
115 RemoveEntryList(&Timer->TimerListEntry);
116
117 /* Update the due time and handle */
118 Timer->DueTime.QuadPart -= DeltaTime.QuadPart;
119 Hand = KiComputeTimerTableIndex(Timer->DueTime.QuadPart);
120 Timer->Header.Hand = (UCHAR)Hand;
121
122 /* Lock the timer and re-insert it */
123 LockQueue = KiAcquireTimerLock(Hand);
124 if (KiInsertTimerTable(Timer, Hand))
125 {
126 /* Remove it from the timer list */
128
129 /* Insert it into our temporary list */
130 InsertTailList(&TempList2, &Timer->TimerListEntry);
131 }
132
133 /* Release the lock */
134 KiReleaseTimerLock(LockQueue);
135 }
136
137 /* Process expired timers. This releases the dispatcher lock. */
138 KiTimerListExpire(&TempList2, OldIrql);
139
140 /* Revert affinity */
142}
143
144/* PUBLIC FUNCTIONS **********************************************************/
145
146/*
147 * @implemented
148 */
149ULONG
150NTAPI
152{
153 /* Return the increment */
154 return KeMaximumIncrement;
155}
156
157/*
158 * @implemented
159 */
160#undef KeQueryTickCount
161VOID
162NTAPI
164{
165 *TickCount = KiReadSystemTime(&KeTickCount);
166}
167
168#ifndef _M_AMD64
169/*
170 * @implemented
171 */
172VOID
173NTAPI
175{
176 /* Loop until we get a perfect match */
177 for (;;)
178 {
179 /* Read the time value */
180 CurrentTime->HighPart = SharedUserData->SystemTime.High1Time;
181 CurrentTime->LowPart = SharedUserData->SystemTime.LowPart;
182 if (CurrentTime->HighPart ==
183 SharedUserData->SystemTime.High2Time) break;
185 }
186}
187
188/*
189 * @implemented
190 */
192NTAPI
194{
195 LARGE_INTEGER CurrentTime;
196
197 /* Loop until we get a perfect match */
198 for (;;)
199 {
200 /* Read the time value */
201 CurrentTime.HighPart = SharedUserData->InterruptTime.High1Time;
202 CurrentTime.LowPart = SharedUserData->InterruptTime.LowPart;
203 if (CurrentTime.HighPart ==
204 SharedUserData->InterruptTime.High2Time) break;
206 }
207
208 /* Return the time value */
209 return CurrentTime.QuadPart;
210}
211#endif
212
213/*
214 * @implemented
215 */
216VOID
217NTAPI
219 IN ULONG MinIncrement)
220{
221 /* Set some Internal Variables */
222 KeMaximumIncrement = MaxIncrement;
223 KeMinimumIncrement = max(MinIncrement, 10000);
224 KeTimeAdjustment = MaxIncrement;
225 KeTimeIncrement = MaxIncrement;
226 KiTickOffset = MaxIncrement;
227}
228
229/* EOF */
unsigned char BOOLEAN
Definition: actypes.h:127
#define FALSE
Definition: types.h:117
BOOLEAN RtlTimeToTimeFields(IN PLARGE_INTEGER Time, IN PTIME_FIELDS TimeFields)
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define HIGH_LEVEL
Definition: env_spec_w32.h:703
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
FORCEINLINE VOID KiRemoveEntryTimer(IN PKTIMER Timer)
Definition: ke_x.h:892
FORCEINLINE VOID KiReleaseTimerLock(IN PKSPIN_LOCK_QUEUE LockQueue)
Definition: ke_x.h:297
FORCEINLINE ULONG KiComputeTimerTableIndex(IN ULONGLONG DueTime)
Definition: ke_x.h:881
FORCEINLINE PKSPIN_LOCK_QUEUE KiAcquireTimerLock(IN ULONG Hand)
Definition: ke_x.h:286
FORCEINLINE KIRQL KiAcquireDispatcherLock(VOID)
Definition: ke_x.h:149
#define ASSERT(a)
Definition: mode.c:44
static PTIME_FIELDS TimeFields
Definition: time.c:36
FORCEINLINE VOID KiWriteSystemTime(_Out_ volatile KSYSTEM_TIME *SystemTime, _In_ LARGE_INTEGER NewTime)
Definition: kefuncs.h:429
FORCEINLINE LARGE_INTEGER KiReadSystemTime(_In_ volatile const KSYSTEM_TIME *SystemTime)
Definition: kefuncs.h:403
#define _Out_
Definition: no_sal2.h:160
BOOLEAN ExCmosClockIsSane
Definition: init.c:93
KTIMER_TABLE_ENTRY KiTimerTableListHead[TIMER_TABLE_SIZE]
Definition: timerobj.c:17
LONG KiTickOffset
Definition: time.c:17
ULONG KeTimeAdjustment
Definition: time.c:18
BOOLEAN FASTCALL KiInsertTimerTable(IN PKTIMER Timer, IN ULONG Hand)
Definition: timerobj.c:63
VOID FASTCALL KiTimerListExpire(IN PLIST_ENTRY ExpiredListHead, IN KIRQL OldIrql)
Definition: dpc.c:338
ULONG KeMinimumIncrement
Definition: clock.c:21
VOID NTAPI KeSetTimeIncrement(IN ULONG MaxIncrement, IN ULONG MinIncrement)
Definition: clock.c:218
ULONGLONG KeBootTimeBias
Definition: clock.c:18
ULONG KeMaximumIncrement
Definition: clock.c:20
volatile KSYSTEM_TIME KeTickCount
Definition: clock.c:19
ULONG NTAPI KeQueryTimeIncrement(VOID)
Definition: clock.c:151
ULONG KeTimeIncrement
Definition: clock.c:22
LARGE_INTEGER KeBootTime
Definition: clock.c:17
VOID NTAPI KeSetSystemTime(IN PLARGE_INTEGER NewTime, OUT PLARGE_INTEGER OldTime, IN BOOLEAN FixInterruptTime, IN PLARGE_INTEGER HalTime OPTIONAL)
Definition: clock.c:28
BOOLEAN NTAPI HalSetRealTimeClock(IN PTIME_FIELDS Time)
Definition: rtc.c:45
#define KeQueryTickCount(CurrentCount)
Definition: ke.h:43
#define YieldProcessor
Definition: ke.h:48
#define KeQueryInterruptTime()
Definition: ke.h:37
#define SharedUserData
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
LIST_ENTRY Entry
Definition: ketypes.h:903
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define max(a, b)
Definition: svc.c:63
VOID NTAPI KeSetSystemAffinityThread(IN KAFFINITY Affinity)
Definition: thrdobj.c:1107
VOID NTAPI KeRevertToUserAffinityThread(VOID)
Definition: thrdobj.c:1021
unsigned char UCHAR
Definition: typedefs.h:53
#define NTAPI
Definition: typedefs.h:36
uint64_t ULONGLONG
Definition: typedefs.h:67
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG LowPart
Definition: typedefs.h:106
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
#define TIMER_TABLE_SIZE
Definition: ketypes.h:900