msvcrt: Return time since CRT initialization in clock function.

Signed-off-by: Piotr Caban <piotr@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Piotr Caban 2019-10-16 13:20:58 +02:00 committed by Alexandre Julliard
parent 19984fad7a
commit d3675fd611
5 changed files with 38 additions and 32 deletions

View file

@ -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:

View file

@ -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;

View file

@ -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();
}

View file

@ -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);
}
/*********************************************************************

View file

@ -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();
}