On 4/28/20 10:11 AM, Rémi Bernon wrote:
Original patch from: Andrew Wesie awesie@gmail.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
v3: Server-side implementation of USD timestamp updates.
The system time check still has some large diffs compared to native after patch #2, probably because of some different clock granularity between server and client.
I didn't include an InterruptTime test because depending on the Windows versions, RtlQueryUnbiasedInterruptTime sometimes doesn't match the USD clock.
I'm sending it as RFC as it's still a little bit rough on the edges, and I only tested on Linux so far.
dlls/ntdll/tests/time.c | 52 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+)
diff --git a/dlls/ntdll/tests/time.c b/dlls/ntdll/tests/time.c index 5382a952d8d8..cc6e9f226e63 100644 --- a/dlls/ntdll/tests/time.c +++ b/dlls/ntdll/tests/time.c @@ -18,7 +18,9 @@
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#define NONAMELESSUNION #include "ntdll_test.h" +#include "ddk/wdm.h"
#define TICKSPERSEC 10000000 #define TICKSPERMSEC 10000 @@ -29,6 +31,7 @@ static VOID (WINAPI *pRtlTimeFieldsToTime)( PTIME_FIELDS TimeFields, PLARGE_IN static NTSTATUS (WINAPI *pNtQueryPerformanceCounter)( LARGE_INTEGER *counter, LARGE_INTEGER *frequency ); static NTSTATUS (WINAPI *pRtlQueryTimeZoneInformation)( RTL_TIME_ZONE_INFORMATION *); static NTSTATUS (WINAPI *pRtlQueryDynamicTimeZoneInformation)( RTL_DYNAMIC_TIME_ZONE_INFORMATION *); +static ULONG (WINAPI *pNtGetTickCount)(void);
static const int MonthLengths[2][12] = { @@ -153,12 +156,60 @@ static void test_RtlQueryTimeZoneInformation(void) wine_dbgstr_w(tzinfo.DaylightName)); }
+static ULONG64 read_ksystem_time(volatile KSYSTEM_TIME *time) +{
- ULONG64 high, low;
- do
- {
high = time->High1Time;
low = time->LowPart;
- }
- while (high != time->High2Time);
- return high << 32 | low;
+}
+static void test_NtGetTickCount(void) +{
- KSHARED_USER_DATA *user_shared_data = (void *)0x7ffe0000;
- ULONG64 usd_time;
- ULONG diff;
- int i;
- for (i = 0; i < 5; ++i)
- {
LARGE_INTEGER system_time;
if (user_shared_data->NtMajorVersion <= 5 && user_shared_data->NtMinorVersion <= 1)
usd_time = ((ULONG64)user_shared_data->TickCountLowDeprecated * user_shared_data->TickCountMultiplier) >> 24;
else
usd_time = (read_ksystem_time(&user_shared_data->u.TickCount) * user_shared_data->TickCountMultiplier) >> 24;
if (!pNtGetTickCount)
diff = GetTickCount() - usd_time;
else
diff = pNtGetTickCount() - usd_time;
We already have tests in kernel32 that GetTickCount() and NtGetTickCount() are close, so it seems probably easiest to just test GetTickCount() here.
todo_wine
ok(diff < 100, "NtGetTickCount - USD->TickCount too high, expected < 100 got %d\n", diff);
usd_time = read_ksystem_time(&user_shared_data->SystemTime);
NtQuerySystemTime(&system_time);
diff = system_time.QuadPart - usd_time;
todo_wine
ok(diff < 100, "NtQuerySystemTime - USD->SystemTime too high, expected < 100 got %d\n", diff);
The way it's done in kernel32() is to read from sources A, B, A, then check that A < B < A. Assuming that source A is sane, that lets you avoid any failures due to spurious lag (as is unfortunately often the case with the testbot.)
Sleep(50);
- }
+}
- START_TEST(time) { HMODULE mod = GetModuleHandleA("ntdll.dll"); pRtlTimeToTimeFields = (void *)GetProcAddress(mod,"RtlTimeToTimeFields"); pRtlTimeFieldsToTime = (void *)GetProcAddress(mod,"RtlTimeFieldsToTime"); pNtQueryPerformanceCounter = (void *)GetProcAddress(mod, "NtQueryPerformanceCounter");
- pNtGetTickCount = (void *)GetProcAddress(mod,"NtGetTickCount"); pRtlQueryTimeZoneInformation = (void *)GetProcAddress(mod, "RtlQueryTimeZoneInformation"); pRtlQueryDynamicTimeZoneInformation =
@@ -169,5 +220,6 @@ START_TEST(time) else win_skip("Required time conversion functions are not available\n"); test_NtQueryPerformanceCounter();
- test_NtGetTickCount(); test_RtlQueryTimeZoneInformation(); }