mirror of
https://github.com/reactos/reactos
synced 2025-10-07 00:42:44 +02:00
Compare commits
2 Commits
powermeter
...
ntos/KiWri
Author | SHA1 | Date | |
---|---|---|---|
|
fb0752b5f5 | ||
|
db47b59b11 |
@@ -1221,27 +1221,19 @@ ULONG
|
||||
NTAPI
|
||||
RtlGetTickCount(VOID)
|
||||
{
|
||||
ULARGE_INTEGER TickCount;
|
||||
LARGE_INTEGER TickCount;
|
||||
|
||||
TickCount = KiReadSystemTime(&SharedUserData->TickCount);
|
||||
|
||||
#ifdef _WIN64
|
||||
TickCount.QuadPart = *((volatile ULONG64*)&SharedUserData->TickCount);
|
||||
return (TickCount.QuadPart * SharedUserData->TickCountMultiplier) >> 24;
|
||||
#else
|
||||
while (TRUE)
|
||||
{
|
||||
TickCount.HighPart = (ULONG)SharedUserData->TickCount.High1Time;
|
||||
TickCount.LowPart = SharedUserData->TickCount.LowPart;
|
||||
|
||||
if (TickCount.HighPart == (ULONG)SharedUserData->TickCount.High2Time)
|
||||
break;
|
||||
|
||||
YieldProcessor();
|
||||
}
|
||||
#endif
|
||||
|
||||
ULONG TickCountMultiplier = SharedUserData->TickCountMultiplier;
|
||||
return (ULONG)((UInt32x32To64(TickCount.LowPart,
|
||||
SharedUserData->TickCountMultiplier) >> 24) +
|
||||
TickCountMultiplier) >> 24) +
|
||||
UInt32x32To64((TickCount.HighPart << 8) & 0xFFFFFFFF,
|
||||
SharedUserData->TickCountMultiplier));
|
||||
TickCountMultiplier));
|
||||
#endif
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
@@ -129,12 +129,7 @@ GetSystemTimeAsFileTime(OUT PFILETIME lpFileTime)
|
||||
{
|
||||
LARGE_INTEGER SystemTime;
|
||||
|
||||
do
|
||||
{
|
||||
SystemTime.HighPart = SharedUserData->SystemTime.High1Time;
|
||||
SystemTime.LowPart = SharedUserData->SystemTime.LowPart;
|
||||
}
|
||||
while (SystemTime.HighPart != SharedUserData->SystemTime.High2Time);
|
||||
SystemTime = KiReadSystemTime(&SharedUserData->SystemTime);
|
||||
|
||||
lpFileTime->dwLowDateTime = SystemTime.LowPart;
|
||||
lpFileTime->dwHighDateTime = SystemTime.HighPart;
|
||||
@@ -227,12 +222,8 @@ FileTimeToLocalFileTime(IN CONST FILETIME *lpFileTime,
|
||||
TimePtr = IsTimeZoneRedirectionEnabled() ?
|
||||
&BaseStaticServerData->ktTermsrvClientBias :
|
||||
&SharedUserData->TimeZoneBias;
|
||||
do
|
||||
{
|
||||
TimeZoneBias.HighPart = TimePtr->High1Time;
|
||||
TimeZoneBias.LowPart = TimePtr->LowPart;
|
||||
}
|
||||
while (TimeZoneBias.HighPart != TimePtr->High2Time);
|
||||
|
||||
TimeZoneBias = KiReadSystemTime(TimePtr);
|
||||
|
||||
FileTime.LowPart = lpFileTime->dwLowDateTime;
|
||||
FileTime.HighPart = lpFileTime->dwHighDateTime;
|
||||
@@ -260,12 +251,7 @@ LocalFileTimeToFileTime(IN CONST FILETIME *lpLocalFileTime,
|
||||
&BaseStaticServerData->ktTermsrvClientBias :
|
||||
&SharedUserData->TimeZoneBias;
|
||||
|
||||
do
|
||||
{
|
||||
TimeZoneBias.HighPart = TimePtr->High1Time;
|
||||
TimeZoneBias.LowPart = TimePtr->LowPart;
|
||||
}
|
||||
while (TimeZoneBias.HighPart != TimePtr->High2Time);
|
||||
TimeZoneBias = KiReadSystemTime(TimePtr);
|
||||
|
||||
FileTime.LowPart = lpLocalFileTime->dwLowDateTime;
|
||||
FileTime.HighPart = lpLocalFileTime->dwHighDateTime;
|
||||
@@ -289,22 +275,13 @@ GetLocalTime(OUT LPSYSTEMTIME lpSystemTime)
|
||||
TIME_FIELDS TimeFields;
|
||||
volatile KSYSTEM_TIME *TimePtr;
|
||||
|
||||
do
|
||||
{
|
||||
SystemTime.HighPart = SharedUserData->SystemTime.High1Time;
|
||||
SystemTime.LowPart = SharedUserData->SystemTime.LowPart;
|
||||
}
|
||||
while (SystemTime.HighPart != SharedUserData->SystemTime.High2Time);
|
||||
SystemTime = KiReadSystemTime(&SharedUserData->SystemTime);
|
||||
|
||||
TimePtr = IsTimeZoneRedirectionEnabled() ?
|
||||
&BaseStaticServerData->ktTermsrvClientBias :
|
||||
&SharedUserData->TimeZoneBias;
|
||||
do
|
||||
{
|
||||
TimeZoneBias.HighPart = TimePtr->High1Time;
|
||||
TimeZoneBias.LowPart = TimePtr->LowPart;
|
||||
}
|
||||
while (TimeZoneBias.HighPart != TimePtr->High2Time);
|
||||
|
||||
TimeZoneBias = KiReadSystemTime(TimePtr);
|
||||
|
||||
SystemTime.QuadPart -= TimeZoneBias.QuadPart;
|
||||
RtlTimeToTimeFields(&SystemTime, &TimeFields);
|
||||
|
@@ -8,18 +8,15 @@ ULONGLONG
|
||||
WINAPI
|
||||
GetTickCount64(VOID)
|
||||
{
|
||||
ULARGE_INTEGER TickCount;
|
||||
LARGE_INTEGER TickCount;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
TickCount.HighPart = (ULONG)SharedUserData->TickCount.High1Time;
|
||||
TickCount.LowPart = SharedUserData->TickCount.LowPart;
|
||||
TickCount = KiReadSystemTime(&SharedUserData->TickCount);
|
||||
|
||||
if (TickCount.HighPart == (ULONG)SharedUserData->TickCount.High2Time) break;
|
||||
|
||||
YieldProcessor();
|
||||
}
|
||||
|
||||
return (UInt32x32To64(TickCount.LowPart, SharedUserData->TickCountMultiplier) >> 24) +
|
||||
(UInt32x32To64(TickCount.HighPart, SharedUserData->TickCountMultiplier) << 8);
|
||||
#ifdef _WIN64
|
||||
return (TickCount.QuadPart * SharedUserData->TickCountMultiplier) >> 24;
|
||||
#else
|
||||
ULONG TickCountMultiplier = SharedUserData->TickCountMultiplier;
|
||||
return (UInt32x32To64(TickCount.LowPart, TickCountMultiplier) >> 24) +
|
||||
(UInt32x32To64(TickCount.HighPart, TickCountMultiplier) << 8);
|
||||
#endif
|
||||
}
|
||||
|
@@ -1550,9 +1550,7 @@ Phase1InitializationDiscard(IN PVOID Context)
|
||||
10000000);
|
||||
|
||||
/* Set the boot time-zone bias */
|
||||
SharedUserData->TimeZoneBias.High2Time = ExpTimeZoneBias.HighPart;
|
||||
SharedUserData->TimeZoneBias.LowPart = ExpTimeZoneBias.LowPart;
|
||||
SharedUserData->TimeZoneBias.High1Time = ExpTimeZoneBias.HighPart;
|
||||
KiWriteSystemTime(&SharedUserData->TimeZoneBias, ExpTimeZoneBias);
|
||||
|
||||
/* Convert the boot time to local time, and set it */
|
||||
UniversalBootTime.QuadPart = SystemBootTime.QuadPart +
|
||||
|
@@ -336,9 +336,7 @@ ExRefreshTimeZoneInformation(IN PLARGE_INTEGER CurrentBootTime)
|
||||
ExpTimeZoneBias = NewTimeZoneBias;
|
||||
|
||||
/* Change SharedUserData->TimeZoneBias for user-mode applications */
|
||||
SharedUserData->TimeZoneBias.High2Time = ExpTimeZoneBias.u.HighPart;
|
||||
SharedUserData->TimeZoneBias.LowPart = ExpTimeZoneBias.u.LowPart;
|
||||
SharedUserData->TimeZoneBias.High1Time = ExpTimeZoneBias.u.HighPart;
|
||||
KiWriteSystemTime(&SharedUserData->TimeZoneBias, ExpTimeZoneBias);
|
||||
SharedUserData->TimeZoneId = ExpTimeZoneId;
|
||||
|
||||
/* Convert boot time from local time to UTC */
|
||||
@@ -349,9 +347,7 @@ ExRefreshTimeZoneInformation(IN PLARGE_INTEGER CurrentBootTime)
|
||||
|
||||
/* Change it for user-mode applications */
|
||||
CurrentTime.QuadPart += ExpTimeZoneBias.QuadPart;
|
||||
SharedUserData->SystemTime.High2Time = CurrentTime.u.HighPart;
|
||||
SharedUserData->SystemTime.LowPart = CurrentTime.u.LowPart;
|
||||
SharedUserData->SystemTime.High1Time = CurrentTime.u.HighPart;
|
||||
KiWriteSystemTime(&SharedUserData->SystemTime, CurrentTime);
|
||||
|
||||
/* Return success */
|
||||
return TRUE;
|
||||
@@ -424,9 +420,7 @@ ExpSetTimeZoneInformation(PRTL_TIME_ZONE_INFORMATION TimeZoneInformation)
|
||||
sizeof(RTL_TIME_ZONE_INFORMATION));
|
||||
|
||||
/* Set the new time zone information */
|
||||
SharedUserData->TimeZoneBias.High1Time = ExpTimeZoneBias.u.HighPart;
|
||||
SharedUserData->TimeZoneBias.High2Time = ExpTimeZoneBias.u.HighPart;
|
||||
SharedUserData->TimeZoneBias.LowPart = ExpTimeZoneBias.u.LowPart;
|
||||
KiWriteSystemTime(&SharedUserData->TimeZoneBias, ExpTimeZoneBias);
|
||||
SharedUserData->TimeZoneId = ExpTimeZoneId;
|
||||
|
||||
DPRINT("New time zone bias: %I64d minutes\n",
|
||||
|
@@ -55,9 +55,7 @@ KeSetSystemTime(IN PLARGE_INTEGER NewTime,
|
||||
KeQuerySystemTime(OldTime);
|
||||
|
||||
/* Set the new system time (ordering of these operations is critical) */
|
||||
SharedUserData->SystemTime.High2Time = NewTime->HighPart;
|
||||
SharedUserData->SystemTime.LowPart = NewTime->LowPart;
|
||||
SharedUserData->SystemTime.High1Time = NewTime->HighPart;
|
||||
KiWriteSystemTime(&SharedUserData->SystemTime, *NewTime);
|
||||
|
||||
/* Check if this was for the HAL and set the RTC time */
|
||||
if (HalTime) ExCmosClockIsSane = HalSetRealTimeClock(&TimeFields);
|
||||
@@ -164,15 +162,7 @@ VOID
|
||||
NTAPI
|
||||
KeQueryTickCount(IN PLARGE_INTEGER TickCount)
|
||||
{
|
||||
/* Loop until we get a perfect match */
|
||||
for (;;)
|
||||
{
|
||||
/* Read the tick count value */
|
||||
TickCount->HighPart = KeTickCount.High1Time;
|
||||
TickCount->LowPart = KeTickCount.LowPart;
|
||||
if (TickCount->HighPart == KeTickCount.High2Time) break;
|
||||
YieldProcessor();
|
||||
}
|
||||
*TickCount = KiReadSystemTime(&KeTickCount);
|
||||
}
|
||||
|
||||
#ifndef _M_AMD64
|
||||
|
@@ -20,33 +20,18 @@ BOOLEAN KiTimeAdjustmentEnabled = FALSE;
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
FORCEINLINE
|
||||
VOID
|
||||
KiWriteSystemTime(volatile KSYSTEM_TIME *SystemTime, ULARGE_INTEGER NewTime)
|
||||
{
|
||||
#ifdef _WIN64
|
||||
/* Do a single atomic write */
|
||||
*(ULONGLONG*)SystemTime = NewTime.QuadPart;
|
||||
#else
|
||||
/* Update in 3 steps, so that a reader can recognize partial updates */
|
||||
SystemTime->High1Time = NewTime.HighPart;
|
||||
SystemTime->LowPart = NewTime.LowPart;
|
||||
#endif
|
||||
SystemTime->High2Time = NewTime.HighPart;
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
VOID
|
||||
KiCheckForTimerExpiration(
|
||||
PKPRCB Prcb,
|
||||
PKTRAP_FRAME TrapFrame,
|
||||
ULARGE_INTEGER InterruptTime)
|
||||
LARGE_INTEGER InterruptTime)
|
||||
{
|
||||
ULONG Hand;
|
||||
|
||||
/* Check for timer expiration */
|
||||
Hand = KeTickCount.LowPart & (TIMER_TABLE_SIZE - 1);
|
||||
if (KiTimerTableListHead[Hand].Time.QuadPart <= InterruptTime.QuadPart)
|
||||
if (KiTimerTableListHead[Hand].Time.QuadPart <= (ULONG64)InterruptTime.QuadPart)
|
||||
{
|
||||
/* Check if we are already doing expiration */
|
||||
if (!Prcb->TimerRequest)
|
||||
@@ -66,7 +51,7 @@ KeUpdateSystemTime(IN PKTRAP_FRAME TrapFrame,
|
||||
IN KIRQL Irql)
|
||||
{
|
||||
PKPRCB Prcb = KeGetCurrentPrcb();
|
||||
ULARGE_INTEGER CurrentTime, InterruptTime;
|
||||
LARGE_INTEGER CurrentTime, InterruptTime;
|
||||
LONG OldTickOffset;
|
||||
|
||||
/* Check if this tick is being skipped */
|
||||
|
@@ -394,6 +394,58 @@ KeRaiseUserException(
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef NONAMELESSUNION
|
||||
|
||||
FORCEINLINE
|
||||
LARGE_INTEGER
|
||||
KiReadSystemTime(
|
||||
_In_ volatile const KSYSTEM_TIME *SystemTime)
|
||||
{
|
||||
LARGE_INTEGER Time;
|
||||
|
||||
#ifdef _WIN64
|
||||
/* Do a single atomic read */
|
||||
Time.QuadPart = *(volatile ULONG64*)SystemTime;
|
||||
#else
|
||||
/* Read in a loop until we get a match */
|
||||
for (;;)
|
||||
{
|
||||
Time.HighPart = SystemTime->High1Time;
|
||||
Time.LowPart = SystemTime->LowPart;
|
||||
if (Time.HighPart == SystemTime->High2Time) break;
|
||||
YieldProcessor();
|
||||
}
|
||||
#endif
|
||||
return Time;
|
||||
}
|
||||
|
||||
#ifndef NTOS_MODE_USER
|
||||
|
||||
FORCEINLINE
|
||||
VOID
|
||||
KiWriteSystemTime(
|
||||
_Out_ volatile KSYSTEM_TIME *SystemTime,
|
||||
_In_ LARGE_INTEGER NewTime)
|
||||
{
|
||||
/* Update High2Time first to indicate an update in progress */
|
||||
SystemTime->High2Time = NewTime.HighPart;
|
||||
|
||||
#ifdef _WIN64
|
||||
/* Do a single 'atomic' write. This isn't actually guaranteed to be atomic,
|
||||
if the address isn't 64 bit aligned. But as long as the entire 64 bits
|
||||
are within a single cache line, we should be good (on x64 at least,
|
||||
when it comes to ARM64, all bets are off) This is also what Windows does. */
|
||||
*(LONGLONG*)SystemTime = NewTime.QuadPart;
|
||||
#else
|
||||
/* Update low part, then high part to allow readers detect partial updates. */
|
||||
SystemTime->LowPart = NewTime.LowPart;
|
||||
SystemTime->High1Time = NewTime.HighPart;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // !NTOS_MODE_USER
|
||||
#endif // !NONAMELESSUNION
|
||||
|
||||
//
|
||||
// Native Calls
|
||||
//
|
||||
|
Reference in New Issue
Block a user