comparison src/os/bsd/vm/os_bsd.cpp @ 17924:917873d2983d

8040140: System.nanoTime() is slow and non-monotonic on OS X Reviewed-by: sspitsyn, shade, dholmes, acorn
author sla
date Fri, 25 Apr 2014 07:40:33 +0200
parents 6048424d3865
children 78bbf4d43a14
comparison
equal deleted inserted replaced
17923:a062c3691003 17924:917873d2983d
125 #define LARGEPAGES_BIT (1 << 6) 125 #define LARGEPAGES_BIT (1 << 6)
126 //////////////////////////////////////////////////////////////////////////////// 126 ////////////////////////////////////////////////////////////////////////////////
127 // global variables 127 // global variables
128 julong os::Bsd::_physical_memory = 0; 128 julong os::Bsd::_physical_memory = 0;
129 129
130 130 #ifdef __APPLE__
131 mach_timebase_info_data_t os::Bsd::_timebase_info = {0, 0};
132 volatile uint64_t os::Bsd::_max_abstime = 0;
133 #else
131 int (*os::Bsd::_clock_gettime)(clockid_t, struct timespec *) = NULL; 134 int (*os::Bsd::_clock_gettime)(clockid_t, struct timespec *) = NULL;
135 #endif
132 pthread_t os::Bsd::_main_thread; 136 pthread_t os::Bsd::_main_thread;
133 int os::Bsd::_page_size = -1; 137 int os::Bsd::_page_size = -1;
134 138
135 static jlong initial_time_count=0; 139 static jlong initial_time_count=0;
136 140
984 int status = gettimeofday(&time, NULL); 988 int status = gettimeofday(&time, NULL);
985 assert(status != -1, "bsd error"); 989 assert(status != -1, "bsd error");
986 return jlong(time.tv_sec) * 1000 + jlong(time.tv_usec / 1000); 990 return jlong(time.tv_sec) * 1000 + jlong(time.tv_usec / 1000);
987 } 991 }
988 992
993 #ifndef __APPLE__
989 #ifndef CLOCK_MONOTONIC 994 #ifndef CLOCK_MONOTONIC
990 #define CLOCK_MONOTONIC (1) 995 #define CLOCK_MONOTONIC (1)
991 #endif 996 #endif
997 #endif
992 998
993 #ifdef __APPLE__ 999 #ifdef __APPLE__
994 void os::Bsd::clock_init() { 1000 void os::Bsd::clock_init() {
995 // XXXDARWIN: Investigate replacement monotonic clock 1001 mach_timebase_info(&_timebase_info);
996 } 1002 }
997 #else 1003 #else
998 void os::Bsd::clock_init() { 1004 void os::Bsd::clock_init() {
999 struct timespec res; 1005 struct timespec res;
1000 struct timespec tp; 1006 struct timespec tp;
1005 } 1011 }
1006 } 1012 }
1007 #endif 1013 #endif
1008 1014
1009 1015
1016 #ifdef __APPLE__
1017
1018 jlong os::javaTimeNanos() {
1019 const uint64_t tm = mach_absolute_time();
1020 const uint64_t now = (tm * Bsd::_timebase_info.numer) / Bsd::_timebase_info.denom;
1021 const uint64_t prev = Bsd::_max_abstime;
1022 if (now <= prev) {
1023 return prev; // same or retrograde time;
1024 }
1025 const uint64_t obsv = Atomic::cmpxchg(now, (volatile jlong*)&Bsd::_max_abstime, prev);
1026 assert(obsv >= prev, "invariant"); // Monotonicity
1027 // If the CAS succeeded then we're done and return "now".
1028 // If the CAS failed and the observed value "obsv" is >= now then
1029 // we should return "obsv". If the CAS failed and now > obsv > prv then
1030 // some other thread raced this thread and installed a new value, in which case
1031 // we could either (a) retry the entire operation, (b) retry trying to install now
1032 // or (c) just return obsv. We use (c). No loop is required although in some cases
1033 // we might discard a higher "now" value in deference to a slightly lower but freshly
1034 // installed obsv value. That's entirely benign -- it admits no new orderings compared
1035 // to (a) or (b) -- and greatly reduces coherence traffic.
1036 // We might also condition (c) on the magnitude of the delta between obsv and now.
1037 // Avoiding excessive CAS operations to hot RW locations is critical.
1038 // See https://blogs.oracle.com/dave/entry/cas_and_cache_trivia_invalidate
1039 return (prev == obsv) ? now : obsv;
1040 }
1041
1042 #else // __APPLE__
1043
1010 jlong os::javaTimeNanos() { 1044 jlong os::javaTimeNanos() {
1011 if (Bsd::supports_monotonic_clock()) { 1045 if (Bsd::supports_monotonic_clock()) {
1012 struct timespec tp; 1046 struct timespec tp;
1013 int status = Bsd::clock_gettime(CLOCK_MONOTONIC, &tp); 1047 int status = Bsd::_clock_gettime(CLOCK_MONOTONIC, &tp);
1014 assert(status == 0, "gettime error"); 1048 assert(status == 0, "gettime error");
1015 jlong result = jlong(tp.tv_sec) * (1000 * 1000 * 1000) + jlong(tp.tv_nsec); 1049 jlong result = jlong(tp.tv_sec) * (1000 * 1000 * 1000) + jlong(tp.tv_nsec);
1016 return result; 1050 return result;
1017 } else { 1051 } else {
1018 timeval time; 1052 timeval time;
1020 assert(status != -1, "bsd error"); 1054 assert(status != -1, "bsd error");
1021 jlong usecs = jlong(time.tv_sec) * (1000 * 1000) + jlong(time.tv_usec); 1055 jlong usecs = jlong(time.tv_sec) * (1000 * 1000) + jlong(time.tv_usec);
1022 return 1000 * usecs; 1056 return 1000 * usecs;
1023 } 1057 }
1024 } 1058 }
1059
1060 #endif // __APPLE__
1025 1061
1026 void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) { 1062 void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {
1027 if (Bsd::supports_monotonic_clock()) { 1063 if (Bsd::supports_monotonic_clock()) {
1028 info_ptr->max_value = ALL_64_BITS; 1064 info_ptr->max_value = ALL_64_BITS;
1029 1065