From 03d418dcd339c8878186fcc8e165b62289d3d17c Mon Sep 17 00:00:00 2001 From: Patrik Nyblom Date: Tue, 5 Mar 2013 11:48:47 +0100 Subject: Tmp --- erts/emulator/sys/win32/sys_time.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'erts') diff --git a/erts/emulator/sys/win32/sys_time.c b/erts/emulator/sys/win32/sys_time.c index 2f2dfc8197..8775b6a24d 100644 --- a/erts/emulator/sys/win32/sys_time.c +++ b/erts/emulator/sys/win32/sys_time.c @@ -63,6 +63,7 @@ static SysHrTime wrap = 0; static DWORD last_tick_count = 0; +static erts_smp_spinlock_t wrap_lock; /* Getting timezone information is a heavy operation, so we want to do this only once */ @@ -82,6 +83,7 @@ sys_init_time(void) static_tzi.DaylightDate.wMonth != 0) { have_static_tzi = 1; } + erts_smp_spinlock_init(&wrap_lock, "sys_gethrtime"); return 1; } @@ -367,11 +369,15 @@ SysHrTime sys_gethrtime(void) { DWORD ticks = (SysHrTime) (GetTickCount() & 0x7FFFFFFF); + SysHrTime res; + erts_smp_spin_lock(&wrap_lock); if (ticks < (SysHrTime) last_tick_count) { wrap += LL_LITERAL(1) << 31; } last_tick_count = ticks; - return ((((LONGLONG) ticks) + wrap) * LL_LITERAL(1000000)); + res = ((((LONGLONG) ticks) + wrap) * LL_LITERAL(1000000)); + erts_smp_spin_unlock(&wrap_lock); + return res } clock_t -- cgit v1.2.3 From be0da3e4417176421c24a226765eb07752f8635c Mon Sep 17 00:00:00 2001 From: Patrik Nyblom Date: Mon, 11 Mar 2013 15:27:26 +0100 Subject: Intermediate code with lock on gettickcount() --- erts/emulator/beam/erl_lock_check.c | 5 +++ erts/emulator/sys/win32/sys_time.c | 62 ++++++++++++++++++++++++++++++------- 2 files changed, 56 insertions(+), 11 deletions(-) (limited to 'erts') diff --git a/erts/emulator/beam/erl_lock_check.c b/erts/emulator/beam/erl_lock_check.c index 69bb4be717..c85c079e73 100644 --- a/erts/emulator/beam/erl_lock_check.c +++ b/erts/emulator/beam/erl_lock_check.c @@ -181,6 +181,11 @@ static erts_lc_lock_order_t erts_lock_order[] = { { "efile_drv dtrace mutex", NULL }, #endif { "mtrace_buf", NULL }, +#ifdef __WIN32__ +#ifdef ERTS_SMP + { "sys_gethrtime", NULL }, +#endif +#endif { "erts_alloc_hard_debug", NULL } }; diff --git a/erts/emulator/sys/win32/sys_time.c b/erts/emulator/sys/win32/sys_time.c index 8775b6a24d..1a33061ef1 100644 --- a/erts/emulator/sys/win32/sys_time.c +++ b/erts/emulator/sys/win32/sys_time.c @@ -63,7 +63,8 @@ static SysHrTime wrap = 0; static DWORD last_tick_count = 0; -static erts_smp_spinlock_t wrap_lock; +static erts_smp_mtx_t wrap_lock; +static ULONGLONG (WINAPI *pGetTickCount64)(void) = NULL; /* Getting timezone information is a heavy operation, so we want to do this only once */ @@ -78,12 +79,31 @@ static int days_in_month[2][13] = { int sys_init_time(void) { + /* + char kernel_dll_name[] = "kernel32"; + HMODULE module; + + module = GetModuleHandle(kernel_dll_name); + pGetTickCount64 = (module != NULL) ? + (ULONGLONG (WINAPI *)(void)) + GetProcAddress(module,"GetTickCount64") : + NULL; + */ if(GetTimeZoneInformation(&static_tzi) && static_tzi.StandardDate.wMonth != 0 && static_tzi.DaylightDate.wMonth != 0) { have_static_tzi = 1; } - erts_smp_spinlock_init(&wrap_lock, "sys_gethrtime"); + + erts_smp_mtx_init(&wrap_lock, "sys_gethrtime"); + /* + * XXX: Debug - remove me! + */ + if (pGetTickCount64 != NULL) { + fprintf(stderr,"got GetTickCount64!\r\n"); + fflush(stderr); + } + return 1; } @@ -365,19 +385,39 @@ sys_gettimeofday(SysTimeval *tv) EPOCH_JULIAN_DIFF); } +extern int erts_initialized; SysHrTime sys_gethrtime(void) { - DWORD ticks = (SysHrTime) (GetTickCount() & 0x7FFFFFFF); - SysHrTime res; - erts_smp_spin_lock(&wrap_lock); - if (ticks < (SysHrTime) last_tick_count) { - wrap += LL_LITERAL(1) << 31; + if (pGetTickCount64 != NULL) { + return ((SysHrTime) pGetTickCount64()) * LL_LITERAL(1000000); + } else { + DWORD ticks; + SysHrTime res; + erts_smp_mtx_lock(&wrap_lock); + ticks = (SysHrTime) (GetTickCount() & 0x7FFFFFFF); + if (ticks < (SysHrTime) last_tick_count) { + /* Detect a race that should no longer be here... */ + if ((((SysHrTime) last_tick_count) - ((SysHrTime) ticks)) > 1000) { + wrap += LL_LITERAL(1) << 31; + } else { + /* + * XXX Debug: Violates locking order, remove all this, + * after testing! + */ + erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf(); + erts_dsprintf(dsbufp, "Did not wrap when last_tick %d " + "and tick %d", + last_tick_count, ticks); + erts_send_error_to_logger_nogl(dsbufp); + ticks = last_tick_count; + } + } + last_tick_count = ticks; + res = ((((LONGLONG) ticks) + wrap) * LL_LITERAL(1000000)); + erts_smp_mtx_unlock(&wrap_lock); + return res; } - last_tick_count = ticks; - res = ((((LONGLONG) ticks) + wrap) * LL_LITERAL(1000000)); - erts_smp_spin_unlock(&wrap_lock); - return res } clock_t -- cgit v1.2.3 From ab22a60d4e8d7a433789bae44b53305ad0d44cdc Mon Sep 17 00:00:00 2001 From: Patrik Nyblom Date: Thu, 2 May 2013 17:18:22 +0200 Subject: Enable use of GetTickCoun64 when available --- erts/emulator/sys/win32/sys_time.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'erts') diff --git a/erts/emulator/sys/win32/sys_time.c b/erts/emulator/sys/win32/sys_time.c index 1a33061ef1..f7f0161b58 100644 --- a/erts/emulator/sys/win32/sys_time.c +++ b/erts/emulator/sys/win32/sys_time.c @@ -79,7 +79,6 @@ static int days_in_month[2][13] = { int sys_init_time(void) { - /* char kernel_dll_name[] = "kernel32"; HMODULE module; @@ -88,7 +87,7 @@ sys_init_time(void) (ULONGLONG (WINAPI *)(void)) GetProcAddress(module,"GetTickCount64") : NULL; - */ + if(GetTimeZoneInformation(&static_tzi) && static_tzi.StandardDate.wMonth != 0 && static_tzi.DaylightDate.wMonth != 0) { @@ -96,13 +95,6 @@ sys_init_time(void) } erts_smp_mtx_init(&wrap_lock, "sys_gethrtime"); - /* - * XXX: Debug - remove me! - */ - if (pGetTickCount64 != NULL) { - fprintf(stderr,"got GetTickCount64!\r\n"); - fflush(stderr); - } return 1; } -- cgit v1.2.3