[RFC PATCH v3 1/2] ntdll/tests: Test updating TickCount in user_shared_data.
Zebediah Figura
zfigura at codeweavers.com
Tue Apr 28 11:30:28 CDT 2020
On 4/28/20 10:11 AM, Rémi Bernon wrote:
> Original patch from: Andrew Wesie <awesie at gmail.com>
>
> Signed-off-by: Rémi Bernon <rbernon at 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();
> }
>
More information about the wine-devel
mailing list