src/os/bsd/vm/os_bsd.cpp

Print this page
rev 6280 : 8040140: System.nanoTime() is slow and non-monotonic on OS X
6864866: add a flag to use result of gethrtime() directly in os::getTimeNanos() on Solaris
Reviewed-by: sspitsyn, shade, dholmes


 110 # include <mach/mach.h> // semaphore_* API
 111 # include <mach-o/dyld.h>
 112 # include <sys/proc_info.h>
 113 # include <objc/objc-auto.h>
 114 #endif
 115 
 116 #ifndef MAP_ANONYMOUS
 117 #define MAP_ANONYMOUS MAP_ANON
 118 #endif
 119 
 120 #define MAX_PATH    (2 * K)
 121 
 122 // for timer info max values which include all bits
 123 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
 124 
 125 #define LARGEPAGES_BIT (1 << 6)
 126 ////////////////////////////////////////////////////////////////////////////////
 127 // global variables
 128 julong os::Bsd::_physical_memory = 0;
 129 
 130 



 131 int (*os::Bsd::_clock_gettime)(clockid_t, struct timespec *) = NULL;

 132 pthread_t os::Bsd::_main_thread;
 133 int os::Bsd::_page_size = -1;
 134 
 135 static jlong initial_time_count=0;
 136 
 137 static int clock_tics_per_sec = 100;
 138 
 139 // For diagnostics to print a message once. see run_periodic_checks
 140 static sigset_t check_signal_done;
 141 static bool check_signals = true;
 142 
 143 static pid_t _initial_pid = 0;
 144 
 145 /* Signal number used to suspend/resume a thread */
 146 
 147 /* do not use any signal number less than SIGSEGV, see 4355769 */
 148 static int SR_signum = SIGUSR2;
 149 sigset_t SR_sigset;
 150 
 151 


 969 jlong os::elapsed_frequency() {
 970   return NANOSECS_PER_SEC; // nanosecond resolution
 971 }
 972 
 973 bool os::supports_vtime() { return true; }
 974 bool os::enable_vtime()   { return false; }
 975 bool os::vtime_enabled()  { return false; }
 976 
 977 double os::elapsedVTime() {
 978   // better than nothing, but not much
 979   return elapsedTime();
 980 }
 981 
 982 jlong os::javaTimeMillis() {
 983   timeval time;
 984   int status = gettimeofday(&time, NULL);
 985   assert(status != -1, "bsd error");
 986   return jlong(time.tv_sec) * 1000  +  jlong(time.tv_usec / 1000);
 987 }
 988 

 989 #ifndef CLOCK_MONOTONIC
 990 #define CLOCK_MONOTONIC (1)
 991 #endif

 992 
 993 #ifdef __APPLE__
 994 void os::Bsd::clock_init() {
 995         // XXXDARWIN: Investigate replacement monotonic clock
 996 }
 997 #else
 998 void os::Bsd::clock_init() {
 999   struct timespec res;
1000   struct timespec tp;
1001   if (::clock_getres(CLOCK_MONOTONIC, &res) == 0 &&
1002       ::clock_gettime(CLOCK_MONOTONIC, &tp)  == 0) {
1003     // yes, monotonic clock is supported
1004     _clock_gettime = ::clock_gettime;
1005   }
1006 }
1007 #endif
1008 
1009 

































1010 jlong os::javaTimeNanos() {
1011   if (os::supports_monotonic_clock()) {
1012     struct timespec tp;
1013     int status = Bsd::clock_gettime(CLOCK_MONOTONIC, &tp);
1014     assert(status == 0, "gettime error");
1015     jlong result = jlong(tp.tv_sec) * (1000 * 1000 * 1000) + jlong(tp.tv_nsec);
1016     return result;
1017   } else {
1018     timeval time;
1019     int status = gettimeofday(&time, NULL);
1020     assert(status != -1, "bsd error");
1021     jlong usecs = jlong(time.tv_sec) * (1000 * 1000) + jlong(time.tv_usec);
1022     return 1000 * usecs;
1023   }
1024 }
1025 


1026 void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {
1027   if (os::supports_monotonic_clock()) {
1028     info_ptr->max_value = ALL_64_BITS;
1029 
1030     // CLOCK_MONOTONIC - amount of time since some arbitrary point in the past
1031     info_ptr->may_skip_backward = false;      // not subject to resetting or drifting
1032     info_ptr->may_skip_forward = false;       // not subject to resetting or drifting
1033   } else {
1034     // gettimeofday - based on time in seconds since the Epoch thus does not wrap
1035     info_ptr->max_value = ALL_64_BITS;
1036 
1037     // gettimeofday is a real time clock so it skips
1038     info_ptr->may_skip_backward = true;
1039     info_ptr->may_skip_forward = true;
1040   }
1041 
1042   info_ptr->kind = JVMTI_TIMER_ELAPSED;                // elapsed not CPU time
1043 }
1044 
1045 // Return the real, user, and system times in seconds from an




 110 # include <mach/mach.h> // semaphore_* API
 111 # include <mach-o/dyld.h>
 112 # include <sys/proc_info.h>
 113 # include <objc/objc-auto.h>
 114 #endif
 115 
 116 #ifndef MAP_ANONYMOUS
 117 #define MAP_ANONYMOUS MAP_ANON
 118 #endif
 119 
 120 #define MAX_PATH    (2 * K)
 121 
 122 // for timer info max values which include all bits
 123 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
 124 
 125 #define LARGEPAGES_BIT (1 << 6)
 126 ////////////////////////////////////////////////////////////////////////////////
 127 // global variables
 128 julong os::Bsd::_physical_memory = 0;
 129 
 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
 134 int (*os::Bsd::_clock_gettime)(clockid_t, struct timespec *) = NULL;
 135 #endif
 136 pthread_t os::Bsd::_main_thread;
 137 int os::Bsd::_page_size = -1;
 138 
 139 static jlong initial_time_count=0;
 140 
 141 static int clock_tics_per_sec = 100;
 142 
 143 // For diagnostics to print a message once. see run_periodic_checks
 144 static sigset_t check_signal_done;
 145 static bool check_signals = true;
 146 
 147 static pid_t _initial_pid = 0;
 148 
 149 /* Signal number used to suspend/resume a thread */
 150 
 151 /* do not use any signal number less than SIGSEGV, see 4355769 */
 152 static int SR_signum = SIGUSR2;
 153 sigset_t SR_sigset;
 154 
 155 


 973 jlong os::elapsed_frequency() {
 974   return NANOSECS_PER_SEC; // nanosecond resolution
 975 }
 976 
 977 bool os::supports_vtime() { return true; }
 978 bool os::enable_vtime()   { return false; }
 979 bool os::vtime_enabled()  { return false; }
 980 
 981 double os::elapsedVTime() {
 982   // better than nothing, but not much
 983   return elapsedTime();
 984 }
 985 
 986 jlong os::javaTimeMillis() {
 987   timeval time;
 988   int status = gettimeofday(&time, NULL);
 989   assert(status != -1, "bsd error");
 990   return jlong(time.tv_sec) * 1000  +  jlong(time.tv_usec / 1000);
 991 }
 992 
 993 #ifndef __APPLE__
 994 #ifndef CLOCK_MONOTONIC
 995 #define CLOCK_MONOTONIC (1)
 996 #endif
 997 #endif
 998 
 999 #ifdef __APPLE__
1000 void os::Bsd::clock_init() {
1001   mach_timebase_info(&_timebase_info);
1002 }
1003 #else
1004 void os::Bsd::clock_init() {
1005   struct timespec res;
1006   struct timespec tp;
1007   if (::clock_getres(CLOCK_MONOTONIC, &res) == 0 &&
1008       ::clock_gettime(CLOCK_MONOTONIC, &tp)  == 0) {
1009     // yes, monotonic clock is supported
1010     _clock_gettime = ::clock_gettime;
1011   }
1012 }
1013 #endif
1014 
1015 
1016 
1017 #ifdef __APPLE__
1018 
1019 jlong os::javaTimeNanos() {
1020     const uint64_t tm = mach_absolute_time();
1021     const uint64_t now = (tm * Bsd::_timebase_info.numer) / Bsd::_timebase_info.denom;
1022     if (AssumeMonotonicOSTimers) {
1023       return now;
1024     }
1025 
1026     const uint64_t prev = Bsd::_max_abstime;
1027     if (now <= prev) {
1028       return prev;   // same or retrograde time;
1029     }
1030     const uint64_t obsv = Atomic::cmpxchg(now, (volatile jlong*)&Bsd::_max_abstime, prev);
1031     assert(obsv >= prev, "invariant");   // Monotonicity
1032     // If the CAS succeeded then we're done and return "now".
1033     // If the CAS failed and the observed value "obsv" is >= now then
1034     // we should return "obsv".  If the CAS failed and now > obsv > prv then
1035     // some other thread raced this thread and installed a new value, in which case
1036     // we could either (a) retry the entire operation, (b) retry trying to install now
1037     // or (c) just return obsv.  We use (c).   No loop is required although in some cases
1038     // we might discard a higher "now" value in deference to a slightly lower but freshly
1039     // installed obsv value.   That's entirely benign -- it admits no new orderings compared
1040     // to (a) or (b) -- and greatly reduces coherence traffic.
1041     // We might also condition (c) on the magnitude of the delta between obsv and now.
1042     // Avoiding excessive CAS operations to hot RW locations is critical.
1043     // See https://blogs.oracle.com/dave/entry/cas_and_cache_trivia_invalidate
1044     return (prev == obsv) ? now : obsv;
1045 }
1046 
1047 #else // __APPLE__
1048 
1049 jlong os::javaTimeNanos() {
1050   if (os::supports_monotonic_clock()) {
1051     struct timespec tp;
1052     int status = Bsd::_clock_gettime(CLOCK_MONOTONIC, &tp);
1053     assert(status == 0, "gettime error");
1054     jlong result = jlong(tp.tv_sec) * (1000 * 1000 * 1000) + jlong(tp.tv_nsec);
1055     return result;
1056   } else {
1057     timeval time;
1058     int status = gettimeofday(&time, NULL);
1059     assert(status != -1, "bsd error");
1060     jlong usecs = jlong(time.tv_sec) * (1000 * 1000) + jlong(time.tv_usec);
1061     return 1000 * usecs;
1062   }
1063 }
1064 
1065 #endif // __APPLE__
1066 
1067 void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {
1068   if (os::supports_monotonic_clock()) {
1069     info_ptr->max_value = ALL_64_BITS;
1070 
1071     // CLOCK_MONOTONIC - amount of time since some arbitrary point in the past
1072     info_ptr->may_skip_backward = false;      // not subject to resetting or drifting
1073     info_ptr->may_skip_forward = false;       // not subject to resetting or drifting
1074   } else {
1075     // gettimeofday - based on time in seconds since the Epoch thus does not wrap
1076     info_ptr->max_value = ALL_64_BITS;
1077 
1078     // gettimeofday is a real time clock so it skips
1079     info_ptr->may_skip_backward = true;
1080     info_ptr->may_skip_forward = true;
1081   }
1082 
1083   info_ptr->kind = JVMTI_TIMER_ELAPSED;                // elapsed not CPU time
1084 }
1085 
1086 // Return the real, user, and system times in seconds from an