Piotr Caban : msvcrt: Return time since CRT initialization in clock function.

Alexandre Julliard julliard at winehq.org
Wed Oct 16 16:59:29 CDT 2019


Module: wine
Branch: master
Commit: d3675fd611c6ccc224857c79e0c17a4374e63ba5
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=d3675fd611c6ccc224857c79e0c17a4374e63ba5

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Wed Oct 16 13:20:58 2019 +0200

msvcrt: Return time since CRT initialization in clock function.

Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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 0be8dd36b5..91496b86fb 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 6e0e338a20..4bf26fbe9a 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 beba796317..0eecfd6796 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 78f4602972..b299976d3f 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 9747d8b21a..fe59e30062 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();
 }




More information about the wine-cvs mailing list