summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Toub <stoub@microsoft.com>2015-12-10 10:45:59 -0500
committerStephen Toub <stoub@microsoft.com>2015-12-10 12:27:51 -0500
commit79b6d5df3dee969ebf89559c90ccc8636783d01b (patch)
treeafe270262b287af9032df2cf232f81336bbafce2
parentcb25307b3022b67cf240ff534f05778845090921 (diff)
downloadcoreclr-79b6d5df3dee969ebf89559c90ccc8636783d01b.tar.gz
coreclr-79b6d5df3dee969ebf89559c90ccc8636783d01b.tar.bz2
coreclr-79b6d5df3dee969ebf89559c90ccc8636783d01b.zip
Use CLOCK_MONOTONIC_COARSE in GetTickCount64
Today, GetTickCount64 is implemented to use clock_gettime with CLOCK_MONOTONIC if it's available. This provides for high-resolution, however it trades off that accuracy for some efficiency. This commit changes it to prefer CLOCK_MONOTONIC_COARSE if it's available (QueryPerformanceCounter still uses CLOCK_MONOTONIC). GetTickCount is typically used for coarse timings, e.g. used in a loop to determine whether more than 10 seconds have passed, and can have lower resolution in exchange for higher efficiency. For Windows, the MSDN docs explicitly state that it's likely to have no better than 10-15 millisecond resolution. Using CLOCK_MONOTONIC_COARSE instead of CLOCK_MONOTIC maps better to this notion, and improves Environment.TickCount throughput on my machine by ~20x. At the same time, on my machine it still provides well better than 10-15ms resolution, closer to ~4ms.
-rw-r--r--src/pal/src/config.h.in1
-rw-r--r--src/pal/src/configure.cmake13
-rw-r--r--src/pal/src/misc/time.cpp12
3 files changed, 23 insertions, 3 deletions
diff --git a/src/pal/src/config.h.in b/src/pal/src/config.h.in
index 143679d5a7..672cfe1d31 100644
--- a/src/pal/src/config.h.in
+++ b/src/pal/src/config.h.in
@@ -82,6 +82,7 @@
#cmakedefine01 HAVE_WORKING_GETTIMEOFDAY
#cmakedefine01 HAVE_WORKING_CLOCK_GETTIME
#cmakedefine01 HAVE_CLOCK_MONOTONIC
+#cmakedefine01 HAVE_CLOCK_MONOTONIC_COARSE
#cmakedefine01 HAVE_MACH_ABSOLUTE_TIME
#cmakedefine01 HAVE_CLOCK_THREAD_CPUTIME
#cmakedefine01 STATVFS64_PROTOTYPE_BROKEN
diff --git a/src/pal/src/configure.cmake b/src/pal/src/configure.cmake
index 333f0094c5..d130e14123 100644
--- a/src/pal/src/configure.cmake
+++ b/src/pal/src/configure.cmake
@@ -343,6 +343,19 @@ int main()
}" HAVE_CLOCK_MONOTONIC)
check_cxx_source_runs("
#include <stdlib.h>
+#include <time.h>
+#include <sys/time.h>
+
+int main()
+{
+ int ret;
+ struct timespec ts;
+ ret = clock_gettime(CLOCK_MONOTONIC_COARSE, &ts);
+
+ exit(ret);
+}" HAVE_CLOCK_MONOTONIC_COARSE)
+check_cxx_source_runs("
+#include <stdlib.h>
#include <mach/mach_time.h>
int main()
diff --git a/src/pal/src/misc/time.cpp b/src/pal/src/misc/time.cpp
index 2f20c60914..939c86996a 100644
--- a/src/pal/src/misc/time.cpp
+++ b/src/pal/src/misc/time.cpp
@@ -337,12 +337,18 @@ GetTickCount64()
{
ULONGLONG retval = 0;
-#if HAVE_CLOCK_MONOTONIC
+#if HAVE_CLOCK_MONOTONIC_COARSE || HAVE_CLOCK_MONOTONIC
{
+ 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(CLOCK_MONOTONIC, &ts) != 0)
+ if (clock_gettime(clockType, &ts) != 0)
{
- ASSERT("clock_gettime(CLOCK_MONOTONIC) failed; errno is %d (%s)\n", errno, strerror(errno));
+ ASSERT("clock_gettime(CLOCK_MONOTONIC*) failed; errno is %d (%s)\n", errno, strerror(errno));
goto EXIT;
}
retval = (ts.tv_sec * tccSecondsToMillieSeconds)+(ts.tv_nsec / tccMillieSecondsToNanoSeconds);