ReactOS 0.4.15-dev-8138-g1e75ea8
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 SharedUserData->SystemTime.High2Time = NewTime->HighPart;
59 SharedUserData->SystemTime.LowPart = NewTime->LowPart;
60 SharedUserData->SystemTime.High1Time = NewTime->HighPart;
61
62 /* Check if this was for the HAL and set the RTC time */
64
65 /* Calculate the difference between the new and the old time */
66 DeltaTime.QuadPart = NewTime->QuadPart - OldTime->QuadPart;
67
68 /* Update system boot time */
69 KeBootTime.QuadPart += DeltaTime.QuadPart;
71
72 /* Lower IRQL back */
73 KeLowerIrql(OldIrql2);
74
75 /* Check if we need to adjust interrupt time */
76 if (FixInterruptTime) ASSERT(FALSE);
77
78 /* Setup a temporary list of absolute timers */
79 InitializeListHead(&TempList);
80
81 /* Loop current timers */
82 for (i = 0; i < TIMER_TABLE_SIZE; i++)
83 {
84 /* Loop the entries in this table and lock the timers */
85 ListHead = &KiTimerTableListHead[i].Entry;
86 LockQueue = KiAcquireTimerLock(i);
87 NextEntry = ListHead->Flink;
88 while (NextEntry != ListHead)
89 {
90 /* Get the timer */
91 Timer = CONTAINING_RECORD(NextEntry, KTIMER, TimerListEntry);
92 NextEntry = NextEntry->Flink;
93
94 /* Is it absolute? */
95 if (Timer->Header.Absolute)
96 {
97 /* Remove it from the timer list */
99
100 /* Insert it into our temporary list */
101 InsertTailList(&TempList, &Timer->TimerListEntry);
102 }
103 }
104
105 /* Release the lock */
106 KiReleaseTimerLock(LockQueue);
107 }
108
109 /* Setup a temporary list of expired timers */
110 InitializeListHead(&TempList2);
111
112 /* Loop absolute timers */
113 while (TempList.Flink != &TempList)
114 {
115 /* Get the timer */
116 Timer = CONTAINING_RECORD(TempList.Flink, KTIMER, TimerListEntry);
117 RemoveEntryList(&Timer->TimerListEntry);
118
119 /* Update the due time and handle */
120 Timer->DueTime.QuadPart -= DeltaTime.QuadPart;
121 Hand = KiComputeTimerTableIndex(Timer->DueTime.QuadPart);
122 Timer->Header.Hand = (UCHAR)Hand;
123
124 /* Lock the timer and re-insert it */
125 LockQueue = KiAcquireTimerLock(Hand);
126 if (KiInsertTimerTable(Timer, Hand))
127 {
128 /* Remove it from the timer list */
130
131 /* Insert it into our temporary list */
132 InsertTailList(&TempList2, &Timer->TimerListEntry);
133 }
134
135 /* Release the lock */
136 KiReleaseTimerLock(LockQueue);
137 }
138
139 /* Process expired timers. This releases the dispatcher lock. */
140 KiTimerListExpire(&TempList2, OldIrql);
141
142 /* Revert affinity */
144}
145
146/* PUBLIC FUNCTIONS **********************************************************/
147
148/*
149 * @implemented
150 */
151ULONG
152NTAPI
154{
155 /* Return the increment */
156 return KeMaximumIncrement;
157}
158
159/*
160 * @implemented
161 */
162#undef KeQueryTickCount
163VOID
164NTAPI
166{
167 /* Loop until we get a perfect match */
168 for (;;)
169 {
170 /* Read the tick count value */
171 TickCount->HighPart = KeTickCount.High1Time;
172 TickCount->LowPart = KeTickCount.LowPart;
173 if (TickCount->HighPart == KeTickCount.High2Time) break;
175 }
176}
177
178#ifndef _M_AMD64
179/*
180 * @implemented
181 */
182VOID
183NTAPI
185{
186 /* Loop until we get a perfect match */
187 for (;;)
188 {
189 /* Read the time value */
190 CurrentTime->HighPart = SharedUserData->SystemTime.High1Time;
191 CurrentTime->LowPart = SharedUserData->SystemTime.LowPart;
192 if (CurrentTime->HighPart ==
193 SharedUserData->SystemTime.High2Time) break;
195 }
196}
197
198/*
199 * @implemented
200 */
202NTAPI
204{
205 LARGE_INTEGER CurrentTime;
206
207 /* Loop until we get a perfect match */
208 for (;;)
209 {
210 /* Read the time value */
211 CurrentTime.HighPart = SharedUserData->InterruptTime.High1Time;
212 CurrentTime.LowPart = SharedUserData->InterruptTime.LowPart;
213 if (CurrentTime.HighPart ==
214 SharedUserData->InterruptTime.High2Time) break;
216 }
217
218 /* Return the time value */
219 return CurrentTime.QuadPart;
220}
221#endif
222
223/*
224 * @implemented
225 */
226VOID
227NTAPI
229 IN ULONG MinIncrement)
230{
231 /* Set some Internal Variables */
232 KeMaximumIncrement = MaxIncrement;
233 KeMinimumIncrement = max(MinIncrement, 10000);
234 KeTimeAdjustment = MaxIncrement;
235 KeTimeIncrement = MaxIncrement;
236 KiTickOffset = MaxIncrement;
237}
238
239/* EOF */
unsigned char BOOLEAN
#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:104
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:228
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:153
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
LONG High1Time
Definition: ketypes.h:930
LONG High2Time
Definition: ketypes.h:931
ULONG LowPart
Definition: ketypes.h:929
LIST_ENTRY Entry
Definition: ketypes.h:778
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
#define NTAPI
Definition: typedefs.h:36
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#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:848
unsigned char UCHAR
Definition: xmlstorage.h:181