Merge fixes for JDK-6900441 and JDK-8029453 from Linux sources.

This commit is contained in:
Jung-uk Kim 2017-04-13 21:27:23 +00:00
parent 54ccbad796
commit 7bd7158dc9
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/head/; revision=438482
3 changed files with 303 additions and 1 deletions

View File

@ -3,7 +3,7 @@
PORTNAME= openjdk
PORTVERSION= ${JDK_MAJOR_VERSION}.${PORT_MINOR_VERSION}.${PORT_BUILD_NUMBER}
PORTREVISION= 3
PORTREVISION= 4
PORTEPOCH= 1
CATEGORIES= java devel
MASTER_SITES= http://download.java.net/openjdk/jdk${JDK_MAJOR_VERSION}u${JDK_MINOR_VERSION}/promoted/b${JDK_BUILD_NUMBER}/ \

View File

@ -0,0 +1,239 @@
--- hotspot/src/os/bsd/vm/os_bsd.cpp.orig 2013-09-06 18:22:03 UTC
+++ hotspot/src/os/bsd/vm/os_bsd.cpp
@@ -163,6 +163,7 @@ Mutex* os::Bsd::_createThread_lock = NUL
#endif
pthread_t os::Bsd::_main_thread;
int os::Bsd::_page_size = -1;
+pthread_condattr_t os::Bsd::_condattr[1];
#ifndef _ALLBSD_SOURCE
bool os::Bsd::_is_floating_stack = false;
bool os::Bsd::_is_NPTL = false;
@@ -1602,7 +1603,10 @@ void os::Bsd::clock_init() {
::clock_gettime(CLOCK_MONOTONIC, &tp) == 0) {
// yes, monotonic clock is supported
_clock_gettime = ::clock_gettime;
+ return;
}
+ warning("No monotonic clock was available - timed services may " \
+ "be adversely affected if the time-of-day clock changes");
}
#else
void os::Bsd::clock_init() {
@@ -1688,7 +1692,7 @@ void os::Bsd::fast_thread_clock_init() {
jlong os::javaTimeNanos() {
if (Bsd::supports_monotonic_clock()) {
struct timespec tp;
- int status = Bsd::clock_gettime(CLOCK_MONOTONIC, &tp);
+ int status = ::clock_gettime(CLOCK_MONOTONIC, &tp);
assert(status == 0, "gettime error");
jlong result = jlong(tp.tv_sec) * (1000 * 1000 * 1000) + jlong(tp.tv_nsec);
return result;
@@ -4679,6 +4683,25 @@ void os::init(void) {
Bsd::clock_init();
initial_time_count = os::elapsed_counter();
+ // pthread_condattr initialization for monotonic clock
+ int status;
+ pthread_condattr_t* _condattr = os::Bsd::condAttr();
+ if ((status = pthread_condattr_init(_condattr)) != 0) {
+ fatal(err_msg("pthread_condattr_init: %s", strerror(status)));
+ }
+ // Only set the clock if CLOCK_MONOTONIC is available
+ if (Bsd::supports_monotonic_clock()) {
+ if ((status = pthread_condattr_setclock(_condattr, CLOCK_MONOTONIC)) != 0) {
+ if (status == EINVAL) {
+ warning("Unable to use monotonic clock with relative timed-waits" \
+ " - changes to the time-of-day clock may have adverse affects");
+ } else {
+ fatal(err_msg("pthread_condattr_setclock: %s", strerror(status)));
+ }
+ }
+ }
+ // else it defaults to CLOCK_REALTIME
+
#ifdef __APPLE__
// XXXDARWIN
// Work around the unaligned VM callbacks in hotspot's
@@ -5599,21 +5622,36 @@ void os::pause() {
static struct timespec* compute_abstime(struct timespec* abstime, jlong millis) {
if (millis < 0) millis = 0;
- struct timeval now;
- int status = gettimeofday(&now, NULL);
- assert(status == 0, "gettimeofday");
+
jlong seconds = millis / 1000;
millis %= 1000;
if (seconds > 50000000) { // see man cond_timedwait(3T)
seconds = 50000000;
}
- abstime->tv_sec = now.tv_sec + seconds;
- long usec = now.tv_usec + millis * 1000;
- if (usec >= 1000000) {
- abstime->tv_sec += 1;
- usec -= 1000000;
+
+ if (os::Bsd::supports_monotonic_clock()) {
+ struct timespec now;
+ int status = ::clock_gettime(CLOCK_MONOTONIC, &now);
+ assert_status(status == 0, status, "clock_gettime");
+ abstime->tv_sec = now.tv_sec + seconds;
+ long nanos = now.tv_nsec + millis * NANOSECS_PER_MILLISEC;
+ if (nanos >= NANOSECS_PER_SEC) {
+ abstime->tv_sec += 1;
+ nanos -= NANOSECS_PER_SEC;
+ }
+ abstime->tv_nsec = nanos;
+ } else {
+ struct timeval now;
+ int status = gettimeofday(&now, NULL);
+ assert(status == 0, "gettimeofday");
+ abstime->tv_sec = now.tv_sec + seconds;
+ long usec = now.tv_usec + millis * 1000;
+ if (usec >= 1000000) {
+ abstime->tv_sec += 1;
+ usec -= 1000000;
+ }
+ abstime->tv_nsec = usec * 1000;
}
- abstime->tv_nsec = usec * 1000;
return abstime;
}
@@ -5705,7 +5743,7 @@ int os::PlatformEvent::park(jlong millis
status = os::Bsd::safe_cond_timedwait(_cond, _mutex, &abst);
if (status != 0 && WorkAroundNPTLTimedWaitHang) {
pthread_cond_destroy (_cond);
- pthread_cond_init (_cond, NULL) ;
+ pthread_cond_init (_cond, os::Bsd::condAttr()) ;
}
assert_status(status == 0 || status == EINTR ||
status == ETIMEDOUT,
@@ -5806,32 +5844,50 @@ void os::PlatformEvent::unpark() {
static void unpackTime(struct timespec* absTime, bool isAbsolute, jlong time) {
assert (time > 0, "convertTime");
+ time_t max_secs = 0;
- struct timeval now;
- int status = gettimeofday(&now, NULL);
- assert(status == 0, "gettimeofday");
+ if (!os::Bsd::supports_monotonic_clock() || isAbsolute) {
+ struct timeval now;
+ int status = gettimeofday(&now, NULL);
+ assert(status == 0, "gettimeofday");
- time_t max_secs = now.tv_sec + MAX_SECS;
+ max_secs = now.tv_sec + MAX_SECS;
- if (isAbsolute) {
- jlong secs = time / 1000;
- if (secs > max_secs) {
- absTime->tv_sec = max_secs;
- }
- else {
- absTime->tv_sec = secs;
+ if (isAbsolute) {
+ jlong secs = time / 1000;
+ if (secs > max_secs) {
+ absTime->tv_sec = max_secs;
+ } else {
+ absTime->tv_sec = secs;
+ }
+ absTime->tv_nsec = (time % 1000) * NANOSECS_PER_MILLISEC;
+ } else {
+ jlong secs = time / NANOSECS_PER_SEC;
+ if (secs >= MAX_SECS) {
+ absTime->tv_sec = max_secs;
+ absTime->tv_nsec = 0;
+ } else {
+ absTime->tv_sec = now.tv_sec + secs;
+ absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_usec*1000;
+ if (absTime->tv_nsec >= NANOSECS_PER_SEC) {
+ absTime->tv_nsec -= NANOSECS_PER_SEC;
+ ++absTime->tv_sec; // note: this must be <= max_secs
+ }
+ }
}
- absTime->tv_nsec = (time % 1000) * NANOSECS_PER_MILLISEC;
- }
- else {
+ } else {
+ // must be relative using monotonic clock
+ struct timespec now;
+ int status = ::clock_gettime(CLOCK_MONOTONIC, &now);
+ assert_status(status == 0, status, "clock_gettime");
+ max_secs = now.tv_sec + MAX_SECS;
jlong secs = time / NANOSECS_PER_SEC;
if (secs >= MAX_SECS) {
absTime->tv_sec = max_secs;
absTime->tv_nsec = 0;
- }
- else {
+ } else {
absTime->tv_sec = now.tv_sec + secs;
- absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_usec*1000;
+ absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_nsec;
if (absTime->tv_nsec >= NANOSECS_PER_SEC) {
absTime->tv_nsec -= NANOSECS_PER_SEC;
++absTime->tv_sec; // note: this must be <= max_secs
@@ -5911,15 +5967,19 @@ void Parker::park(bool isAbsolute, jlong
jt->set_suspend_equivalent();
// cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
+ assert(_cur_index == -1, "invariant");
if (time == 0) {
- status = pthread_cond_wait (_cond, _mutex) ;
+ _cur_index = REL_INDEX; // arbitrary choice when not timed
+ status = pthread_cond_wait (&_cond[_cur_index], _mutex) ;
} else {
- status = os::Bsd::safe_cond_timedwait (_cond, _mutex, &absTime) ;
+ _cur_index = isAbsolute ? ABS_INDEX : REL_INDEX;
+ status = os::Bsd::safe_cond_timedwait (&_cond[_cur_index], _mutex, &absTime) ;
if (status != 0 && WorkAroundNPTLTimedWaitHang) {
- pthread_cond_destroy (_cond) ;
- pthread_cond_init (_cond, NULL);
+ pthread_cond_destroy (&_cond[_cur_index]) ;
+ pthread_cond_init (&_cond[_cur_index], isAbsolute ? NULL : os::Bsd::condAttr());
}
}
+ _cur_index = -1;
assert_status(status == 0 || status == EINTR ||
status == ETIMEDOUT,
status, "cond_timedwait");
@@ -5948,17 +6008,26 @@ void Parker::unpark() {
s = _counter;
_counter = 1;
if (s < 1) {
- if (WorkAroundNPTLTimedWaitHang) {
- status = pthread_cond_signal (_cond) ;
- assert (status == 0, "invariant") ;
+ // thread might be parked
+ if (_cur_index != -1) {
+ // thread is definitely parked
+ if (WorkAroundNPTLTimedWaitHang) {
+ status = pthread_cond_signal (&_cond[_cur_index]);
+ assert (status == 0, "invariant");
status = pthread_mutex_unlock(_mutex);
- assert (status == 0, "invariant") ;
- } else {
+ assert (status == 0, "invariant");
+ } else {
+ // must capture correct index before unlocking
+ int index = _cur_index;
status = pthread_mutex_unlock(_mutex);
- assert (status == 0, "invariant") ;
- status = pthread_cond_signal (_cond) ;
- assert (status == 0, "invariant") ;
- }
+ assert (status == 0, "invariant");
+ status = pthread_cond_signal (&_cond[index]);
+ assert (status == 0, "invariant");
+ }
+ } else {
+ pthread_mutex_unlock(_mutex);
+ assert (status == 0, "invariant") ;
+ }
} else {
pthread_mutex_unlock(_mutex);
assert (status == 0, "invariant") ;

View File

@ -0,0 +1,63 @@
--- hotspot/src/os/bsd/vm/os_bsd.hpp.orig 2013-09-06 18:22:03 UTC
+++ hotspot/src/os/bsd/vm/os_bsd.hpp
@@ -222,6 +222,13 @@ class Bsd {
static jlong fast_thread_cpu_time(clockid_t clockid);
#endif
+ // pthread_cond clock suppport
+ private:
+ static pthread_condattr_t _condattr[1];
+
+ public:
+ static pthread_condattr_t* condAttr() { return _condattr; }
+
// Stack repair handling
// none present
@@ -287,7 +294,7 @@ class PlatformEvent : public CHeapObj<mt
public:
PlatformEvent() {
int status;
- status = pthread_cond_init (_cond, NULL);
+ status = pthread_cond_init (_cond, os::Bsd::condAttr());
assert_status(status == 0, status, "cond_init");
status = pthread_mutex_init (_mutex, NULL);
assert_status(status == 0, status, "mutex_init");
@@ -302,14 +309,19 @@ class PlatformEvent : public CHeapObj<mt
void park () ;
void unpark () ;
int TryPark () ;
- int park (jlong millis) ;
+ int park (jlong millis) ; // relative timed-wait only
void SetAssociation (Thread * a) { _Assoc = a ; }
};
class PlatformParker : public CHeapObj<mtInternal> {
protected:
+ enum {
+ REL_INDEX = 0,
+ ABS_INDEX = 1
+ };
+ int _cur_index; // which cond is in use: -1, 0, 1
pthread_mutex_t _mutex [1] ;
- pthread_cond_t _cond [1] ;
+ pthread_cond_t _cond [2] ; // one for relative times and one for abs.
public: // TODO-FIXME: make dtor private
~PlatformParker() { guarantee (0, "invariant") ; }
@@ -317,10 +329,13 @@ class PlatformParker : public CHeapObj<m
public:
PlatformParker() {
int status;
- status = pthread_cond_init (_cond, NULL);
- assert_status(status == 0, status, "cond_init");
+ status = pthread_cond_init (&_cond[REL_INDEX], os::Bsd::condAttr());
+ assert_status(status == 0, status, "cond_init rel");
+ status = pthread_cond_init (&_cond[ABS_INDEX], NULL);
+ assert_status(status == 0, status, "cond_init abs");
status = pthread_mutex_init (_mutex, NULL);
assert_status(status == 0, status, "mutex_init");
+ _cur_index = -1; // mark as unused
}
};