Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexis Christoforides <alexis@thenull.net>2018-04-24 19:00:06 +0300
committerGitHub <noreply@github.com>2018-04-24 19:00:06 +0300
commita5b924fa68ab4291fe021a460e7beb657c30641e (patch)
tree62794dd67c3f2a91315999b71943f7b3f201529a
parent34396522f380d07be76c02e43d53b6decb9f5e22 (diff)
parentdd6e11936be663b86e916499663541684fabe81e (diff)
Merge pull request #8412 from mono/backport-new-boottime-2017-12
Backport new mono_msec_boottime() to 2017-12
-rw-r--r--configure.ac27
-rw-r--r--mono/utils/mono-time.c83
2 files changed, 102 insertions, 8 deletions
diff --git a/configure.ac b/configure.ac
index ce90cf046f8..fff663b84ac 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1545,6 +1545,33 @@ if test x$platform_android = xyes; then
fi
if test x$host_win32 = xno; then
+ dnl *************************************
+ dnl *** Checks for time capabilities ***
+ dnl *************************************
+
+ AC_MSG_CHECKING(for CLOCK_MONOTONIC)
+ AC_TRY_COMPILE([#include <time.h>], [
+ const int foo = CLOCK_MONOTONIC;
+ ],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_CLOCK_MONOTONIC, 1, [CLOCK_MONOTONIC])
+ ], [
+ AC_MSG_RESULT(no)
+ ])
+
+ AC_MSG_CHECKING(for CLOCK_MONOTONIC_COARSE)
+ AC_TRY_COMPILE([#include <time.h>], [
+ const int foo = CLOCK_MONOTONIC_COARSE;
+ ],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_CLOCK_MONOTONIC_COARSE, 1, [CLOCK_MONOTONIC_COARSE])
+ ], [
+ AC_MSG_RESULT(no)
+ ])
+
+ AC_CHECK_FUNC(mach_absolute_time, [AC_DEFINE(HAVE_MACH_ABSOLUTE_TIME, 1, [mach_absolute_time])])
+ AC_CHECK_FUNC(gethrtime, [AC_DEFINE(HAVE_GETHRTIME, 1, [gethrtime])])
+ AC_CHECK_FUNC(read_real_time, [AC_DEFINE(HAVE_READ_REAL_TIME, 1, [read_real_time])])
dnl hires monotonic clock support
AC_SEARCH_LIBS(clock_gettime, rt)
diff --git a/mono/utils/mono-time.c b/mono/utils/mono-time.c
index 4a3b2705563..a3c6151a08b 100644
--- a/mono/utils/mono-time.c
+++ b/mono/utils/mono-time.c
@@ -9,16 +9,34 @@
#include <config.h>
#include <stdlib.h>
#include <stdio.h>
+#include <errno.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
-#include <utils/mono-time.h>
+#include <mono/utils/mono-time.h>
+#include <mono/utils/atomic.h>
+#if HAVE_MACH_ABSOLUTE_TIME
+#include <mach/mach_time.h>
+static mach_timebase_info_data_t s_TimebaseInfo;
+#endif
#define MTICKS_PER_SEC (10 * 1000 * 1000)
+typedef enum _TimeConversionConstants
+{
+ tccSecondsToMillieSeconds = 1000, // 10^3
+ tccSecondsToMicroSeconds = 1000000, // 10^6
+ tccSecondsToNanoSeconds = 1000000000, // 10^9
+ tccMillieSecondsToMicroSeconds = 1000, // 10^3
+ tccMillieSecondsToNanoSeconds = 1000000, // 10^6
+ tccMicroSecondsToNanoSeconds = 1000, // 10^3
+ tccSecondsTo100NanoSeconds = 10000000, // 10^7
+ tccMicroSecondsTo100NanoSeconds = 10 // 10^1
+} TimeConversionConstants;
+
gint64
mono_msec_ticks (void)
{
@@ -126,16 +144,65 @@ get_boot_time (void)
}
/* Returns the number of milliseconds from boot time: this should be monotonic */
+/* Adapted from CoreCLR: https://github.com/dotnet/coreclr/blob/66d2738ea96fcce753dec1370e79a0c78f7b6adb/src/pal/src/misc/time.cpp */
gint64
mono_msec_boottime (void)
{
- static gint64 boot_time = 0;
- gint64 now;
- if (!boot_time)
- boot_time = get_boot_time ();
- now = mono_100ns_datetime ();
- /*printf ("now: %llu (boot: %llu) ticks: %llu\n", (gint64)now, (gint64)boot_time, (gint64)(now - boot_time));*/
- return (now - boot_time)/10000;
+ gint64 retval = 0;
+
+ /* clock_gettime () is found by configure on Apple builds, but its only present from ios 10, macos 10.12, tvos 10 and watchos 3 */
+#if (defined(HAVE_CLOCK_MONOTONIC_COARSE) || defined(HAVE_CLOCK_MONOTONIC)) && !(defined(TARGET_IOS) || defined(TARGET_OSX) || defined(TARGET_WATCHOS) || defined(TARGET_TVOS))
+ clockid_t clockType =
+#if HAVE_CLOCK_MONOTONIC_COARSE
+ CLOCK_MONOTONIC_COARSE; /* good enough resolution, fastest speed */
+#else
+ CLOCK_MONOTONIC;
+#endif
+ struct timespec ts;
+ if (clock_gettime (clockType, &ts) != 0) {
+ g_error ("clock_gettime(CLOCK_MONOTONIC*) failed; errno is %d", errno, strerror (errno));
+ goto exit;
+ }
+ retval = (ts.tv_sec * tccSecondsToMillieSeconds) + (ts.tv_nsec / tccMillieSecondsToNanoSeconds);
+
+#elif HAVE_MACH_ABSOLUTE_TIME
+ static gboolean timebase_inited;
+
+ if (!timebase_inited) {
+ kern_return_t machRet;
+ mach_timebase_info_data_t tmp;
+ machRet = mach_timebase_info (&tmp);
+ g_assert (machRet == KERN_SUCCESS);
+ /* Assume memcpy works correctly if ran concurrently */
+ memcpy (&s_TimebaseInfo, &tmp, sizeof (mach_timebase_info_data_t));
+ mono_memory_barrier ();
+ timebase_inited = TRUE;
+ }
+ retval = (mach_absolute_time () * s_TimebaseInfo.numer / s_TimebaseInfo.denom) / tccMillieSecondsToNanoSeconds;
+
+#elif HAVE_GETHRTIME
+ retval = (gint64)(gethrtime () / tccMillieSecondsToNanoSeconds);
+
+#elif HAVE_READ_REAL_TIME
+ timebasestruct_t tb;
+ read_real_time (&tb, TIMEBASE_SZ);
+ if (time_base_to_time (&tb, TIMEBASE_SZ) != 0) {
+ g_error ("time_base_to_time() failed; errno is %d (%s)", errno, strerror (errno));
+ goto exit;
+ }
+ retval = (tb.tb_high * tccSecondsToMillieSeconds) + (tb.tb_low / tccMillieSecondsToNanoSeconds);
+
+#else
+ struct timeval tv;
+ if (gettimeofday (&tv, NULL) == -1) {
+ g_error ("gettimeofday() failed; errno is %d (%s)", errno, strerror (errno));
+ goto exit;
+ }
+ retval = (tv.tv_sec * tccSecondsToMillieSeconds) + (tv.tv_usec / tccMillieSecondsToMicroSeconds);
+
+#endif /* HAVE_CLOCK_MONOTONIC */
+exit:
+ return retval;
}
/* Returns the number of 100ns ticks from unspecified time: this should be monotonic */