aboutsummaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
authorJung-uk Kim <jkim@FreeBSD.org>2017-04-13 18:09:21 +0000
committerJung-uk Kim <jkim@FreeBSD.org>2017-04-13 18:09:21 +0000
commitd656192397c5452f69fa8c8a1d309253226e695f (patch)
treed5e24ef94adfc1113475c7f58181267d25bdf80f /java
parente4e74c2d53c185cc6793fd8c767cbe6d854a4f6d (diff)
downloadports-d656192397c5452f69fa8c8a1d309253226e695f.tar.gz
ports-d656192397c5452f69fa8c8a1d309253226e695f.zip
Merge fix for JDK-6900441 from Linux source.
http://bugs.java.com/view_bug.do?bug_id=6900441 While we are at it, merge fix for JDK-8029453. http://bugs.java.com/view_bug.do?bug_id=8029453 Note JDK-8029453 only affects us when "-XX:WorkAroundNPTLTimedWaitHang=0" is forcibly set. Reported by: 张泽鹏 (redraiment at gmail dot com) Tested by: 张泽鹏 (redraiment at gmail dot com)
Notes
Notes: svn path=/head/; revision=438460
Diffstat (limited to 'java')
-rw-r--r--java/openjdk8/Makefile1
-rw-r--r--java/openjdk8/files/patch-hotspot_src_os_bsd_vm_os__bsd.cpp245
-rw-r--r--java/openjdk8/files/patch-hotspot_src_os_bsd_vm_os__bsd.hpp63
3 files changed, 309 insertions, 0 deletions
diff --git a/java/openjdk8/Makefile b/java/openjdk8/Makefile
index 15a40b1255cd..ddd09c73146c 100644
--- a/java/openjdk8/Makefile
+++ b/java/openjdk8/Makefile
@@ -2,6 +2,7 @@
PORTNAME= openjdk
PORTVERSION= ${JDK_MAJOR_VERSION}.${JDK_UPDATE_VERSION}.${JDK_BUILD_NUMBER:S/^0//}
+PORTREVISION= 1
CATEGORIES= java devel
MASTER_SITES= http://download.java.net/openjdk/jdk${JDK_MAJOR_VERSION}/promoted/b${DIST_BUILD_NUMBER}/:jdk \
https://adopt-openjdk.ci.cloudbees.com/job/jtreg/${JTREG_JENKINS_BUILD}/artifact/:jtreg \
diff --git a/java/openjdk8/files/patch-hotspot_src_os_bsd_vm_os__bsd.cpp b/java/openjdk8/files/patch-hotspot_src_os_bsd_vm_os__bsd.cpp
new file mode 100644
index 000000000000..1e1161249e33
--- /dev/null
+++ b/java/openjdk8/files/patch-hotspot_src_os_bsd_vm_os__bsd.cpp
@@ -0,0 +1,245 @@
+--- hotspot/src/os/bsd/vm/os_bsd.cpp.orig 2017-04-12 17:03:59 UTC
++++ hotspot/src/os/bsd/vm/os_bsd.cpp
+@@ -155,6 +155,7 @@ int (*os::Bsd::_getcpuclockid)(pthread_t
+ #endif
+ pthread_t os::Bsd::_main_thread;
+ int os::Bsd::_page_size = -1;
++pthread_condattr_t os::Bsd::_condattr[1];
+
+ static jlong initial_time_count=0;
+
+@@ -1076,12 +1077,15 @@ void os::Bsd::clock_init() {
+ void os::Bsd::clock_init() {
+ struct timespec res;
+ struct timespec tp;
++ _getcpuclockid = (int (*)(pthread_t, clockid_t *))dlsym(RTLD_DEFAULT, "pthread_getcpuclockid");
+ if (::clock_getres(CLOCK_MONOTONIC, &res) == 0 &&
+ ::clock_gettime(CLOCK_MONOTONIC, &tp) == 0) {
+ // yes, monotonic clock is supported
+ _clock_gettime = ::clock_gettime;
++ return;
+ }
+- _getcpuclockid = (int (*)(pthread_t, clockid_t *))dlsym(RTLD_DEFAULT, "pthread_getcpuclockid");
++ warning("No monotonic clock was available - timed services may " \
++ "be adversely affected if the time-of-day clock changes");
+ }
+ #endif
+
+@@ -1117,7 +1121,7 @@ jlong os::javaTimeNanos() {
+ 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;
+@@ -3721,6 +3725,25 @@ void os::init(void) {
+ Bsd::clock_init();
+ initial_time_count = javaTimeNanos();
+
++ // 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
+@@ -4483,21 +4506,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;
+ }
+
+@@ -4589,7 +4627,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,
+@@ -4690,32 +4728,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
+@@ -4795,15 +4851,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");
+@@ -4832,17 +4892,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") ;
diff --git a/java/openjdk8/files/patch-hotspot_src_os_bsd_vm_os__bsd.hpp b/java/openjdk8/files/patch-hotspot_src_os_bsd_vm_os__bsd.hpp
new file mode 100644
index 000000000000..44bd21a99193
--- /dev/null
+++ b/java/openjdk8/files/patch-hotspot_src_os_bsd_vm_os__bsd.hpp
@@ -0,0 +1,63 @@
+--- hotspot/src/os/bsd/vm/os_bsd.hpp.orig 2017-04-12 15:33:50 UTC
++++ hotspot/src/os/bsd/vm/os_bsd.hpp
+@@ -155,6 +155,13 @@ class Bsd {
+ #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
+@@ -220,7 +227,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");
+@@ -235,14 +242,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") ; }
+@@ -250,10 +262,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
+ }
+ };
+