--- a/src/hotspot/os/posix/os_posix.cpp Wed Jan 23 14:10:31 2019 -0800
+++ b/src/hotspot/os/posix/os_posix.cpp Wed Jan 23 21:17:51 2019 -0500
@@ -1619,11 +1619,9 @@
}
}
-
-// Shared pthread_mutex/cond based PlatformEvent implementation.
-// Not currently usable by Solaris.
-
-#ifndef SOLARIS
+// Shared clock/time and other supporting routines for pthread_mutex/cond
+// initialization. This is enabled on Solaris but only some of the clock/time
+// functionality is actually used there.
// Shared condattr object for use with relative timed-waits. Will be associated
// with CLOCK_MONOTONIC if available to avoid issues with time-of-day changes,
@@ -1661,11 +1659,11 @@
// This means we have clockid_t, clock_gettime et al and CLOCK_MONOTONIC
-static int (*_clock_gettime)(clockid_t, struct timespec *);
-static int (*_clock_getres)(clockid_t, struct timespec *);
-static int (*_pthread_condattr_setclock)(pthread_condattr_t *, clockid_t);
+static int (*_clock_gettime)(clockid_t, struct timespec *) = NULL;
+static int (*_clock_getres)(clockid_t, struct timespec *) = NULL;
+static int (*_pthread_condattr_setclock)(pthread_condattr_t *, clockid_t) = NULL;
-static bool _use_clock_monotonic_condattr;
+static bool _use_clock_monotonic_condattr = false;
// Exported clock functionality
@@ -1707,9 +1705,6 @@
handle = RTLD_DEFAULT;
}
- _clock_gettime = NULL;
- _clock_getres = NULL;
-
int (*clock_getres_func)(clockid_t, struct timespec*) =
(int(*)(clockid_t, struct timespec*))dlsym(handle, "clock_getres");
int (*clock_gettime_func)(clockid_t, struct timespec*) =
@@ -1736,8 +1731,6 @@
// 2. Check for pthread_condattr_setclock support.
- _pthread_condattr_setclock = NULL;
-
// libpthread is already loaded.
int (*condattr_setclock_func)(pthread_condattr_t*, clockid_t) =
(int (*)(pthread_condattr_t*, clockid_t))dlsym(RTLD_DEFAULT,
@@ -1750,6 +1743,7 @@
pthread_init_common();
+#ifndef SOLARIS
int status;
if (_pthread_condattr_setclock != NULL && _clock_gettime != NULL) {
if ((status = _pthread_condattr_setclock(_condAttr, CLOCK_MONOTONIC)) != 0) {
@@ -1763,18 +1757,20 @@
} else {
_use_clock_monotonic_condattr = true;
}
- } else {
- _use_clock_monotonic_condattr = false;
}
+#endif // !SOLARIS
+
}
void os::Posix::init_2(void) {
+#ifndef SOLARIS
log_info(os)("Use of CLOCK_MONOTONIC is%s supported",
(_clock_gettime != NULL ? "" : " not"));
log_info(os)("Use of pthread_condattr_setclock is%s supported",
(_pthread_condattr_setclock != NULL ? "" : " not"));
log_info(os)("Relative timed-wait using pthread_cond_timedwait is associated with %s",
_use_clock_monotonic_condattr ? "CLOCK_MONOTONIC" : "the default clock");
+#endif // !SOLARIS
}
#else // !SUPPORTS_CLOCK_MONOTONIC
@@ -1784,30 +1780,25 @@
}
void os::Posix::init_2(void) {
+#ifndef SOLARIS
log_info(os)("Use of CLOCK_MONOTONIC is not supported");
log_info(os)("Use of pthread_condattr_setclock is not supported");
log_info(os)("Relative timed-wait using pthread_cond_timedwait is associated with the default clock");
+#endif // !SOLARIS
}
#endif // SUPPORTS_CLOCK_MONOTONIC
-os::PlatformEvent::PlatformEvent() {
- int status = pthread_cond_init(_cond, _condAttr);
- assert_status(status == 0, status, "cond_init");
- status = pthread_mutex_init(_mutex, _mutexAttr);
- assert_status(status == 0, status, "mutex_init");
- _event = 0;
- _nParked = 0;
-}
-
// Utility to convert the given timeout to an absolute timespec
-// (based on the appropriate clock) to use with pthread_cond_timewait.
+// (based on the appropriate clock) to use with pthread_cond_timewait,
+// and sem_timedwait().
// The clock queried here must be the clock used to manage the
-// timeout of the condition variable.
+// timeout of the condition variable or semaphore.
//
// The passed in timeout value is either a relative time in nanoseconds
// or an absolute time in milliseconds. A relative timeout will be
-// associated with CLOCK_MONOTONIC if available; otherwise, or if absolute,
+// associated with CLOCK_MONOTONIC if available, unless the real-time clock
+// is explicitly requested; otherwise, or if absolute,
// the default time-of-day clock will be used.
// Given time is a 64-bit value and the time_t used in the timespec is
@@ -1824,7 +1815,7 @@
// Calculate a new absolute time that is "timeout" nanoseconds from "now".
// "unit" indicates the unit of "now_part_sec" (may be nanos or micros depending
-// on which clock is being used).
+// on which clock API is being used).
static void calc_rel_time(timespec* abstime, jlong timeout, jlong now_sec,
jlong now_part_sec, jlong unit) {
time_t max_secs = now_sec + MAX_SECS;
@@ -1849,6 +1840,7 @@
// Unpack the given deadline in milliseconds since the epoch, into the given timespec.
// The current time in seconds is also passed in to enforce an upper bound as discussed above.
+// This is only used with gettimeofday, when clock_gettime is not available.
static void unpack_abs_time(timespec* abstime, jlong deadline, jlong now_sec) {
time_t max_secs = now_sec + MAX_SECS;
@@ -1865,7 +1857,18 @@
}
}
-static void to_abstime(timespec* abstime, jlong timeout, bool isAbsolute) {
+static jlong millis_to_nanos(jlong millis) {
+ // We have to watch for overflow when converting millis to nanos,
+ // but if millis is that large then we will end up limiting to
+ // MAX_SECS anyway, so just do that here.
+ if (millis / MILLIUNITS > MAX_SECS) {
+ millis = jlong(MAX_SECS) * MILLIUNITS;
+ }
+ return millis * (NANOUNITS / MILLIUNITS);
+}
+
+static void to_abstime(timespec* abstime, jlong timeout,
+ bool isAbsolute, bool isRealtime) {
DEBUG_ONLY(int max_secs = MAX_SECS;)
if (timeout < 0) {
@@ -1874,9 +1877,14 @@
#ifdef SUPPORTS_CLOCK_MONOTONIC
- if (_use_clock_monotonic_condattr && !isAbsolute) {
+ clockid_t clock = CLOCK_MONOTONIC;
+ // need to ensure we have a runtime check for clock_gettime support
+ if (!isAbsolute && _clock_gettime != NULL) {
+ if (!_use_clock_monotonic_condattr || isRealtime) {
+ clock = CLOCK_REALTIME;
+ }
struct timespec now;
- int status = _clock_gettime(CLOCK_MONOTONIC, &now);
+ int status = _clock_gettime(clock, &now);
assert_status(status == 0, status, "clock_gettime");
calc_rel_time(abstime, timeout, now.tv_sec, now.tv_nsec, NANOUNITS);
DEBUG_ONLY(max_secs += now.tv_sec;)
@@ -1906,6 +1914,19 @@
assert(abstime->tv_nsec < NANOUNITS, "tv_nsec >= NANOUNITS");
}
+// Create an absolute time 'millis' milliseconds in the future, using the
+// real-time (time-of-day) clock. Used by PosixSemaphore.
+void os::Posix::to_RTC_abstime(timespec* abstime, int64_t millis) {
+ to_abstime(abstime, millis_to_nanos(millis),
+ false /* not absolute */,
+ true /* use real-time clock */);
+}
+
+// Shared pthread_mutex/cond based PlatformEvent implementation.
+// Not currently usable by Solaris.
+
+#ifndef SOLARIS
+
// PlatformEvent
//
// Assumption:
@@ -1921,6 +1942,15 @@
// Having three states allows for some detection of bad usage - see
// comments on unpark().
+os::PlatformEvent::PlatformEvent() {
+ int status = pthread_cond_init(_cond, _condAttr);
+ assert_status(status == 0, status, "cond_init");
+ status = pthread_mutex_init(_mutex, _mutexAttr);
+ assert_status(status == 0, status, "mutex_init");
+ _event = 0;
+ _nParked = 0;
+}
+
void os::PlatformEvent::park() { // AKA "down()"
// Transitions for _event:
// -1 => -1 : illegal
@@ -1982,13 +2012,7 @@
if (v == 0) { // Do this the hard way by blocking ...
struct timespec abst;
- // We have to watch for overflow when converting millis to nanos,
- // but if millis is that large then we will end up limiting to
- // MAX_SECS anyway, so just do that here.
- if (millis / MILLIUNITS > MAX_SECS) {
- millis = jlong(MAX_SECS) * MILLIUNITS;
- }
- to_abstime(&abst, millis * (NANOUNITS / MILLIUNITS), false);
+ to_abstime(&abst, millis_to_nanos(millis), false, false);
int ret = OS_TIMEOUT;
int status = pthread_mutex_lock(_mutex);
@@ -2106,7 +2130,7 @@
return;
}
if (time > 0) {
- to_abstime(&absTime, time, isAbsolute);
+ to_abstime(&absTime, time, isAbsolute, false);
}
// Enter safepoint region