From d3675fd611c6ccc224857c79e0c17a4374e63ba5 Mon Sep 17 00:00:00 2001 From: Piotr Caban Date: Wed, 16 Oct 2019 13:20:58 +0200 Subject: [PATCH] msvcrt: Return time since CRT initialization in clock function. Signed-off-by: Piotr Caban Signed-off-by: Alexandre Julliard --- dlls/msvcrt/main.c | 1 + dlls/msvcrt/msvcrt.h | 1 + dlls/msvcrt/tests/time.c | 18 ------------------ dlls/msvcrt/time.c | 25 +++++++++++-------------- dlls/ucrtbase/tests/misc.c | 25 +++++++++++++++++++++++++ 5 files changed, 38 insertions(+), 32 deletions(-) diff --git a/dlls/msvcrt/main.c b/dlls/msvcrt/main.c index 0be8dd36b5f..91496b86fb4 100644 --- a/dlls/msvcrt/main.c +++ b/dlls/msvcrt/main.c @@ -124,6 +124,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) #elif _MSVCR_VER >= 80 MSVCRT__set_printf_count_output(0); #endif + msvcrt_init_clock(); TRACE("finished process init\n"); break; case DLL_THREAD_ATTACH: diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h index 6e0e338a209..4bf26fbe9a3 100644 --- a/dlls/msvcrt/msvcrt.h +++ b/dlls/msvcrt/msvcrt.h @@ -369,6 +369,7 @@ extern void msvcrt_free_signals(void) DECLSPEC_HIDDEN; extern void msvcrt_free_popen_data(void) DECLSPEC_HIDDEN; extern BOOL msvcrt_init_heap(void) DECLSPEC_HIDDEN; extern void msvcrt_destroy_heap(void) DECLSPEC_HIDDEN; +extern void msvcrt_init_clock(void) DECLSPEC_HIDDEN; #if _MSVCR_VER >= 100 extern void msvcrt_init_scheduler(void*) DECLSPEC_HIDDEN; diff --git a/dlls/msvcrt/tests/time.c b/dlls/msvcrt/tests/time.c index beba7963179..0eecfd6796f 100644 --- a/dlls/msvcrt/tests/time.c +++ b/dlls/msvcrt/tests/time.c @@ -918,23 +918,6 @@ static void test__tzset(void) _putenv(TZ_env); } -static void test_clock(void) -{ - static const int THRESH = 100; - FILETIME start, cur; - int c, expect; - BOOL ret; - - ret = GetProcessTimes(GetCurrentProcess(), &start, &cur, &cur, &cur); - ok(ret, "GetProcessTimes failed with error: %d\n", GetLastError()); - GetSystemTimeAsFileTime(&cur); - expect = (((LONGLONG)cur.dwHighDateTime<<32)+cur.dwLowDateTime - - ((LONGLONG)start.dwHighDateTime<<32)-start.dwLowDateTime) / 10000; - - c = clock(); - ok(abs(c-expect) < THRESH, "clock() = %d, expected %d\n", c, expect); -} - START_TEST(time) { init(); @@ -953,5 +936,4 @@ START_TEST(time) test_localtime64_s(); test_daylight(); test_asctime(); - test_clock(); } diff --git a/dlls/msvcrt/time.c b/dlls/msvcrt/time.c index 78f46029720..b299976d3f3 100644 --- a/dlls/msvcrt/time.c +++ b/dlls/msvcrt/time.c @@ -38,6 +38,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcrt); BOOL WINAPI GetDaylightFlag(void); +static LONGLONG init_time; + +void msvcrt_init_clock(void) +{ + LARGE_INTEGER systime; + + NtQuerySystemTime(&systime); + init_time = systime.QuadPart; +} + static const int MonthLengths[2][12] = { { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, @@ -712,23 +722,10 @@ int CDECL _wstrtime_s(MSVCRT_wchar_t* time, MSVCRT_size_t size) */ MSVCRT_clock_t CDECL MSVCRT_clock(void) { - static LONGLONG start_time; LARGE_INTEGER systime; - if(!start_time) { - KERNEL_USER_TIMES pti; - - /* while Linux's clock returns user time, Windows' clock - * returns wall-clock time from process start. cache the - * process start time since it won't change and to avoid - * wineserver round-trip overhead */ - if(NtQueryInformationProcess(GetCurrentProcess(), ProcessTimes, &pti, sizeof(pti), NULL)) - return -1; - start_time = pti.CreateTime.QuadPart; - } - NtQuerySystemTime(&systime); - return (systime.QuadPart - start_time) * MSVCRT_CLOCKS_PER_SEC / TICKSPERSEC; + return (systime.QuadPart - init_time) / (TICKSPERSEC / MSVCRT_CLOCKS_PER_SEC); } /********************************************************************* diff --git a/dlls/ucrtbase/tests/misc.c b/dlls/ucrtbase/tests/misc.c index 9747d8b21ab..fe59e300623 100644 --- a/dlls/ucrtbase/tests/misc.c +++ b/dlls/ucrtbase/tests/misc.c @@ -107,6 +107,7 @@ typedef struct MSVCRT__exception { typedef int (CDECL *MSVCRT_matherr_func)(struct MSVCRT__exception *); static HMODULE module; +static LONGLONG crt_init_start, crt_init_end; static int (CDECL *p_initialize_onexit_table)(MSVCRT__onexit_table_t *table); static int (CDECL *p_register_onexit_function)(MSVCRT__onexit_table_t *table, MSVCRT__onexit_t func); @@ -146,6 +147,7 @@ static int (__cdecl *p__close)(int); static void* (__cdecl *p__o_malloc)(size_t); static size_t (__cdecl *p__msize)(void*); static void (__cdecl *p_free)(void*); +static clock_t (__cdecl *p_clock)(void); static void test__initialize_onexit_table(void) { @@ -465,7 +467,13 @@ static void test__get_narrow_winmain_command_line(char *path) static BOOL init(void) { + FILETIME cur; + + GetSystemTimeAsFileTime(&cur); + crt_init_start = ((LONGLONG)cur.dwHighDateTime << 32) + cur.dwLowDateTime; module = LoadLibraryA("ucrtbase.dll"); + GetSystemTimeAsFileTime(&cur); + crt_init_end = ((LONGLONG)cur.dwHighDateTime << 32) + cur.dwLowDateTime; if(!module) { win_skip("ucrtbase.dll not available\n"); @@ -510,6 +518,7 @@ static BOOL init(void) p__o_malloc = (void*)GetProcAddress(module, "_o_malloc"); p__msize = (void*)GetProcAddress(module, "_msize"); p_free = (void*)GetProcAddress(module, "free"); + p_clock = (void*)GetProcAddress(module, "clock"); return TRUE; } @@ -1166,6 +1175,21 @@ static void test__o_malloc(void) p_free(m); } +static void test_clock(void) +{ + static const int thresh = 100; + int c, expect_min, expect_max; + FILETIME cur; + + GetSystemTimeAsFileTime(&cur); + c = p_clock(); + + expect_min = (((LONGLONG)cur.dwHighDateTime << 32) + cur.dwLowDateTime - crt_init_end) / 10000; + expect_max = (((LONGLONG)cur.dwHighDateTime << 32) + cur.dwLowDateTime - crt_init_start) / 10000; + ok(c > expect_min-thresh && c < expect_max+thresh, "clock() = %d, expected range [%d, %d]\n", + c, expect_min, expect_max); +} + START_TEST(misc) { int arg_c; @@ -1202,4 +1226,5 @@ START_TEST(misc) test_quick_exit(arg_v[0]); test__stat32(); test__o_malloc(); + test_clock(); }