--- old/make/solaris/makefiles/vm.make 2015-06-15 21:33:23.156083916 +0200 +++ new/make/solaris/makefiles/vm.make 2015-06-15 21:33:23.032079751 +0200 @@ -143,7 +143,7 @@ LIBS += -lsocket -lsched -ldl $(LIBM) -lthread -lc -ldemangle endif # sparcWorks -LIBS += -lkstat +LIBS += -lkstat -lrt # By default, link the *.o into the library, not the executable. LINK_INTO$(LINK_INTO) = LIBJVM --- old/src/os/bsd/vm/os_bsd.cpp 2015-06-15 21:33:23.416092651 +0200 +++ new/src/os/bsd/vm/os_bsd.cpp 2015-06-15 21:33:23.268087679 +0200 @@ -1953,6 +1953,9 @@ #define SEM_DESTROY(sem) sem_destroy(&sem) #endif +#ifdef __APPLE__ +// OS X doesn't support unamed POSIX semaphores, so the implementation in os_posix.cpp can't be used. + Semaphore::Semaphore(uint value, uint max) : _semaphore(0) { SEM_INIT(_semaphore, value); } @@ -1972,84 +1975,79 @@ } void Semaphore::wait() { -#ifdef __APPLE__ while (SEM_WAIT(_semaphore) == KERN_ABORTED) { -#else - while (SEM_WAIT(_semaphore) == -1 && errno == EINTR) { -#endif // Semaphore was interrupted. Retry. } } -static jlong semaphore_currenttime() { - struct timeval tv; - gettimeofday(&tv, NULL); - return (tv.tv_sec * NANOSECS_PER_SEC) + (tv.tv_usec * 1000); -} +class BsdSemaphore : public Semaphore { + private: + static jlong currenttime() { + struct timeval tv; + gettimeofday(&tv, NULL); + return (tv.tv_sec * NANOSECS_PER_SEC) + (tv.tv_usec * 1000); + } -#ifdef __APPLE__ -bool Semaphore::trywait() { - return timedwait(0, 0); -} + public: + BsdSemaphore(uint value = 0) : Semaphore(value) {} -bool Semaphore::timedwait(unsigned int sec, int nsec) { - kern_return_t kr = KERN_ABORTED; - mach_timespec_t waitspec; - waitspec.tv_sec = sec; - waitspec.tv_nsec = nsec; - - jlong starttime = semaphore_currenttime(); - - kr = semaphore_timedwait(_semaphore, waitspec); - while (kr == KERN_ABORTED) { - jlong totalwait = (sec * NANOSECS_PER_SEC) + nsec; - - jlong current = semaphore_currenttime(); - jlong passedtime = current - starttime; - - if (passedtime >= totalwait) { - waitspec.tv_sec = 0; - waitspec.tv_nsec = 0; - } else { - jlong waittime = totalwait - (current - starttime); - waitspec.tv_sec = waittime / NANOSECS_PER_SEC; - waitspec.tv_nsec = waittime % NANOSECS_PER_SEC; - } + bool trywait() { + return timedwait(0, 0); + } + + bool timedwait(unsigned int sec, int nsec) { + kern_return_t kr = KERN_ABORTED; + mach_timespec_t waitspec; + waitspec.tv_sec = sec; + waitspec.tv_nsec = nsec; + + jlong starttime = currenttime(); kr = semaphore_timedwait(_semaphore, waitspec); - } + while (kr == KERN_ABORTED) { + jlong totalwait = (sec * NANOSECS_PER_SEC) + nsec; - return kr == KERN_SUCCESS; -} + jlong current = currenttime(); + jlong passedtime = current - starttime; + + if (passedtime >= totalwait) { + waitspec.tv_sec = 0; + waitspec.tv_nsec = 0; + } else { + jlong waittime = totalwait - (current - starttime); + waitspec.tv_sec = waittime / NANOSECS_PER_SEC; + waitspec.tv_nsec = waittime % NANOSECS_PER_SEC; + } + + kr = semaphore_timedwait(_semaphore, waitspec); + } + + return kr == KERN_SUCCESS; + } +}; #else -bool Semaphore::trywait() { - return sem_trywait(&_semaphore) == 0; -} +class BsdSemaphore : public os::PosixSemaphore { + public: + BsdSemaphore(uint value = 0) : os::PosixSemaphore(value) {} -bool Semaphore::timedwait(unsigned int sec, int nsec) { - struct timespec ts; - unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec); - - while (1) { - int result = sem_timedwait(&_semaphore, &ts); - if (result == 0) { - return true; - } else if (errno == EINTR) { - continue; - } else if (errno == ETIMEDOUT) { - return false; - } else { - return false; - } + bool BsdSemaphore::trywait() { + return sem_trywait(&_semaphore) == 0; } -} + + bool BsdSemaphore::timedwait(unsigned int sec, int nsec) { + struct timespec ts; + unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec); + + return os::PosixSemaphore::timedwait(ts); + } +}; #endif // __APPLE__ static os_semaphore_t sig_sem; -static Semaphore sr_semaphore; +static BsdSemaphore sr_semaphore; void os::signal_init_pd() { // Initialize signal structures --- old/src/os/linux/vm/os_linux.cpp 2015-06-15 21:33:23.768104475 +0200 +++ new/src/os/linux/vm/os_linux.cpp 2015-06-15 21:33:23.616099369 +0200 @@ -69,7 +69,6 @@ #include "utilities/elfFile.hpp" #include "utilities/growableArray.hpp" #include "utilities/macros.hpp" -#include "utilities/semaphore.hpp" #include "utilities/vmError.hpp" // put OS-includes here @@ -2394,70 +2393,30 @@ return CAST_FROM_FN_PTR(void*, UserHandler); } -Semaphore::Semaphore(uint value, uint max) { - guarantee(value <= max, "value lower than max"); - guarantee(max == Semaphore::NoMaxCount || max <= SEM_VALUE_MAX, "Max value set too high"); - - int ret = sem_init(&_semaphore, 0, value); - guarantee(ret == 0, "Failed to initialize semaphore"); -} - -Semaphore::~Semaphore() { - sem_destroy(&_semaphore); -} - -void Semaphore::signal() { - int ret = sem_post(&_semaphore); - guarantee(ret == 0, err_msg("sem_post failed: %d", ret)); -} - -void Semaphore::signal(uint count) { - for (uint i = 0; i < count; i++) { - signal(); - } -} - -void Semaphore::wait() { - while (sem_wait(&_semaphore) == -1 && errno == EINTR) { - // Retry if the wait was interrupted by a signal. - } -} - -bool Semaphore::trywait() { - return sem_trywait(&_semaphore) == 0; -} - -bool Semaphore::timedwait(unsigned int sec, int nsec) { - - struct timespec ts; - // Semaphore's are always associated with CLOCK_REALTIME - os::Linux::clock_gettime(CLOCK_REALTIME, &ts); - // see unpackTime for discussion on overflow checking - if (sec >= MAX_SECS) { - ts.tv_sec += MAX_SECS; - ts.tv_nsec = 0; - } else { - ts.tv_sec += sec; - ts.tv_nsec += nsec; - if (ts.tv_nsec >= NANOSECS_PER_SEC) { - ts.tv_nsec -= NANOSECS_PER_SEC; - ++ts.tv_sec; // note: this must be <= max_secs - } - } +class LinuxSemaphore : public os::PosixSemaphore { + public: + LinuxSemaphore(uint value = 0) : os::PosixSemaphore(value) {} - while (1) { - int result = sem_timedwait(&_semaphore, &ts); - if (result == 0) { - return true; - } else if (errno == EINTR) { - continue; - } else if (errno == ETIMEDOUT) { - return false; + bool timedwait(unsigned int sec, int nsec) { + struct timespec ts; + // Semaphore's are always associated with CLOCK_REALTIME + os::Linux::clock_gettime(CLOCK_REALTIME, &ts); + // see unpackTime for discussion on overflow checking + if (sec >= MAX_SECS) { + ts.tv_sec += MAX_SECS; + ts.tv_nsec = 0; } else { - return false; + ts.tv_sec += sec; + ts.tv_nsec += nsec; + if (ts.tv_nsec >= NANOSECS_PER_SEC) { + ts.tv_nsec -= NANOSECS_PER_SEC; + ++ts.tv_sec; // note: this must be <= max_secs + } } + + return os::PosixSemaphore::timedwait(ts); } -} +}; extern "C" { typedef void (*sa_handler_t)(int); @@ -2496,7 +2455,7 @@ // Linux(POSIX) specific hand shaking semaphore. static sem_t sig_sem; -static Semaphore sr_semaphore; +static LinuxSemaphore sr_semaphore; void os::signal_init_pd() { // Initialize signal structures --- old/src/os/posix/vm/os_posix.cpp 2015-06-15 21:33:24.128116568 +0200 +++ new/src/os/posix/vm/os_posix.cpp 2015-06-15 21:33:23.992112000 +0200 @@ -1015,3 +1015,61 @@ } } } + +#define assert_with_errno(cond, msg) \ + do { \ + int err = errno; \ + assert(cond, err_msg("%s; error='%s' (errno=%d)", msg, strerror(err), err)); \ +} while (false) + +// POSIX unamed semaphores are not supported on OS X. +#ifndef __APPLE__ + +Semaphore::Semaphore(uint value, uint /* max */) { + int ret = sem_init(&_semaphore, 0, value); + + assert_with_errno(ret == 0, "Failed to initialize semaphore"); +} + +Semaphore::~Semaphore() { + sem_destroy(&_semaphore); +} + +void Semaphore::signal() { + int ret = sem_post(&_semaphore); + + assert_with_errno(ret == 0, "sem_post failed"); +} + +void Semaphore::signal(uint count) { + for (uint i = 0; i < count; i++) { + signal(); + } +} + +void Semaphore::wait() { + while (sem_wait(&_semaphore) == -1 && errno == EINTR) { + // Retry if the wait was interrupted by a signal. + } +} + +bool os::PosixSemaphore::trywait() { + return sem_trywait(&_semaphore) == 0; +} + +bool os::PosixSemaphore::timedwait(const struct timespec ts) { + while (1) { + int result = sem_timedwait(&_semaphore, &ts); + if (result == 0) { + return true; + } else if (errno == EINTR) { + continue; + } else if (errno == ETIMEDOUT) { + return false; + } else { + return false; + } + } +} + +#endif // __APPLE__ --- old/src/os/posix/vm/os_posix.hpp 2015-06-15 21:33:24.396125571 +0200 +++ new/src/os/posix/vm/os_posix.hpp 2015-06-15 21:33:24.248120600 +0200 @@ -89,4 +89,12 @@ sigjmp_buf _jmpbuf; }; +class PosixSemaphore : public Semaphore { + public: + PosixSemaphore(uint value = 0) : Semaphore(value) {} + + bool trywait(); + bool timedwait(struct timespec ts); +}; + #endif // OS_POSIX_VM_OS_POSIX_HPP --- old/src/os/solaris/vm/os_solaris.cpp 2015-06-15 21:33:24.652134171 +0200 +++ new/src/os/solaris/vm/os_solaris.cpp 2015-06-15 21:33:24.500129064 +0200 @@ -67,7 +67,6 @@ #include "utilities/defaultStream.hpp" #include "utilities/events.hpp" #include "utilities/growableArray.hpp" -#include "utilities/semaphore.hpp" #include "utilities/vmError.hpp" // put OS-includes here @@ -2267,68 +2266,17 @@ return CAST_FROM_FN_PTR(void*, UserHandler); } -static int sem_max_value = -1; +class SolarisSemaphore : public os::PosixSemaphore { + public: + SolarisSemaphore(uint value = 0) : os::PosixSemaphore(value) {} + + bool timedwait(unsigned int sec, int nsec) { + struct timespec ts; + unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec); -Semaphore::Semaphore(uint value, uint max) { - guarantee(value <= max, "value lower than max"); - - static long sem_value_max = sysconf(_SC_SEM_VALUE_MAX); - guarantee(max == Semaphore::NoMaxCount || value <= sem_max_value, - err_msg("Max value: %u set higher than SEM_VALUE_MAX: %l", sem_value_max)); - - int ret = sema_init(&_semaphore, value, NULL, NULL); - - guarantee(ret == 0, "Failed to initialize semaphore"); -} - -Semaphore::~Semaphore() { - sema_destroy(&_semaphore); -} - -void Semaphore::signal() { - int ret = sema_post(&_semaphore); - - assert(ret == 0, err_msg("Semaphore signal failed: %d", errno)); -} - -void Semaphore::signal(uint count) { - for (uint i = 0; i < count; i++) { - signal(); - } -} - -void Semaphore::wait() { - int ret; - - do { - ret = sema_wait(&_semaphore); - // Retry if the wait was interrupted by a signal. - } while (errno == EINTR); - - assert(ret == 0, err_msg("Semaphore wait failed: %d", errno)); -} - -bool Semaphore::trywait() { - return sema_trywait(&_semaphore) == 0; -} - -bool Semaphore::timedwait(unsigned int sec, int nsec) { - struct timespec ts; - unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec); - - while (1) { - int result = sema_timedwait(&_semaphore, &ts); - if (result == 0) { - return true; - } else if (errno == EINTR) { - continue; - } else if (errno == ETIME) { - return false; - } else { - return false; - } + return os::PosixSemaphore::timedwait(ts); } -} +}; extern "C" { typedef void (*sa_handler_t)(int); @@ -3727,7 +3675,7 @@ osthread->set_ucontext(context); } -static Semaphore sr_semaphore; +static SolarisSemaphore sr_semaphore; void os::Solaris::SR_handler(Thread* thread, ucontext_t* uc) { // Save and restore errno to avoid confusing native code with EINTR --- old/src/os/windows/vm/os_windows.cpp 2015-06-15 21:33:25.036147070 +0200 +++ new/src/os/windows/vm/os_windows.cpp 2015-06-15 21:33:24.872141561 +0200 @@ -1899,7 +1899,7 @@ Semaphore::Semaphore(uint value, uint max) { _semaphore = ::CreateSemaphore(NULL, value, max, NULL); - guarantee(_semaphore != NULL, err_msg("CreateSemaphore failed: %ld", GetLastError())); + assert(_semaphore != NULL, err_msg("CreateSemaphore failed: %ld", GetLastError())); } Semaphore::~Semaphore() { @@ -1911,7 +1911,7 @@ void Semaphore::signal(uint count) { BOOL ret = ::ReleaseSemaphore(_semaphore, count, NULL); - guarantee(ret != 0, err_msg("ReleaseSemaphore failed: %d", GetLastError())); + assert(ret != 0, err_msg("ReleaseSemaphore failed: %d", GetLastError())); } void Semaphore::signal() { @@ -1920,17 +1920,7 @@ void Semaphore::wait() { DWORD ret = ::WaitForSingleObject(_semaphore, INFINITE); - guarantee(ret == WAIT_OBJECT_0, err_msg("WaitForSingleObject failed: %d", GetLastError())); -} - -bool Semaphore::trywait() { - Unimplemented(); - return false; -} - -bool Semaphore::timedwait(unsigned int sec, int nsec) { - Unimplemented(); - return false; + assert(ret == WAIT_OBJECT_0, err_msg("WaitForSingleObject failed: %d", GetLastError())); } // sun.misc.Signal --- old/src/share/vm/runtime/os.hpp 2015-06-15 21:33:25.376158492 +0200 +++ new/src/share/vm/runtime/os.hpp 2015-06-15 21:33:25.236153789 +0200 @@ -28,6 +28,7 @@ #include "jvmtifiles/jvmti.h" #include "runtime/extendedPC.hpp" #include "runtime/handles.hpp" +#include "utilities/semaphore.hpp" #include "utilities/top.hpp" #ifdef TARGET_OS_FAMILY_linux # include "jvm_linux.h" --- old/src/share/vm/utilities/semaphore.cpp 2015-06-15 21:33:25.616166554 +0200 +++ new/src/share/vm/utilities/semaphore.cpp 2015-06-15 21:33:25.488162255 +0200 @@ -30,7 +30,6 @@ #ifndef PRODUCT -#if IMPLEMENTS_SEMAPHORE_CLASS static void test_semaphore_single_with_max_once(uint max) { assert(max > 0, "precondition"); @@ -129,9 +128,5 @@ test_semaphore_many(); } -#else // IMPLEMENTS_SEMAPHORE_CLASS -void test_semaphore() {} -#endif - #endif // PRODUCT --- old/src/share/vm/utilities/semaphore.hpp 2015-06-15 21:33:25.864174885 +0200 +++ new/src/share/vm/utilities/semaphore.hpp 2015-06-15 21:33:25.720170048 +0200 @@ -28,39 +28,35 @@ #include "memory/allocation.hpp" #include "utilities/globalDefinitions.hpp" -#define IMPLEMENTS_SEMAPHORE_CLASS 1 - -#if defined(TARGET_OS_FAMILY_bsd) +#if defined(TARGET_OS_FAMILY_linux) || defined(TARGET_OS_FAMILY_solaris) || defined(TARGET_OS_FAMILY_aix) +# include "semaphore_posix.hpp" +#elif defined(TARGET_OS_FAMILY_bsd) # include "semaphore_bsd.hpp" -#elif defined(TARGET_OS_FAMILY_linux) -# include "semaphore_linux.hpp" -#elif defined(TARGET_OS_FAMILY_solaris) -# include "semaphore_solaris.hpp" #elif defined(TARGET_OS_FAMILY_windows) # include "semaphore_windows.hpp" #else - // Redefine for platforms that don't implement the Semaphore class. -# undef IMPLEMENTS_SEMAPHORE_CLASS -# define IMPLEMENTS_SEMAPHORE_CLASS 0 +# error "No semaphore implementation provided for this OS" #endif -#if IMPLEMENTS_SEMAPHORE_CLASS - class Semaphore : public CHeapObj { + private: + // Prevent copying and assignment of Semaphore instances. + Semaphore(const Semaphore &); + Semaphore& operator=(const Semaphore&); + + protected: + os_semaphore_t _semaphore; + public: static const uint NoMaxCount = (uint)-1; Semaphore(uint value = 0, uint max = NoMaxCount); - ~Semaphore(); + virtual ~Semaphore(); + void signal(); void signal(uint count); + void wait(); - bool trywait(); - bool timedwait(unsigned int sec, int nsec); - private: - os_semaphore_t _semaphore; }; -#endif - #endif // SHARE_VM_UTILITIES_SEMAPHORE_HPP --- /dev/null 2015-05-29 12:41:18.476004839 +0200 +++ new/src/os/posix/vm/semaphore_posix.hpp 2015-06-15 21:33:25.964178245 +0200 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_POSIX_VM_SEMAPHORE_POSIX_HPP +#define OS_POSIX_VM_SEMAPHORE_POSIX_HPP + +#include + +typedef sem_t os_semaphore_t; + +#endif // OS_POSIX_VM_SEMAPHORE_POSIX_HPP --- old/src/os/linux/vm/semaphore_linux.hpp 2015-06-15 21:33:26.320190203 +0200 +++ /dev/null 2015-05-29 12:41:18.476004839 +0200 @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef OS_LINUX_VM_SEMAPHORE_LINUX_HPP -#define OS_LINUX_VM_SEMAPHORE_LINUX_HPP - -#include - -typedef sem_t os_semaphore_t; - -#endif // OS_LINUX_VM_SEMAPHORE_LINUX_HPP --- old/src/os/solaris/vm/semaphore_solaris.hpp 2015-06-15 21:33:26.520196921 +0200 +++ /dev/null 2015-05-29 12:41:18.476004839 +0200 @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef OS_SOLARIS_VM_SEMAPHORE_SOLARIS_HPP -#define OS_SOLARIS_VM_SEMAPHORE_SOLARIS_HPP - -#include - -typedef sema_t os_semaphore_t; - -#endif // OS_SOLARIS_VM_SEMAPHORE_SOLARIS_HPP