aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRickard Green <[email protected]>2015-03-24 19:43:08 +0100
committerRickard Green <[email protected]>2015-03-25 14:48:34 +0100
commit139edf3f40fcf746fe21318f03032c091b3c2fc1 (patch)
tree610fd2b83989922ca6e69e1164e58520d41266ed
parentc20482023b70768bd84d25f1e34dbbc2fe09cf31 (diff)
downloadotp-139edf3f40fcf746fe21318f03032c091b3c2fc1.tar.gz
otp-139edf3f40fcf746fe21318f03032c091b3c2fc1.tar.bz2
otp-139edf3f40fcf746fe21318f03032c091b3c2fc1.zip
Fixes and cleanup
-rw-r--r--erts/aclocal.m48
-rw-r--r--erts/emulator/beam/erl_time_sup.c48
-rw-r--r--erts/emulator/sys/unix/erl_unix_sys.h99
-rw-r--r--erts/emulator/sys/unix/sys_time.c491
-rw-r--r--erts/emulator/sys/win32/erl_win_sys.h9
-rw-r--r--erts/emulator/sys/win32/sys_time.c121
6 files changed, 564 insertions, 212 deletions
diff --git a/erts/aclocal.m4 b/erts/aclocal.m4
index 7a969547cf..40ea980209 100644
--- a/erts/aclocal.m4
+++ b/erts/aclocal.m4
@@ -745,9 +745,9 @@ AC_DEFUN(ERL_MONOTONIC_CLOCK,
done
])
- AC_CHECK_FUNCS([clock_getres gethrtime])
+ AC_CHECK_FUNCS([clock_getres clock_get_attributes gethrtime])
- AC_CACHE_CHECK([for mach clock_get_time()], erl_cv_mach_clock_get_time_monotonic,
+ AC_CACHE_CHECK([for mach clock_get_time() with monotonic clock type], erl_cv_mach_clock_get_time_monotonic,
[
AC_TRY_COMPILE([
#include <mach/clock.h>
@@ -854,9 +854,9 @@ AC_DEFUN(ERL_WALL_CLOCK,
done
])
- AC_CHECK_FUNCS([clock_getres gettimeofday])
+ AC_CHECK_FUNCS([clock_getres clock_get_attributes gettimeofday])
- AC_CACHE_CHECK([for mach clock_get_time()], erl_cv_mach_clock_get_time_wall,
+ AC_CACHE_CHECK([for mach clock_get_time() with wall clock type], erl_cv_mach_clock_get_time_wall,
[
AC_TRY_COMPILE([
#include <mach/clock.h>
diff --git a/erts/emulator/beam/erl_time_sup.c b/erts/emulator/beam/erl_time_sup.c
index ef39f4b5f4..8203436c85 100644
--- a/erts/emulator/beam/erl_time_sup.c
+++ b/erts/emulator/beam/erl_time_sup.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1999-2012. All Rights Reserved.
+ * Copyright Ericsson AB 1999-2015. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -139,12 +139,12 @@ struct time_sup_read_only__ {
int os_monotonic_time_locked;
Uint64 os_monotonic_time_resolution;
Uint64 os_monotonic_time_extended;
+#endif
char *os_system_time_func;
char *os_system_time_clock_id;
int os_system_time_locked;
Uint64 os_system_time_resolution;
Uint64 os_system_time_extended;
-#endif
#if !ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT
ErtsMonotonicTime start;
struct {
@@ -287,7 +287,7 @@ get_time_offset(void)
#define ERTS_LONG_TIME_CORRECTION_CHECK ERTS_SEC_TO_MONOTONIC(60)
#define ERTS_SHORT_TIME_CORRECTION_CHECK ERTS_SEC_TO_MONOTONIC(15)
-#define ERTS_TIME_DRIFT_MAX_ADJ_DIFF ERTS_USEC_TO_MONOTONIC(100)
+#define ERTS_TIME_DRIFT_MAX_ADJ_DIFF ERTS_USEC_TO_MONOTONIC(50)
#define ERTS_TIME_DRIFT_MIN_ADJ_DIFF ERTS_USEC_TO_MONOTONIC(5)
static ERTS_INLINE ErtsMonotonicTime
@@ -353,21 +353,21 @@ print_correction(int change,
if (!change)
fprintf(stderr,
- "sdiff = %lld usec : [ec=%lld ppm, dc=%lld ppm] : "
+ "sdiff = %lld usec : [ec=%lld ppm, dc=%lld ppb] : "
"tmo = %lld msec\r\n",
(long long) usec_sdiff,
(long long) (1000000*old_ecorr) / ERTS_TCORR_ERR_UNIT,
- (long long) (1000000*old_dcorr) / ERTS_MONOTONIC_TIME_UNIT,
+ (long long) (1000000000*old_dcorr) / ERTS_MONOTONIC_TIME_UNIT,
(long long) tmo);
else
fprintf(stderr,
- "sdiff = %lld usec : [ec=%lld ppm, dc=%lld ppm] "
- "-> [ec=%lld ppm, dc=%lld ppm] : tmo = %lld msec\r\n",
+ "sdiff = %lld usec : [ec=%lld ppm, dc=%lld ppb] "
+ "-> [ec=%lld ppm, dc=%lld ppb] : tmo = %lld msec\r\n",
(long long) usec_sdiff,
(long long) (1000000*old_ecorr) / ERTS_TCORR_ERR_UNIT,
- (long long) (1000000*old_dcorr) / ERTS_MONOTONIC_TIME_UNIT,
+ (long long) (1000000000*old_dcorr) / ERTS_MONOTONIC_TIME_UNIT,
(long long) (1000000*new_ecorr) / ERTS_TCORR_ERR_UNIT,
- (long long) (1000000*new_dcorr) / ERTS_MONOTONIC_TIME_UNIT,
+ (long long) (1000000000*new_dcorr) / ERTS_MONOTONIC_TIME_UNIT,
(long long) tmo);
}
@@ -412,8 +412,7 @@ check_time_correction(void *unused)
ASSERT(time_sup.inf.c.finalized_offset);
- os_mtime = erts_os_monotonic_time();
- os_stime = erts_os_system_time();
+ erts_os_times(&os_mtime, &os_stime);
cdata = time_sup.inf.c.parmon.cdata;
@@ -556,13 +555,6 @@ check_time_correction(void *unused)
ddp->acc.mon = mtime_acc;
ddp->acc.sys = stime_acc;
- /*
- * If calculated drift adjustment is if off by more than 20%
- * from the average drift we interpret this as a discontinous
- * leap in system time and ignore it. If it actually is a
- * change in drift we will later detect this when the average
- * drift change.
- */
drift_adj_diff = avg_drift_adj - drift_adj;
if (drift_adj_diff < -ERTS_TIME_DRIFT_MAX_ADJ_DIFF
|| ERTS_TIME_DRIFT_MAX_ADJ_DIFF < drift_adj_diff) {
@@ -691,8 +683,7 @@ init_check_time_correction(void *unused)
old_mtime = ddp->intervals[0].time.mon;
old_stime = ddp->intervals[0].time.sys;
- mtime = erts_os_monotonic_time();
- stime = erts_os_system_time();
+ erts_os_times(&mtime, &stime);
mtime_diff = mtime - old_mtime;
stime_diff = stime - old_stime;
@@ -732,8 +723,7 @@ finalize_corrected_time_offset(ErtsSystemTime *stimep)
erts_smp_rwmtx_rlock(&time_sup.inf.c.parmon.rwmtx);
- os_mtime = erts_os_monotonic_time();
- *stimep = erts_os_system_time();
+ erts_os_times(&os_mtime, stimep);
cdata = time_sup.inf.c.parmon.cdata;
@@ -852,6 +842,7 @@ void erts_init_sys_time_sup(void)
= sys_init_time_res.os_monotonic_time_info.resolution;
time_sup.r.o.os_monotonic_time_extended
= sys_init_time_res.os_monotonic_time_info.extended;
+#endif
time_sup.r.o.os_system_time_func
= sys_init_time_res.os_system_time_info.func;
time_sup.r.o.os_system_time_clock_id
@@ -860,7 +851,6 @@ void erts_init_sys_time_sup(void)
= sys_init_time_res.os_system_time_info.locked_use;
time_sup.r.o.os_system_time_resolution
= sys_init_time_res.os_system_time_info.resolution;
-#endif
}
int
@@ -935,9 +925,11 @@ erts_init_time_sup(int time_correction, ErtsTimeWarpMode time_warp_mode)
#endif
- resolution = time_sup.r.o.os_monotonic_time_resolution;
- if (resolution > time_sup.r.o.os_system_time_resolution)
- resolution = time_sup.r.o.os_system_time_resolution;
+ resolution = time_sup.r.o.os_system_time_resolution;
+#ifdef ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT
+ if (resolution > time_sup.r.o.os_monotonic_time_resolution)
+ resolution = time_sup.r.o.os_monotonic_time_resolution;
+#endif
time_sup.r.o.adj.large_diff = erts_time_sup__.r.o.monotonic_time_unit;
time_sup.r.o.adj.large_diff *= 50;
@@ -972,8 +964,8 @@ erts_init_time_sup(int time_correction, ErtsTimeWarpMode time_warp_mode)
ErtsMonotonicCorrectionData *cdatap;
erts_smp_rwmtx_opt_t rwmtx_opts = ERTS_SMP_RWMTX_OPT_DEFAULT_INITER;
ErtsMonotonicTime offset;
- time_sup.inf.c.minit = erts_os_monotonic_time();
- time_sup.inf.c.sinit = erts_os_system_time();
+ erts_os_times(&time_sup.inf.c.minit,
+ &time_sup.inf.c.sinit);
time_sup.r.o.moffset = -1*time_sup.inf.c.minit;
offset = time_sup.inf.c.sinit;
offset -= ERTS_MONOTONIC_TIME_UNIT;
diff --git a/erts/emulator/sys/unix/erl_unix_sys.h b/erts/emulator/sys/unix/erl_unix_sys.h
index 5394e94c8c..c2cd870f80 100644
--- a/erts/emulator/sys/unix/erl_unix_sys.h
+++ b/erts/emulator/sys/unix/erl_unix_sys.h
@@ -171,61 +171,47 @@ typedef long long ErtsSysHrTime;
typedef ErtsMonotonicTime ErtsSystemTime;
-ErtsSystemTime erts_os_system_time(void);
-
#define ERTS_MONOTONIC_TIME_MIN (((ErtsMonotonicTime) 1) << 63)
#define ERTS_MONOTONIC_TIME_MAX (~ERTS_MONOTONIC_TIME_MIN)
/*
- * OS monotonic time
+ * OS monotonic time and OS system time
*/
-/*
- * Most common with os monotonic time using nano second
- * time unit. These defines are modified below if this
- * isn't the case...
- */
-#define ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT 1
-#define ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT (1000*1000*1000)
+#undef ERTS_OS_TIMES_INLINE_FUNC_PTR_CALL__
+
+#if defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME)
+# if defined(__linux__)
+# define ERTS_OS_TIMES_INLINE_FUNC_PTR_CALL__ 1
+# endif
+#endif
+
+ErtsSystemTime erts_os_system_time(void);
+#undef ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT
+#undef ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT
#undef ERTS_OS_MONOTONIC_INLINE_FUNC_PTR_CALL__
#undef ERTS_HAVE_CORRECTED_OS_MONOTONIC
#if defined(OS_MONOTONIC_TIME_USING_CLOCK_GETTIME)
-
-#if defined(__linux__)
-
-#define ERTS_HAVE_CORRECTED_OS_MONOTONIC 1
-#define ERTS_OS_MONOTONIC_INLINE_FUNC_PTR_CALL__ 1
-
-#else /* !defined(__linux__) */
-
-ErtsMonotonicTime erts_os_monotonic_time(void);
-
-#endif /* !defined(__linux__) */
-
+# define ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT 1
+# define ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT (1000*1000*1000)
+# if defined(__linux__)
+# define ERTS_HAVE_CORRECTED_OS_MONOTONIC 1
+# define ERTS_OS_MONOTONIC_INLINE_FUNC_PTR_CALL__ 1
+# endif
+#elif defined(OS_MONOTONIC_TIME_USING_MACH_CLOCK_GET_TIME)
+# define ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT 1
+# define ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT (1000*1000*1000)
#elif defined(OS_MONOTONIC_TIME_USING_GETHRTIME)
-
-#define erts_os_monotonic() ((ErtsMonotonicTime) gethrtime())
-#define erts_sys_hrtime() ((ErtsSysHrTime) gethrtime())
-
-#elif defined(OS_MONOTONIC_TIME_USING_MACH_CLOCK_GET_TIME) \
- || defined(OS_MONOTONIC_TIME_USING_TIMES)
-
-#if defined(OS_MONOTONIC_TIME_USING_TIMES)
+# define ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT 1
+# define ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT (1000*1000*1000)
+#elif defined(OS_MONOTONIC_TIME_USING_TIMES)
+# define ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT 1
/* Time unit determined at runtime... */
-# undef ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT
# define ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT 0
-#endif
-
-ErtsMonotonicTime erts_os_monotonic_time(void);
-
#else /* No OS monotonic available... */
-
-#undef ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT
-#undef ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT
-#define ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT (1000*1000)
-
+# define ERTS_COMPILE_TIME_MONOTONIC_TIME_UNIT (1000*1000)
#endif
/*
@@ -233,14 +219,15 @@ ErtsMonotonicTime erts_os_monotonic_time(void);
* time function found. Time unit is nano-seconds.
* It may or may not be monotonic.
*/
-#ifndef erts_sys_hrtime
-extern ErtsSysHrTime erts_sys_hrtime(void);
-#endif
+ErtsSysHrTime erts_sys_hrtime(void);
struct erts_sys_time_read_only_data__ {
#ifdef ERTS_OS_MONOTONIC_INLINE_FUNC_PTR_CALL__
ErtsMonotonicTime (*os_monotonic_time)(void);
#endif
+#ifdef ERTS_OS_TIMES_INLINE_FUNC_PTR_CALL__
+ void (*os_times)(ErtsMonotonicTime *, ErtsSystemTime *);
+#endif
int ticks_per_sec;
};
@@ -255,21 +242,43 @@ typedef struct {
extern ErtsSysTimeData__ erts_sys_time_data__;
+#ifdef ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT
+
#ifdef ERTS_OS_MONOTONIC_INLINE_FUNC_PTR_CALL__
+ERTS_GLB_INLINE
+#endif
+ErtsMonotonicTime erts_os_monotonic_time(void);
-ERTS_GLB_INLINE ErtsMonotonicTime erts_os_monotonic_time(void);
+#ifdef ERTS_OS_TIMES_INLINE_FUNC_PTR_CALL__
+ERTS_GLB_INLINE
+#endif
+void erts_os_times(ErtsMonotonicTime *, ErtsSystemTime *);
#if ERTS_GLB_INLINE_INCL_FUNC_DEF
+#ifdef ERTS_OS_MONOTONIC_INLINE_FUNC_PTR_CALL__
+
ERTS_GLB_INLINE ErtsMonotonicTime
erts_os_monotonic_time(void)
{
return (*erts_sys_time_data__.r.o.os_monotonic_time)();
}
+#endif /* ERTS_OS_MONOTONIC_INLINE_FUNC_PTR_CALL__ */
+
+#ifdef ERTS_OS_TIMES_INLINE_FUNC_PTR_CALL__
+
+ERTS_GLB_INLINE void
+erts_os_times(ErtsMonotonicTime *mtimep, ErtsSystemTime *stimep)
+{
+ return (*erts_sys_time_data__.r.o.os_times)(mtimep, stimep);
+}
+
+#endif /* ERTS_OS_TIMES_INLINE_FUNC_PTR_CALL__ */
+
#endif /* ERTS_GLB_INLINE_INCL_FUNC_DEF */
-#endif /* ERTS_OS_MONOTONIC_INLINE_FUNC_PTR_CALL__ */
+#endif /* ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT */
/*
*
diff --git a/erts/emulator/sys/unix/sys_time.c b/erts/emulator/sys/unix/sys_time.c
index d6591a8296..e764607c25 100644
--- a/erts/emulator/sys/unix/sys_time.c
+++ b/erts/emulator/sys/unix/sys_time.c
@@ -35,6 +35,20 @@
#include "global.h"
#include "erl_os_monotonic_time_extender.h"
+#undef ERTS_HAVE_ERTS_OS_TIMES_IMPL__
+#undef ERTS_HAVE_ERTS_SYS_HRTIME_IMPL__
+
+#if defined(OS_MONOTONIC_TIME_USING_MACH_CLOCK_GET_TIME) \
+ || defined(OS_SYSTEM_TIME_USING_MACH_CLOCK_GET_TIME)
+# include <mach/clock.h>
+# include <mach/mach.h>
+# ifdef HAVE_CLOCK_GET_ATTRIBUTES
+# define ERTS_HAVE_MACH_CLOCK_GETRES
+static Sint64
+mach_clock_getres(clock_id_t clkid, char *clkid_str);
+# endif
+#endif
+
#ifdef NO_SYSCONF
# define TICKS_PER_SEC() HZ
#else
@@ -87,6 +101,10 @@ ErtsSysTimeData__ erts_sys_time_data__ erts_align_attribute(ERTS_CACHE_LINE_SIZE
static ErtsMonotonicTime clock_gettime_monotonic_raw(void);
static ErtsMonotonicTime clock_gettime_monotonic_verified(void);
+#if defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME)
+static void clock_gettime_times_raw(ErtsMonotonicTime *, ErtsSystemTime *);
+static void clock_gettime_times_verified(ErtsMonotonicTime *, ErtsSystemTime *);
+#endif
#endif /* defined(__linux__) && defined(OS_MONOTONIC_TIME_USING_CLOCK_GETTIME) */
@@ -167,6 +185,9 @@ sys_init_time(ErtsSysInitTimeResult *init_resp)
init_resp->os_monotonic_time_info.resolution = 1;
}
}
+#elif defined(ERTS_HAVE_MACH_CLOCK_GETRES) && defined(MONOTONIC_CLOCK_ID)
+ init_resp->os_monotonic_time_info.resolution
+ = mach_clock_getres(MONOTONIC_CLOCK_ID, MONOTONIC_CLOCK_ID_STR);
#endif
#ifdef MONOTONIC_CLOCK_ID_STR
@@ -197,9 +218,14 @@ sys_init_time(ErtsSysInitTimeResult *init_resp)
#if defined(__linux__) && defined(OS_MONOTONIC_TIME_USING_CLOCK_GETTIME)
- if (vsn >= ERTS_MK_VSN_INT(2, 6, 33))
+ if (vsn >= ERTS_MK_VSN_INT(2, 6, 33)) {
erts_sys_time_data__.r.o.os_monotonic_time =
clock_gettime_monotonic_raw;
+#if defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME)
+ erts_sys_time_data__.r.o.os_times =
+ clock_gettime_times_raw;
+#endif
+ }
else {
/*
* Linux versions prior to 2.6.33 have a
@@ -208,6 +234,10 @@ sys_init_time(ErtsSysInitTimeResult *init_resp)
*/
erts_sys_time_data__.r.o.os_monotonic_time =
clock_gettime_monotonic_verified;
+#if defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME)
+ erts_sys_time_data__.r.o.os_times =
+ clock_gettime_times_verified;
+#endif
erts_smp_mtx_init(&internal_state.w.f.mtx,
"os_monotonic_time");
internal_state.w.f.last_delivered
@@ -292,6 +322,9 @@ sys_init_time(ErtsSysInitTimeResult *init_resp)
init_resp->os_system_time_info.resolution = 1;
}
}
+#elif defined(ERTS_HAVE_MACH_CLOCK_GETRES) && defined(WALL_CLOCK_ID)
+ init_resp->os_system_time_info.resolution
+ = mach_clock_getres(WALL_CLOCK_ID, WALL_CLOCK_ID_STR);
#endif
#if defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME)
@@ -303,7 +336,7 @@ sys_init_time(ErtsSysInitTimeResult *init_resp)
init_resp->os_system_time_info.resolution = 1000*1000;
init_resp->os_system_time_info.clock_id = NULL;
#else
-# error Missing erts_os_system_time() implmenentation
+# error Missing erts_os_system_time() implementation
#endif
}
@@ -333,117 +366,102 @@ adj_stime_time_unit(ErtsSystemTime stime, Uint32 res)
(Uint32) ERTS_MONOTONIC_TIME_UNIT));
}
-#if defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME)
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
+ * POSIX clock_gettime() *
+\* */
-ErtsSystemTime
-erts_os_system_time(void)
+#if defined(OS_MONOTONIC_TIME_USING_CLOCK_GETTIME) \
+ || defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME)
+
+static ERTS_INLINE ErtsMonotonicTime
+timespec2montime(struct timespec *ts)
+{
+ ErtsMonotonicTime time;
+ time = (ErtsMonotonicTime) ts->tv_sec;
+ time *= (ErtsMonotonicTime) 1000*1000*1000;
+ time += (ErtsMonotonicTime) ts->tv_nsec;
+ return time;
+}
+
+static ERTS_INLINE ErtsMonotonicTime
+posix_clock_gettime(clockid_t id, char *name)
{
- ErtsSystemTime stime;
struct timespec ts;
- if (clock_gettime(WALL_CLOCK_ID,&ts) != 0) {
+ if (clock_gettime(id, &ts) != 0) {
int err = errno;
char *errstr = err ? strerror(err) : "unknown";
erl_exit(ERTS_ABORT_EXIT,
"clock_gettime(%s, _) failed: %s (%d)\n",
- WALL_CLOCK_ID_STR, errstr, err);
-
+ name, errstr, err);
}
-
- stime = (ErtsSystemTime) ts.tv_sec;
- stime *= (ErtsSystemTime) 1000*1000*1000;
- stime += (ErtsSystemTime) ts.tv_nsec;
- return adj_stime_time_unit(stime, (Uint32) 1000*1000*1000);
+ return timespec2montime(&ts);
}
-#elif defined(OS_SYSTEM_TIME_USING_MACH_CLOCK_GET_TIME)
+#endif /* defined(OS_MONOTONIC_TIME_USING_CLOCK_GETTIME) \
+ || defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME) */
+
+#if defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME)
ErtsSystemTime
erts_os_system_time(void)
{
ErtsSystemTime stime;
- kern_return_t res;
- clock_serv_t clk_srv;
- mach_timespec_t time_spec;
- int err;
-
- host_get_clock_service(mach_host_self(),
- WALL_CLOCK_ID,
- &clk_srv);
- errno = 0;
- res = clock_get_time(clk_srv, &time_spec);
- err = errno;
- mach_port_deallocate(mach_task_self(), clk_srv);
- if (res != KERN_SUCCESS) {
- char *errstr = err ? strerror(err) : "unknown";
- erl_exit(ERTS_ABORT_EXIT,
- "clock_get_time(%s, _) failed: %s (%d)\n",
- MONOTONIC_CLOCK_ID_STR, errstr, err);
- }
-
- stime = (ErtsSystemTime) time_spec.tv_sec;
- stime *= (ErtsSystemTime) 1000*1000*1000;
- stime += (ErtsSystemTime) time_spec.tv_nsec;
+ stime = (ErtsSystemTime) posix_clock_gettime(WALL_CLOCK_ID,
+ WALL_CLOCK_ID_STR);
+#if defined(OS_MONOTONIC_TIME_USING_CLOCK_GETTIME)
+ return stime;
+#else
return adj_stime_time_unit(stime, (Uint32) 1000*1000*1000);
+#endif
}
-#elif defined(OS_SYSTEM_TIME_GETTIMEOFDAY)
-
-ErtsSystemTime
-erts_os_system_time(void)
-{
- ErtsSystemTime stime;
- struct timeval tv;
-
- if (gettimeofday(&tv, NULL) != 0) {
- int err = errno;
- char *errstr = err ? strerror(err) : "unknown";
- erl_exit(ERTS_ABORT_EXIT,
- "gettimeofday(_, NULL) failed: %s (%d)\n",
- errstr, err);
- }
-
- stime = (ErtsSystemTime) tv.tv_sec;
- stime *= (ErtsSystemTime) 1000*1000;
- stime += (ErtsSystemTime) tv.tv_usec;
+#endif /* defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME) */
- return adj_stime_time_unit(stime, (Uint32) 1000*1000);
-}
+#if defined(OS_MONOTONIC_TIME_USING_CLOCK_GETTIME)
-#else
-# error Missing erts_os_system_time() implmenentation
-#endif
+#if defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME)
-#if defined(OS_MONOTONIC_TIME_USING_CLOCK_GETTIME)
+#define ERTS_HAVE_ERTS_OS_TIMES_IMPL__
-static ERTS_INLINE ErtsMonotonicTime
-clock_gettime_monotonic(void)
+static ERTS_INLINE void
+posix_clock_gettime_times(ErtsMonotonicTime *mtimep,
+ ErtsSystemTime *stimep)
{
- ErtsMonotonicTime mtime;
- struct timespec ts;
+ struct timespec mts, sts;
+ int mres, sres, merr, serr;
- if (clock_gettime(MONOTONIC_CLOCK_ID,&ts) != 0) {
- int err = errno;
- char *errstr = err ? strerror(err) : "unknown";
+ mres = clock_gettime(MONOTONIC_CLOCK_ID, &mts);
+ merr = errno;
+ sres = clock_gettime(WALL_CLOCK_ID, &sts);
+ serr = errno;
+
+ if (mres != 0) {
+ char *errstr = merr ? strerror(merr) : "unknown";
erl_exit(ERTS_ABORT_EXIT,
"clock_gettime(%s, _) failed: %s (%d)\n",
- MONOTONIC_CLOCK_ID_STR, errstr, err);
-
+ MONOTONIC_CLOCK_ID_STR, errstr, merr);
}
- mtime = (ErtsMonotonicTime) ts.tv_sec;
- mtime *= (ErtsMonotonicTime) 1000*1000*1000;
- mtime += (ErtsMonotonicTime) ts.tv_nsec;
- return mtime;
+ if (sres != 0) {
+ char *errstr = serr ? strerror(serr) : "unknown";
+ erl_exit(ERTS_ABORT_EXIT,
+ "clock_gettime(%s, _) failed: %s (%d)\n",
+ WALL_CLOCK_ID_STR, errstr, serr);
+ }
+
+ *mtimep = timespec2montime(&mts);
+ *stimep = (ErtsSystemTime) timespec2montime(&sts);
}
+#endif /* defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME) */
+
#if defined(__linux__)
static ErtsMonotonicTime clock_gettime_monotonic_verified(void)
{
- ErtsMonotonicTime mtime;
-
- mtime = clock_gettime_monotonic();
+ ErtsMonotonicTime mtime = posix_clock_gettime(MONOTONIC_CLOCK_ID,
+ MONOTONIC_CLOCK_ID_STR);
erts_smp_mtx_lock(&internal_state.w.f.mtx);
if (mtime < internal_state.w.f.last_delivered)
@@ -455,66 +473,301 @@ static ErtsMonotonicTime clock_gettime_monotonic_verified(void)
return mtime;
}
+#if defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME)
+
+static void clock_gettime_times_verified(ErtsMonotonicTime *mtimep,
+ ErtsSystemTime *stimep)
+{
+ posix_clock_gettime_times(mtimep, stimep);
+
+ erts_smp_mtx_lock(&internal_state.w.f.mtx);
+ if (*mtimep < internal_state.w.f.last_delivered)
+ *mtimep = internal_state.w.f.last_delivered;
+ else
+ internal_state.w.f.last_delivered = *mtimep;
+ erts_smp_mtx_unlock(&internal_state.w.f.mtx);
+}
+
+#endif /* defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME) */
+
static ErtsMonotonicTime clock_gettime_monotonic_raw(void)
{
- return clock_gettime_monotonic();
+ return posix_clock_gettime(MONOTONIC_CLOCK_ID,
+ MONOTONIC_CLOCK_ID_STR);
}
+#if defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME)
+
+static void clock_gettime_times_raw(ErtsMonotonicTime *mtimep,
+ ErtsSystemTime *stimep)
+{
+ posix_clock_gettime_times(mtimep, stimep);
+}
+
+#endif /* defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME) */
+
#else /* !defined(__linux__) */
ErtsMonotonicTime erts_os_monotonic_time(void)
{
- return clock_gettime_monotonic();
+ return posix_clock_gettime(MONOTONIC_CLOCK_ID,
+ MONOTONIC_CLOCK_ID_STR);
+}
+
+#if defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME)
+
+static void erts_os_times(ErtsMonotonicTime *mtimep,
+ ErtsSystemTime *stimep)
+{
+ posix_clock_gettime_times(mtimep, stimep);
}
+#endif /* defined(OS_SYSTEM_TIME_USING_CLOCK_GETTIME) */
+
#endif /* !defined(__linux__) */
+#define ERTS_HAVE_ERTS_SYS_HRTIME_IMPL__
+
ErtsSysHrTime
erts_sys_hrtime(void)
{
- return (ErtsSysHrTime) clock_gettime_monotonic();
+ return (ErtsSysHrTime) posix_clock_gettime(MONOTONIC_CLOCK_ID,
+ MONOTONIC_CLOCK_ID_STR);
}
-#elif defined(OS_MONOTONIC_TIME_USING_MACH_CLOCK_GET_TIME)
+#endif /* defined(OS_MONOTONIC_TIME_USING_CLOCK_GETTIME) */
-#include <mach/clock.h>
-#include <mach/mach.h>
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
+ * MACH clock_get_time() *
+\* */
-ErtsMonotonicTime erts_os_monotonic_time(void)
+#if defined(OS_MONOTONIC_TIME_USING_MACH_CLOCK_GET_TIME) \
+ || defined(OS_SYSTEM_TIME_USING_MACH_CLOCK_GET_TIME)
+
+#ifdef ERTS_HAVE_MACH_CLOCK_GETRES
+
+static Sint64
+mach_clock_getres(clock_id_t clkid, char *clkid_str)
{
- ErtsMonotonicTime mtime;
- kern_return_t res;
+ mach_port_t task;
+ host_name_port_t host;
+ natural_t attr[1];
+ kern_return_t kret;
+ clock_serv_t clk_srv;
+ mach_msg_type_number_t cnt;
+
+ host = mach_host_self();
+ kret = host_get_clock_service(host, clkid, &clk_srv);
+ if (kret != KERN_SUCCESS) {
+ erl_exit(ERTS_ABORT_EXIT,
+ "host_get_clock_service(_, %s, _) failed\n",
+ clkid_str);
+ }
+
+ cnt = sizeof(attr);
+ kret = clock_get_attributes(clk_srv, CLOCK_GET_TIME_RES, (clock_attr_t) attr, &cnt);
+ if (kret != KERN_SUCCESS) {
+ erl_exit(ERTS_ABORT_EXIT,
+ "clock_get_attributes(%s, _) failed\n",
+ clkid_str);
+ }
+ task = mach_task_self();
+ mach_port_deallocate(task, host);
+ mach_port_deallocate(task, clk_srv);
+
+ return (Sint64) attr[0];
+}
+
+#endif /* ERTS_HAVE_MACH_CLOCK_GETRES */
+
+static ERTS_INLINE Sint64
+mach_clock_gettime(clock_id_t clkid, char *clkid_str)
+{
+ Sint64 time;
+ mach_port_t task;
+ host_name_port_t host;
+ kern_return_t kret;
clock_serv_t clk_srv;
mach_timespec_t time_spec;
- int err;
- host_get_clock_service(mach_host_self(),
- MONOTONIC_CLOCK_ID,
- &clk_srv);
+ host = mach_host_self();
+ kret = host_get_clock_service(host, clkid, &clk_srv);
+ if (kret != KERN_SUCCESS) {
+ erl_exit(ERTS_ABORT_EXIT,
+ "host_get_clock_service(_, %s, _) failed\n",
+ clkid_str);
+ }
errno = 0;
- res = clock_get_time(clk_srv, &time_spec);
- err = errno;
- mach_port_deallocate(mach_task_self(), clk_srv);
- if (res != KERN_SUCCESS) {
- char *errstr = err ? strerror(err) : "unknown";
+ kret = clock_get_time(clk_srv, &time_spec);
+ if (kret != KERN_SUCCESS) {
+ erl_exit(ERTS_ABORT_EXIT,
+ "clock_get_time(%s, _) failed\n",
+ clkid_str);
+ }
+ task = mach_task_self();
+ mach_port_deallocate(task, host);
+ mach_port_deallocate(task, clk_srv);
+
+ time = (Sint64) time_spec.tv_sec;
+ time *= (Sint64) 1000*1000*1000;
+ time += (Sint64) time_spec.tv_nsec;
+ return time;
+}
+
+#endif /* defined(OS_MONOTONIC_TIME_USING_MACH_CLOCK_GET_TIME) \
+ || defined(OS_SYSTEM_TIME_USING_MACH_CLOCK_GET_TIME) */
+
+#if defined(OS_SYSTEM_TIME_USING_MACH_CLOCK_GET_TIME)
+
+#define ERTS_HAVE_ERTS_OS_TIMES_IMPL__
+
+ErtsSystemTime
+erts_os_system_time(void)
+{
+ ErtsSystemTime stime;
+ stime = (ErtsSystemTime) mach_clock_gettime(WALL_CLOCK_ID,
+ WALL_CLOCK_ID_STR);
+#if defined(OS_MONOTONIC_TIME_USING_MACH_CLOCK_GET_TIME)
+ return stime;
+#else
+ return adj_stime_time_unit(stime, (Uint32) 1000*1000*1000);
+#endif
+}
+
+#endif /* defined(OS_SYSTEM_TIME_USING_MACH_CLOCK_GET_TIME) */
+
+#if defined(OS_MONOTONIC_TIME_USING_MACH_CLOCK_GET_TIME)
+
+ErtsMonotonicTime
+erts_os_monotonic_time(void)
+{
+ return (ErtsMonotonicTime) mach_clock_gettime(MONOTONIC_CLOCK_ID,
+ MONOTONIC_CLOCK_ID_STR);
+}
+
+#define ERTS_HAVE_ERTS_SYS_HRTIME_IMPL__
+
+ErtsSysHrTime
+erts_sys_hrtime(void)
+{
+ return (ErtsMonotonicTime) mach_clock_gettime(MONOTONIC_CLOCK_ID,
+ MONOTONIC_CLOCK_ID_STR);
+}
+
+#if defined(OS_SYSTEM_TIME_USING_MACH_CLOCK_GET_TIME)
+
+#define ERTS_HAVE_ERTS_OS_TIMES_IMPL__
+
+void
+erts_os_times(ErtsMonotonicTime *mtimep, ErtsSystemTime *stimep)
+{
+ ErtsMonotonicTime mtime;
+ ErtsSystemTime stime;
+ mach_port_t task;
+ host_name_port_t host;
+ kern_return_t mkret, skret;
+ clock_serv_t mclk_srv, sclk_srv;
+ mach_timespec_t mon_time_spec, sys_time_spec;
+
+ host = mach_host_self();
+ mkret = host_get_clock_service(host, MONOTONIC_CLOCK_ID, &mclk_srv);
+ skret = host_get_clock_service(host, WALL_CLOCK_ID, &sclk_srv);
+ if (mkret != KERN_SUCCESS) {
+ erl_exit(ERTS_ABORT_EXIT,
+ "host_get_clock_service(_, %s, _) failed\n",
+ MONOTONIC_CLOCK_ID);
+ }
+ if (skret != KERN_SUCCESS) {
erl_exit(ERTS_ABORT_EXIT,
- "clock_get_time(%s, _) failed: %s (%d)\n",
- MONOTONIC_CLOCK_ID_STR, errstr, err);
+ "host_get_clock_service(_, %s, _) failed\n",
+ WALL_CLOCK_ID);
}
+ mkret = clock_get_time(mclk_srv, &mon_time_spec);
+ skret = clock_get_time(sclk_srv, &sys_time_spec);
+ if (mkret != KERN_SUCCESS) {
+ erl_exit(ERTS_ABORT_EXIT,
+ "clock_get_time(%s, _) failed\n",
+ MONOTONIC_CLOCK_ID);
+ }
+ if (skret != KERN_SUCCESS) {
+ erl_exit(ERTS_ABORT_EXIT,
+ "clock_get_time(%s, _) failed\n",
+ WALL_CLOCK_ID);
+ }
+ task = mach_task_self();
+ mach_port_deallocate(task, host);
+ mach_port_deallocate(task, mclk_srv);
+ mach_port_deallocate(task, sclk_srv);
- mtime = (ErtsMonotonicTime) time_spec.tv_sec;
+ mtime = (ErtsMonotonicTime) mon_time_spec.tv_sec;
mtime *= (ErtsMonotonicTime) 1000*1000*1000;
- mtime += (ErtsMonotonicTime) time_spec.tv_nsec;
- return mtime;
+ mtime += (ErtsMonotonicTime) mon_time_spec.tv_nsec;
+ stime = (ErtsSystemTime) sys_time_spec.tv_sec;
+ stime *= (ErtsSystemTime) 1000*1000*1000;
+ stime += (ErtsSystemTime) sys_time_spec.tv_nsec;
+ *mtimep = mtime;
+ *stimep = stime;
+}
+
+#endif /* defined(OS_SYSTEM_TIME_USING_MACH_CLOCK_GET_TIME) */
+
+#endif /* defined(OS_MONOTONIC_TIME_USING_MACH_CLOCK_GET_TIME) */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
+ * Solaris gethrtime() - OS monotonic time *
+\* */
+
+#if defined(OS_MONOTONIC_TIME_USING_GETHRTIME)
+
+ErtsMonotonicTime erts_os_monotonic_time(void)
+{
+ return (ErtsMonotonicTime) gethrtime();
}
+#define ERTS_HAVE_ERTS_SYS_HRTIME_IMPL__
+
ErtsSysHrTime
erts_sys_hrtime(void)
{
- return (ErtsSysHrTime) erts_os_monotonic_time();
+ return (ErtsSysHrTime) gethrtime();
}
-#elif defined(OS_MONOTONIC_TIME_USING_TIMES)
+#endif /* defined(OS_MONOTONIC_TIME_USING_GETHRTIME) */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
+ * gettimeofday() - OS system time *
+\* */
+
+#if defined(OS_SYSTEM_TIME_GETTIMEOFDAY)
+
+ErtsSystemTime
+erts_os_system_time(void)
+{
+ ErtsSystemTime stime;
+ struct timeval tv;
+
+ if (gettimeofday(&tv, NULL) != 0) {
+ int err = errno;
+ char *errstr = err ? strerror(err) : "unknown";
+ erl_exit(ERTS_ABORT_EXIT,
+ "gettimeofday(_, NULL) failed: %s (%d)\n",
+ errstr, err);
+ }
+
+ stime = (ErtsSystemTime) tv.tv_sec;
+ stime *= (ErtsSystemTime) 1000*1000;
+ stime += (ErtsSystemTime) tv.tv_usec;
+
+ return adj_stime_time_unit(stime, (Uint32) 1000*1000);
+}
+
+#endif /* defined(OS_SYSTEM_TIME_GETTIMEOFDAY) */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
+ * times() - OS monotonic time *
+\* */
+
+#if defined(OS_MONOTONIC_TIME_USING_TIMES)
ErtsMonotonicTime
erts_os_monotonic_time(void)
@@ -526,29 +779,35 @@ erts_os_monotonic_time(void)
ticks) << internal_state.r.o.times_shift;
}
-# define ERTS_NEED_ERTS_SYS_HRTIME_FALLBACK
-
-#else /* !defined(OS_MONOTONIC_TIME_USING_TIMES) */
-/* No os-monotonic-time */
-# define ERTS_NEED_ERTS_SYS_HRTIME_FALLBACK
#endif
-#ifdef ERTS_NEED_ERTS_SYS_HRTIME_FALLBACK
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
+ * Fallbacks *
+\* */
+
+#ifndef ERTS_HAVE_ERTS_SYS_HRTIME_IMPL__
ErtsSysHrTime
erts_sys_hrtime(void)
{
- ErtsSysHrTime time;
- struct timeval tv;
- gettimeofday(&tv);
- time = (ErtsSysHrTime) tv.tv_sec;
- time *= (ErtsSysHrTime) 1000*1000*1000;
- time += ((ErtsSysHrTime) tv.tv_usec)*1000;
- return time;
+ return (ErtsSysHrTime) erts_os_system_time();
+}
+
+#endif
+
+#if !defined(ERTS_HAVE_ERTS_OS_TIMES_IMPL__) \
+ && defined(ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT)
+
+void
+erts_os_times(ErtsMonotonicTime *mtimep, ErtsSystemTime *stimep)
+{
+ *mtimep = erts_os_monotonic_time();
+ *stimep = erts_os_system_time();
}
#endif
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifdef HAVE_GETHRVTIME_PROCFS_IOCTL
diff --git a/erts/emulator/sys/win32/erl_win_sys.h b/erts/emulator/sys/win32/erl_win_sys.h
index d214ba002c..7c3f35c2f2 100644
--- a/erts/emulator/sys/win32/erl_win_sys.h
+++ b/erts/emulator/sys/win32/erl_win_sys.h
@@ -193,6 +193,7 @@ ErtsSystemTime erts_os_system_time(void);
struct erts_sys_time_read_only_data__ {
ErtsMonotonicTime (*os_monotonic_time)(void);
+ void (*os_times)(ErtsMonotonicTime *, ErtsSystemTime*);
ErtsSysHrTime (*sys_hrtime)(void);
};
@@ -208,6 +209,8 @@ typedef struct {
extern ErtsSysTimeData__ erts_sys_time_data__;
ERTS_GLB_INLINE ErtsMonotonicTime erts_os_monotonic_time(void);
+ERTS_GLB_INLINE void erts_os_times(ErtsMonotonicTime *,
+ ErtsSystemTime *);
ERTS_GLB_INLINE ErtsSysHrTime erts_sys_hrtime(void);
#if ERTS_GLB_INLINE_INCL_FUNC_DEF
@@ -218,6 +221,12 @@ erts_os_monotonic_time(void)
return (*erts_sys_time_data__.r.o.os_monotonic_time)();
}
+ERTS_GLB_INLINE void
+erts_os_times(ErtsMonotonicTime *mtimep, ErtsSystemTime *stimep)
+{
+ return (*erts_sys_time_data__.r.o.os_times)(mtimep, stimep);
+}
+
ERTS_GLB_INLINE ErtsSysHrTime
erts_sys_hrtime(void)
{
diff --git a/erts/emulator/sys/win32/sys_time.c b/erts/emulator/sys/win32/sys_time.c
index da9c4d2e29..7fe61084ce 100644
--- a/erts/emulator/sys/win32/sys_time.c
+++ b/erts/emulator/sys/win32/sys_time.c
@@ -119,6 +119,24 @@ __declspec(align(ASSUMED_CACHE_LINE_SIZE)) struct {
__declspec(align(ASSUMED_CACHE_LINE_SIZE)) ErtsSysTimeData__ erts_sys_time_data__;
+
+static ERTS_INLINE ErtsSystemTime
+SystemTime2MilliSec(SYSTEMTIME *stp)
+{
+ ErtsSystemTime stime;
+ FILETIME ft;
+ ULARGE_INTEGER ull;
+
+ SystemTimeToFileTime(stp, &ft);
+ FILETIME_TO_ULI(ull,ft);
+ /* now in 100 ns units */
+ stime = (ErtsSystemTime) ull.QuadPart;
+ stime -= (((ErtsSystemTime) EPOCH_JULIAN_DIFF)
+ * ((ErtsSystemTime) (10*1000*1000)));
+ stime /= (ErtsSystemTime) (10*1000); /* ms */
+ return stime;
+}
+
static ErtsMonotonicTime
os_monotonic_time_qpc(void)
{
@@ -130,6 +148,30 @@ os_monotonic_time_qpc(void)
return (ErtsMonotonicTime) pc.QuadPart;
}
+static void
+os_times_qpc(ErtsMonotonicTime *mtimep, ErtsSystemTime *stimep)
+{
+ LARGE_INTEGER pc;
+ SYSTEMTIME st;
+ ErtsSystemTime stime;
+ BOOL qpcr;
+
+ qpcr = (*internal_state.r.o.pQueryPerformanceCounter)(&pc);
+ GetSystemTime(&st);
+
+ if (!qpcr)
+ erl_exit(ERTS_ABORT_EXIT, "QueryPerformanceCounter() failed\n");
+
+ *mtimep = (ErtsMonotonicTime) pc.QuadPart;
+
+ stime = SystemTime2MilliSec(&st);
+
+ *stimep = ((ErtsSystemTime)
+ erts_time_unit_conversion((Uint64) stime,
+ (Uint32) 1000,
+ internal_state.r.o.pcf));
+}
+
static Uint32
get_tick_count(void)
{
@@ -139,18 +181,64 @@ get_tick_count(void)
static ErtsMonotonicTime
os_monotonic_time_gtc32(void)
{
+ ErtsMonotonicTime mtime;
Uint32 ticks = (Uint32) GetTickCount();
ERTS_CHK_EXTEND_OS_MONOTONIC_TIME(&internal_state.wr.m.os_mtime_xtnd,
- tick_count);
- return ERTS_EXTEND_OS_MONOTONIC_TIME(&internal_state.wr.m.os_mtime_xtnd,
- ticks) << 10;
+ ticks);
+ mtime = ERTS_EXTEND_OS_MONOTONIC_TIME(&internal_state.wr.m.os_mtime_xtnd,
+ ticks);
+ mtime <<= ERTS_GET_TICK_COUNT_TIME_UNIT_SHIFT;
+ return mtime;
+}
+
+static void
+os_times_gtc32(ErtsMonotonicTime *mtimep, ErtsSystemTime *stimep)
+{
+ SYSTEMTIME st;
+ ErtsSystemTime stime, mtime;
+ Uint32 ticks;
+
+ ticks = (Uint32) GetTickCount();
+ GetSystemTime(&st);
+
+ ERTS_CHK_EXTEND_OS_MONOTONIC_TIME(&internal_state.wr.m.os_mtime_xtnd,
+ ticks);
+ mtime = ERTS_EXTEND_OS_MONOTONIC_TIME(&internal_state.wr.m.os_mtime_xtnd,
+ ticks);
+ mtime <<= ERTS_GET_TICK_COUNT_TIME_UNIT_SHIFT;
+ *mtimep = mtime;
+
+ stime = SystemTime2MilliSec(&st);
+ stime <<= ERTS_GET_TICK_COUNT_TIME_UNIT_SHIFT;
+ *stimep = stime;
+
}
static ErtsMonotonicTime
os_monotonic_time_gtc64(void)
{
ULONGLONG ticks = (*internal_state.r.o.pGetTickCount64)();
- return (ErtsMonotonicTime) ticks << 10;
+ ErtsMonotonicTime mtime = (ErtsMonotonicTime) ticks;
+ return mtime << ERTS_GET_TICK_COUNT_TIME_UNIT_SHIFT;
+}
+
+static void
+os_times_gtc64(ErtsMonotonicTime *mtimep, ErtsSystemTime *stimep)
+{
+ SYSTEMTIME st;
+ ErtsSystemTime stime, mtime;
+ ULONGLONG ticks;
+
+ ticks = (*internal_state.r.o.pGetTickCount64)();
+ GetSystemTime(&st);
+
+ mtime = (ErtsMonotonicTime) ticks;
+ mtime <<= ERTS_GET_TICK_COUNT_TIME_UNIT_SHIFT;
+ *mtimep = mtime;
+
+ stime = SystemTime2MilliSec(&st);
+ stime <<= ERTS_GET_TICK_COUNT_TIME_UNIT_SHIFT;
+ *stimep = stime;
}
static ErtsSysHrTime
@@ -197,6 +285,7 @@ void
sys_init_time(ErtsSysInitTimeResult *init_resp)
{
ErtsMonotonicTime (*os_mtime_func)(void);
+ void (*os_times_func)(ErtsMonotonicTime *, ErtsSystemTime *);
ErtsSysHrTime (*sys_hrtime_func)(void) = NULL;
ErtsMonotonicTime time_unit;
char kernel_dll_name[] = "kernel32";
@@ -220,6 +309,7 @@ sys_init_time(ErtsSysInitTimeResult *init_resp)
time_unit <<= ERTS_GET_TICK_COUNT_TIME_UNIT_SHIFT;
internal_state.r.o.using_get_tick_count_time_unit = 1;
os_mtime_func = os_monotonic_time_gtc32;
+ os_times_func = os_times_gtc32;
init_resp->os_monotonic_time_info.extended = 1;
erts_init_os_monotonic_time_extender(&internal_state.wr.m.os_mtime_xtnd,
get_tick_count,
@@ -250,6 +340,7 @@ sys_init_time(ErtsSysInitTimeResult *init_resp)
time_unit <<= ERTS_GET_TICK_COUNT_TIME_UNIT_SHIFT;
internal_state.r.o.using_get_tick_count_time_unit = 1;
os_mtime_func = os_monotonic_time_gtc64;
+ os_times_func = os_times_gtc64;
if (!sys_hrtime_func)
sys_hrtime_func = sys_hrtime_gtc64;
}
@@ -292,10 +383,12 @@ sys_init_time(ErtsSysInitTimeResult *init_resp)
internal_state.r.o.using_get_tick_count_time_unit = 0;
init_resp->os_monotonic_time_info.resolution = time_unit;
os_mtime_func = os_monotonic_time_qpc;
+ os_times_func = os_times_qpc;
}
}
erts_sys_time_data__.r.o.os_monotonic_time = os_mtime_func;
+ erts_sys_time_data__.r.o.os_times = os_times_func;
init_resp->os_monotonic_time_unit = time_unit;
init_resp->have_os_monotonic_time = 1;
init_resp->sys_clock_resolution = 1;
@@ -600,21 +693,11 @@ sys_gettimeofday(SysTimeval *tv)
ErtsSystemTime
erts_os_system_time(void)
{
- SYSTEMTIME t;
- FILETIME ft;
- ULARGE_INTEGER ull;
+ SYSTEMTIME st;
ErtsSystemTime stime;
- GetSystemTime(&t);
- SystemTimeToFileTime(&t, &ft);
- FILETIME_TO_ULI(ull,ft);
-
- /* now in 100 ns units */
-
- stime = (ErtsSystemTime) ull.QuadPart;
- stime -= (((ErtsSystemTime) EPOCH_JULIAN_DIFF)
- * ((ErtsSystemTime) (10*1000*1000)));
- stime /= (ErtsSystemTime) (10*1000);
+ GetSystemTime(&st);
+ stime = SystemTime2MilliSec(&st);
if (internal_state.r.o.using_get_tick_count_time_unit) {
stime <<= ERTS_GET_TICK_COUNT_TIME_UNIT_SHIFT;
@@ -622,9 +705,9 @@ erts_os_system_time(void)
}
return ((ErtsSystemTime)
- erts_time_unit_conversion(stime,
+ erts_time_unit_conversion((Uint64) stime,
(Uint32) 1000,
- (Uint32) ERTS_MONOTONIC_TIME_UNIT));
+ internal_state.r.o.pcf));
}