# HG changeset patch # User coleenp # Date 1515714156 18000 # Node ID 612dfa1d8aad904f52bac34921fbf6e07e22b7e5 # Parent 2569f227ae8e6c80cd9ee57afba58bafaddcd095 8130039: Move the platform-specific [OS]Semaphore code 8130038: Unify the semaphore usage in os_xxx.cpp 8194763: os::signal_lookup is unused Reviewed-by: dholmes, kbarrett diff -r 2569f227ae8e -r 612dfa1d8aad src/hotspot/os/aix/os_aix.cpp --- a/src/hotspot/os/aix/os_aix.cpp Thu Jan 11 11:28:51 2018 +0100 +++ b/src/hotspot/os/aix/os_aix.cpp Thu Jan 11 18:42:36 2018 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2017 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -1723,7 +1723,7 @@ local_sem_post(); } -static int check_pending_signals(bool wait) { +static int check_pending_signals() { Atomic::store(0, &sigint_count); for (;;) { for (int i = 0; i < NSIG + 1; i++) { @@ -1732,9 +1732,6 @@ return i; } } - if (!wait) { - return -1; - } JavaThread *thread = JavaThread::current(); ThreadBlockInVM tbivm(thread); @@ -1763,12 +1760,8 @@ } } -int os::signal_lookup() { - return check_pending_signals(false); -} - int os::signal_wait() { - return check_pending_signals(true); + return check_pending_signals(); } //////////////////////////////////////////////////////////////////////////////// diff -r 2569f227ae8e -r 612dfa1d8aad src/hotspot/os/bsd/os_bsd.cpp --- a/src/hotspot/os/bsd/os_bsd.cpp Thu Jan 11 11:28:51 2018 +0100 +++ b/src/hotspot/os/bsd/os_bsd.cpp Thu Jan 11 18:42:36 2018 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2018, 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 @@ -52,13 +52,13 @@ #include "runtime/orderAccess.inline.hpp" #include "runtime/osThread.hpp" #include "runtime/perfMemory.hpp" +#include "runtime/semaphore.hpp" #include "runtime/sharedRuntime.hpp" #include "runtime/statSampler.hpp" #include "runtime/stubRoutines.hpp" #include "runtime/thread.inline.hpp" #include "runtime/threadCritical.hpp" #include "runtime/timer.hpp" -#include "semaphore_bsd.hpp" #include "services/attachListener.hpp" #include "services/memTracker.hpp" #include "services/runtimeService.hpp" @@ -91,7 +91,6 @@ # include # include # include -# include # include # include # include @@ -1829,135 +1828,28 @@ // a counter for each possible signal value static volatile jint pending_signals[NSIG+1] = { 0 }; - -// Bsd(POSIX) specific hand shaking semaphore. -#ifdef __APPLE__ -typedef semaphore_t os_semaphore_t; - - #define SEM_INIT(sem, value) semaphore_create(mach_task_self(), &sem, SYNC_POLICY_FIFO, value) - #define SEM_WAIT(sem) semaphore_wait(sem) - #define SEM_POST(sem) semaphore_signal(sem) - #define SEM_DESTROY(sem) semaphore_destroy(mach_task_self(), sem) -#else -typedef sem_t os_semaphore_t; - - #define SEM_INIT(sem, value) sem_init(&sem, 0, value) - #define SEM_WAIT(sem) sem_wait(&sem) - #define SEM_POST(sem) sem_post(&sem) - #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. - -static const char* sem_init_strerror(kern_return_t value) { - switch (value) { - case KERN_INVALID_ARGUMENT: return "Invalid argument"; - case KERN_RESOURCE_SHORTAGE: return "Resource shortage"; - default: return "Unknown"; - } -} - -OSXSemaphore::OSXSemaphore(uint value) { - kern_return_t ret = SEM_INIT(_semaphore, value); - - guarantee(ret == KERN_SUCCESS, "Failed to create semaphore: %s", sem_init_strerror(ret)); -} - -OSXSemaphore::~OSXSemaphore() { - SEM_DESTROY(_semaphore); -} - -void OSXSemaphore::signal(uint count) { - for (uint i = 0; i < count; i++) { - kern_return_t ret = SEM_POST(_semaphore); - - assert(ret == KERN_SUCCESS, "Failed to signal semaphore"); - } -} - -void OSXSemaphore::wait() { - kern_return_t ret; - while ((ret = SEM_WAIT(_semaphore)) == KERN_ABORTED) { - // Semaphore was interrupted. Retry. - } - assert(ret == KERN_SUCCESS, "Failed to wait on semaphore"); -} - -jlong OSXSemaphore::currenttime() { - struct timeval tv; - gettimeofday(&tv, NULL); - return (tv.tv_sec * NANOSECS_PER_SEC) + (tv.tv_usec * 1000); -} - -bool OSXSemaphore::trywait() { - return timedwait(0, 0); -} - -bool OSXSemaphore::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; - - 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 -// Use POSIX implementation of semaphores. - -struct timespec PosixSemaphore::create_timespec(unsigned int sec, int nsec) { - struct timespec ts; - unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec); - - return ts; -} - -#endif // __APPLE__ - -static os_semaphore_t sig_sem; - -#ifdef __APPLE__ -static OSXSemaphore sr_semaphore; -#else -static PosixSemaphore sr_semaphore; -#endif +static Semaphore* sig_sem = NULL; void os::signal_init_pd() { // Initialize signal structures ::memset((void*)pending_signals, 0, sizeof(pending_signals)); // Initialize signal semaphore - ::SEM_INIT(sig_sem, 0); + sig_sem = new Semaphore(); } void os::signal_notify(int sig) { - Atomic::inc(&pending_signals[sig]); - ::SEM_POST(sig_sem); + if (sig_sem != NULL) { + Atomic::inc(&pending_signals[sig]); + sig_sem->signal(); + } else { + // Signal thread is not created with ReduceSignalUsage and signal_init_pd + // initialization isn't called. + assert(ReduceSignalUsage, "signal semaphore should be created"); + } } -static int check_pending_signals(bool wait) { +static int check_pending_signals() { Atomic::store(0, &sigint_count); for (;;) { for (int i = 0; i < NSIG + 1; i++) { @@ -1966,9 +1858,6 @@ return i; } } - if (!wait) { - return -1; - } JavaThread *thread = JavaThread::current(); ThreadBlockInVM tbivm(thread); @@ -1976,7 +1865,7 @@ do { thread->set_suspend_equivalent(); // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self() - ::SEM_WAIT(sig_sem); + sig_sem->wait(); // were we externally suspended while we were waiting? threadIsSuspended = thread->handle_special_suspend_equivalent_condition(); @@ -1985,7 +1874,7 @@ // another thread suspended us. We don't want to continue running // while suspended because that would surprise the thread that // suspended us. - ::SEM_POST(sig_sem); + sig_sem->signal(); thread->java_suspend_self(); } @@ -1993,12 +1882,8 @@ } } -int os::signal_lookup() { - return check_pending_signals(false); -} - int os::signal_wait() { - return check_pending_signals(true); + return check_pending_signals(); } //////////////////////////////////////////////////////////////////////////////// @@ -2663,6 +2548,12 @@ // // Currently only ever called on the VMThread or JavaThread // +#ifdef __APPLE__ +static OSXSemaphore sr_semaphore; +#else +static PosixSemaphore sr_semaphore; +#endif + static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) { // Save and restore errno to avoid confusing native code with EINTR // after sigsuspend. diff -r 2569f227ae8e -r 612dfa1d8aad src/hotspot/os/bsd/semaphore_bsd.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hotspot/os/bsd/semaphore_bsd.cpp Thu Jan 11 18:42:36 2018 -0500 @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2018, 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. + * + */ + +#include "precompiled/precompiled.hpp" +#include "semaphore_bsd.hpp" +#include "utilities/debug.hpp" + +#include + +#ifdef __APPLE__ +// OS X doesn't support unamed POSIX semaphores, so the implementation in os_posix.cpp can't be used. + +static const char* sem_init_strerror(kern_return_t value) { + switch (value) { + case KERN_INVALID_ARGUMENT: return "Invalid argument"; + case KERN_RESOURCE_SHORTAGE: return "Resource shortage"; + default: return "Unknown"; + } +} + +OSXSemaphore::OSXSemaphore(uint value) { + kern_return_t ret = semaphore_create(mach_task_self(), &_semaphore, SYNC_POLICY_FIFO, value); + + guarantee(ret == KERN_SUCCESS, "Failed to create semaphore: %s", sem_init_strerror(ret)); +} + +OSXSemaphore::~OSXSemaphore() { + semaphore_destroy(mach_task_self(), _semaphore); +} + +void OSXSemaphore::signal(uint count) { + for (uint i = 0; i < count; i++) { + kern_return_t ret = semaphore_signal(_semaphore); + + assert(ret == KERN_SUCCESS, "Failed to signal semaphore"); + } +} + +void OSXSemaphore::wait() { + kern_return_t ret; + while ((ret = semaphore_wait(_semaphore)) == KERN_ABORTED) { + // Semaphore was interrupted. Retry. + } + assert(ret == KERN_SUCCESS, "Failed to wait on semaphore"); +} + +int64_t OSXSemaphore::currenttime() { + struct timeval tv; + gettimeofday(&tv, NULL); + return (tv.tv_sec * NANOSECS_PER_SEC) + (tv.tv_usec * 1000); +} + +bool OSXSemaphore::trywait() { + return timedwait(0, 0); +} + +bool OSXSemaphore::timedwait(unsigned int sec, int nsec) { + kern_return_t kr = KERN_ABORTED; + mach_timespec_t waitspec; + waitspec.tv_sec = sec; + waitspec.tv_nsec = nsec; + + int64_t starttime = currenttime(); + + kr = semaphore_timedwait(_semaphore, waitspec); + while (kr == KERN_ABORTED) { + int64_t totalwait = (sec * NANOSECS_PER_SEC) + nsec; + + int64_t current = currenttime(); + int64_t passedtime = current - starttime; + + if (passedtime >= totalwait) { + waitspec.tv_sec = 0; + waitspec.tv_nsec = 0; + } else { + int64_t 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; +} +#endif // __APPLE__ diff -r 2569f227ae8e -r 612dfa1d8aad src/hotspot/os/bsd/semaphore_bsd.hpp --- a/src/hotspot/os/bsd/semaphore_bsd.hpp Thu Jan 11 11:28:51 2018 +0100 +++ b/src/hotspot/os/bsd/semaphore_bsd.hpp Thu Jan 11 18:42:36 2018 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, 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 @@ -53,7 +53,7 @@ bool timedwait(unsigned int sec, int nsec); private: - static jlong currenttime(); + static int64_t currenttime(); }; typedef OSXSemaphore SemaphoreImpl; diff -r 2569f227ae8e -r 612dfa1d8aad src/hotspot/os/linux/os_linux.cpp --- a/src/hotspot/os/linux/os_linux.cpp Thu Jan 11 11:28:51 2018 +0100 +++ b/src/hotspot/os/linux/os_linux.cpp Thu Jan 11 18:42:36 2018 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2018, 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 @@ -95,7 +95,6 @@ # include # include # include -# include # include # include # include @@ -2479,11 +2478,11 @@ return CAST_FROM_FN_PTR(void*, UserHandler); } -struct timespec PosixSemaphore::create_timespec(unsigned int sec, int nsec) { +static struct timespec create_semaphore_timespec(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 + // see os_posix.cpp for discussion on overflow checking if (sec >= MAX_SECS) { ts.tv_sec += MAX_SECS; ts.tv_nsec = 0; @@ -2535,7 +2534,7 @@ static volatile jint pending_signals[NSIG+1] = { 0 }; // Linux(POSIX) specific hand shaking semaphore. -static sem_t sig_sem; +static Semaphore* sig_sem = NULL; static PosixSemaphore sr_semaphore; void os::signal_init_pd() { @@ -2543,15 +2542,21 @@ ::memset((void*)pending_signals, 0, sizeof(pending_signals)); // Initialize signal semaphore - ::sem_init(&sig_sem, 0, 0); + sig_sem = new Semaphore(); } void os::signal_notify(int sig) { - Atomic::inc(&pending_signals[sig]); - ::sem_post(&sig_sem); -} - -static int check_pending_signals(bool wait) { + if (sig_sem != NULL) { + Atomic::inc(&pending_signals[sig]); + sig_sem->signal(); + } else { + // Signal thread is not created with ReduceSignalUsage and signal_init_pd + // initialization isn't called. + assert(ReduceSignalUsage, "signal semaphore should be created"); + } +} + +static int check_pending_signals() { Atomic::store(0, &sigint_count); for (;;) { for (int i = 0; i < NSIG + 1; i++) { @@ -2560,9 +2565,6 @@ return i; } } - if (!wait) { - return -1; - } JavaThread *thread = JavaThread::current(); ThreadBlockInVM tbivm(thread); @@ -2570,7 +2572,7 @@ do { thread->set_suspend_equivalent(); // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self() - ::sem_wait(&sig_sem); + sig_sem->wait(); // were we externally suspended while we were waiting? threadIsSuspended = thread->handle_special_suspend_equivalent_condition(); @@ -2579,7 +2581,7 @@ // another thread suspended us. We don't want to continue running // while suspended because that would surprise the thread that // suspended us. - ::sem_post(&sig_sem); + sig_sem->signal(); thread->java_suspend_self(); } @@ -2587,12 +2589,8 @@ } } -int os::signal_lookup() { - return check_pending_signals(false); -} - int os::signal_wait() { - return check_pending_signals(true); + return check_pending_signals(); } //////////////////////////////////////////////////////////////////////////////// @@ -4317,7 +4315,7 @@ // managed to send the signal and switch to SUSPEND_REQUEST, now wait for SUSPENDED while (true) { - if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) { + if (sr_semaphore.timedwait(create_semaphore_timespec(0, 2 * NANOSECS_PER_MILLISEC))) { break; } else { // timeout @@ -4351,7 +4349,7 @@ while (true) { if (sr_notify(osthread) == 0) { - if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) { + if (sr_semaphore.timedwait(create_semaphore_timespec(0, 2 * NANOSECS_PER_MILLISEC))) { if (osthread->sr.is_running()) { return; } diff -r 2569f227ae8e -r 612dfa1d8aad src/hotspot/os/posix/os_posix.cpp --- a/src/hotspot/os/posix/os_posix.cpp Thu Jan 11 11:28:51 2018 +0100 +++ b/src/hotspot/os/posix/os_posix.cpp Thu Jan 11 18:42:36 2018 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2018, 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 @@ -31,14 +31,8 @@ #include "utilities/macros.hpp" #include "utilities/vmError.hpp" -#ifndef __APPLE__ -// POSIX unamed semaphores are not supported on OS X. -#include "semaphore_posix.hpp" -#endif - #include #include -#include #include #include #include @@ -1499,67 +1493,6 @@ } } -// POSIX unamed semaphores are not supported on OS X. -#ifndef __APPLE__ - -PosixSemaphore::PosixSemaphore(uint value) { - int ret = sem_init(&_semaphore, 0, value); - - guarantee_with_errno(ret == 0, "Failed to initialize semaphore"); -} - -PosixSemaphore::~PosixSemaphore() { - sem_destroy(&_semaphore); -} - -void PosixSemaphore::signal(uint count) { - for (uint i = 0; i < count; i++) { - int ret = sem_post(&_semaphore); - - assert_with_errno(ret == 0, "sem_post failed"); - } -} - -void PosixSemaphore::wait() { - int ret; - - do { - ret = sem_wait(&_semaphore); - } while (ret != 0 && errno == EINTR); - - assert_with_errno(ret == 0, "sem_wait failed"); -} - -bool PosixSemaphore::trywait() { - int ret; - - do { - ret = sem_trywait(&_semaphore); - } while (ret != 0 && errno == EINTR); - - assert_with_errno(ret == 0 || errno == EAGAIN, "trywait failed"); - - return ret == 0; -} - -bool PosixSemaphore::timedwait(struct timespec ts) { - while (true) { - int result = sem_timedwait(&_semaphore, &ts); - if (result == 0) { - return true; - } else if (errno == EINTR) { - continue; - } else if (errno == ETIMEDOUT) { - return false; - } else { - assert_with_errno(false, "timedwait failed"); - return false; - } - } -} - -#endif // __APPLE__ - // Shared pthread_mutex/cond based PlatformEvent implementation. // Not currently usable by Solaris. diff -r 2569f227ae8e -r 612dfa1d8aad src/hotspot/os/posix/semaphore_posix.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hotspot/os/posix/semaphore_posix.cpp Thu Jan 11 18:42:36 2018 -0500 @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2018, 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. + * + */ + +#include "precompiled/precompiled.hpp" +#ifndef __APPLE__ +#include "runtime/os.hpp" +// POSIX unamed semaphores are not supported on OS X. +#include "semaphore_posix.hpp" +#include + +#define check_with_errno(check_type, cond, msg) \ + do { \ + int err = errno; \ + check_type(cond, "%s; error='%s' (errno=%s)", msg, os::strerror(err), \ + os::errno_name(err)); \ +} while (false) + +#define assert_with_errno(cond, msg) check_with_errno(assert, cond, msg) +#define guarantee_with_errno(cond, msg) check_with_errno(guarantee, cond, msg) + +PosixSemaphore::PosixSemaphore(uint value) { + int ret = sem_init(&_semaphore, 0, value); + + guarantee_with_errno(ret == 0, "Failed to initialize semaphore"); +} + +PosixSemaphore::~PosixSemaphore() { + sem_destroy(&_semaphore); +} + +void PosixSemaphore::signal(uint count) { + for (uint i = 0; i < count; i++) { + int ret = sem_post(&_semaphore); + + assert_with_errno(ret == 0, "sem_post failed"); + } +} + +void PosixSemaphore::wait() { + int ret; + + do { + ret = sem_wait(&_semaphore); + } while (ret != 0 && errno == EINTR); + + assert_with_errno(ret == 0, "sem_wait failed"); +} + +bool PosixSemaphore::trywait() { + int ret; + + do { + ret = sem_trywait(&_semaphore); + } while (ret != 0 && errno == EINTR); + + assert_with_errno(ret == 0 || errno == EAGAIN, "trywait failed"); + + return ret == 0; +} + +bool PosixSemaphore::timedwait(struct timespec ts) { + while (true) { + int result = sem_timedwait(&_semaphore, &ts); + if (result == 0) { + return true; + } else if (errno == EINTR) { + continue; + } else if (errno == ETIMEDOUT) { + return false; + } else { + assert_with_errno(false, "timedwait failed"); + return false; + } + } +} +#endif // __APPLE__ + diff -r 2569f227ae8e -r 612dfa1d8aad src/hotspot/os/posix/semaphore_posix.hpp --- a/src/hotspot/os/posix/semaphore_posix.hpp Thu Jan 11 11:28:51 2018 +0100 +++ b/src/hotspot/os/posix/semaphore_posix.hpp Thu Jan 11 18:42:36 2018 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, 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 @@ -45,15 +45,7 @@ void wait(); bool trywait(); - bool timedwait(unsigned int sec, int nsec) { - return timedwait(create_timespec(sec, nsec)); - } - - private: bool timedwait(struct timespec ts); - - // OS specific implementation to create a timespec suitable for semaphores. - struct timespec create_timespec(unsigned int set, int nsec); }; typedef PosixSemaphore SemaphoreImpl; diff -r 2569f227ae8e -r 612dfa1d8aad src/hotspot/os/solaris/os_solaris.cpp --- a/src/hotspot/os/solaris/os_solaris.cpp Thu Jan 11 11:28:51 2018 +0100 +++ b/src/hotspot/os/solaris/os_solaris.cpp Thu Jan 11 18:42:36 2018 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2018, 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 @@ -2062,7 +2062,7 @@ return CAST_FROM_FN_PTR(void*, UserHandler); } -struct timespec PosixSemaphore::create_timespec(unsigned int sec, int nsec) { +static struct timespec create_semaphore_timespec(unsigned int sec, int nsec) { struct timespec ts; unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec); @@ -2100,7 +2100,7 @@ static jint *pending_signals = NULL; static int *preinstalled_sigs = NULL; static struct sigaction *chainedsigactions = NULL; -static sema_t sig_sem; +static Semaphore* sig_sem = NULL; typedef int (*version_getting_t)(); version_getting_t os::Solaris::get_libjsig_version = NULL; @@ -2115,6 +2115,7 @@ Sigexit = Maxsignum+1; assert(Maxsignum >0, "Unable to obtain max signal number"); + // Initialize signal structures // pending_signals has one int per signal // The additional signal is for SIGEXIT - exit signal to signal_thread pending_signals = (jint *)os::malloc(sizeof(jint) * (Sigexit+1), mtInternal); @@ -2132,21 +2133,22 @@ } void os::signal_init_pd() { - int ret; - - ret = ::sema_init(&sig_sem, 0, NULL, NULL); - assert(ret == 0, "sema_init() failed"); -} - -void os::signal_notify(int signal_number) { - int ret; - - Atomic::inc(&pending_signals[signal_number]); - ret = ::sema_post(&sig_sem); - assert(ret == 0, "sema_post() failed"); -} - -static int check_pending_signals(bool wait_for_signal) { + // Initialize signal semaphore + sig_sem = new Semaphore(); +} + +void os::signal_notify(int sig) { + if (sig_sem != NULL) { + Atomic::inc(&pending_signals[sig]); + sig_sem->signal(); + } else { + // Signal thread is not created with ReduceSignalUsage and signal_init_pd + // initialization isn't called. + assert(ReduceSignalUsage, "signal semaphore should be created"); + } +} + +static int check_pending_signals() { int ret; while (true) { for (int i = 0; i < Sigexit + 1; i++) { @@ -2155,19 +2157,13 @@ return i; } } - if (!wait_for_signal) { - return -1; - } JavaThread *thread = JavaThread::current(); ThreadBlockInVM tbivm(thread); bool threadIsSuspended; do { thread->set_suspend_equivalent(); - // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self() - while ((ret = ::sema_wait(&sig_sem)) == EINTR) - ; - assert(ret == 0, "sema_wait() failed"); + sig_sem->wait(); // were we externally suspended while we were waiting? threadIsSuspended = thread->handle_special_suspend_equivalent_condition(); @@ -2176,8 +2172,7 @@ // another thread suspended us. We don't want to continue running // while suspended because that would surprise the thread that // suspended us. - ret = ::sema_post(&sig_sem); - assert(ret == 0, "sema_post() failed"); + sig_sem->signal(); thread->java_suspend_self(); } @@ -2185,12 +2180,8 @@ } } -int os::signal_lookup() { - return check_pending_signals(false); -} - int os::signal_wait() { - return check_pending_signals(true); + return check_pending_signals(); } //////////////////////////////////////////////////////////////////////////////// @@ -3599,7 +3590,7 @@ // managed to send the signal and switch to SUSPEND_REQUEST, now wait for SUSPENDED while (true) { - if (sr_semaphore.timedwait(0, 2000 * NANOSECS_PER_MILLISEC)) { + if (sr_semaphore.timedwait(create_semaphore_timespec(0, 2000 * NANOSECS_PER_MILLISEC))) { break; } else { // timeout @@ -3633,7 +3624,7 @@ while (true) { if (sr_notify(osthread) == 0) { - if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) { + if (sr_semaphore.timedwait(create_semaphore_timespec(0, 2 * NANOSECS_PER_MILLISEC))) { if (osthread->sr.is_running()) { return; } diff -r 2569f227ae8e -r 612dfa1d8aad src/hotspot/os/windows/os_windows.cpp --- a/src/hotspot/os/windows/os_windows.cpp Thu Jan 11 11:28:51 2018 +0100 +++ b/src/hotspot/os/windows/os_windows.cpp Thu Jan 11 18:42:36 2018 -0500 @@ -62,7 +62,6 @@ #include "runtime/threadCritical.hpp" #include "runtime/timer.hpp" #include "runtime/vm_version.hpp" -#include "semaphore_windows.hpp" #include "services/attachListener.hpp" #include "services/memTracker.hpp" #include "services/runtimeService.hpp" @@ -1845,36 +1844,6 @@ return (int)error; } -WindowsSemaphore::WindowsSemaphore(uint value) { - _semaphore = ::CreateSemaphore(NULL, value, LONG_MAX, NULL); - - guarantee(_semaphore != NULL, "CreateSemaphore failed with error code: %lu", GetLastError()); -} - -WindowsSemaphore::~WindowsSemaphore() { - ::CloseHandle(_semaphore); -} - -void WindowsSemaphore::signal(uint count) { - if (count > 0) { - BOOL ret = ::ReleaseSemaphore(_semaphore, count, NULL); - - assert(ret != 0, "ReleaseSemaphore failed with error code: %lu", GetLastError()); - } -} - -void WindowsSemaphore::wait() { - DWORD ret = ::WaitForSingleObject(_semaphore, INFINITE); - assert(ret != WAIT_FAILED, "WaitForSingleObject failed with error code: %lu", GetLastError()); - assert(ret == WAIT_OBJECT_0, "WaitForSingleObject failed with return value: %lu", ret); -} - -bool WindowsSemaphore::trywait() { - DWORD ret = ::WaitForSingleObject(_semaphore, 0); - assert(ret != WAIT_FAILED, "WaitForSingleObject failed with error code: %lu", GetLastError()); - return ret == WAIT_OBJECT_0; -} - // sun.misc.Signal // NOTE that this is a workaround for an apparent kernel bug where if // a signal handler for SIGBREAK is installed then that signal handler @@ -1966,13 +1935,14 @@ // a counter for each possible signal value, including signal_thread exit signal static volatile jint pending_signals[NSIG+1] = { 0 }; -static HANDLE sig_sem = NULL; +static Semaphore* sig_sem = NULL; void os::signal_init_pd() { // Initialize signal structures memset((void*)pending_signals, 0, sizeof(pending_signals)); - sig_sem = ::CreateSemaphore(NULL, 0, NSIG+1, NULL); + // Initialize signal semaphore + sig_sem = new Semaphore(); // Programs embedding the VM do not want it to attempt to receive // events like CTRL_LOGOFF_EVENT, which are used to implement the @@ -1994,17 +1964,18 @@ } } -void os::signal_notify(int signal_number) { - BOOL ret; +void os::signal_notify(int sig) { if (sig_sem != NULL) { - Atomic::inc(&pending_signals[signal_number]); - ret = ::ReleaseSemaphore(sig_sem, 1, NULL); - assert(ret != 0, "ReleaseSemaphore() failed"); - } -} - -static int check_pending_signals(bool wait_for_signal) { - DWORD ret; + Atomic::inc(&pending_signals[sig]); + sig_sem->signal(); + } else { + // Signal thread is not created with ReduceSignalUsage and signal_init_pd + // initialization isn't called. + assert(ReduceSignalUsage, "signal semaphore should be created"); + } +} + +static int check_pending_signals() { while (true) { for (int i = 0; i < NSIG + 1; i++) { jint n = pending_signals[i]; @@ -2012,10 +1983,6 @@ return i; } } - if (!wait_for_signal) { - return -1; - } - JavaThread *thread = JavaThread::current(); ThreadBlockInVM tbivm(thread); @@ -2024,8 +1991,7 @@ do { thread->set_suspend_equivalent(); // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self() - ret = ::WaitForSingleObject(sig_sem, INFINITE); - assert(ret == WAIT_OBJECT_0, "WaitForSingleObject() failed"); + sig_sem->wait(); // were we externally suspended while we were waiting? threadIsSuspended = thread->handle_special_suspend_equivalent_condition(); @@ -2034,8 +2000,7 @@ // another thread suspended us. We don't want to continue running // while suspended because that would surprise the thread that // suspended us. - ret = ::ReleaseSemaphore(sig_sem, 1, NULL); - assert(ret != 0, "ReleaseSemaphore() failed"); + sig_sem->signal(); thread->java_suspend_self(); } @@ -2043,12 +2008,8 @@ } } -int os::signal_lookup() { - return check_pending_signals(false); -} - int os::signal_wait() { - return check_pending_signals(true); + return check_pending_signals(); } // Implicit OS exception handling diff -r 2569f227ae8e -r 612dfa1d8aad src/hotspot/os/windows/semaphore_windows.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hotspot/os/windows/semaphore_windows.cpp Thu Jan 11 18:42:36 2018 -0500 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2018, 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. + * + */ + +#include "precompiled.hpp" +#include "semaphore_windows.hpp" +#include "utilities/debug.hpp" + +#include +#include + +WindowsSemaphore::WindowsSemaphore(uint value) { + _semaphore = ::CreateSemaphore(NULL, value, LONG_MAX, NULL); + + guarantee(_semaphore != NULL, "CreateSemaphore failed with error code: %lu", GetLastError()); +} + +WindowsSemaphore::~WindowsSemaphore() { + ::CloseHandle(_semaphore); +} + +void WindowsSemaphore::signal(uint count) { + if (count > 0) { + BOOL ret = ::ReleaseSemaphore(_semaphore, count, NULL); + + assert(ret != 0, "ReleaseSemaphore failed with error code: %lu", GetLastError()); + } +} + +void WindowsSemaphore::wait() { + DWORD ret = ::WaitForSingleObject(_semaphore, INFINITE); + assert(ret != WAIT_FAILED, "WaitForSingleObject failed with error code: %lu", GetLastError()); + assert(ret == WAIT_OBJECT_0, "WaitForSingleObject failed with return value: %lu", ret); +} + +bool WindowsSemaphore::trywait() { + DWORD ret = ::WaitForSingleObject(_semaphore, 0); + assert(ret != WAIT_FAILED, "WaitForSingleObject failed with error code: %lu", GetLastError()); + return ret == WAIT_OBJECT_0; +} diff -r 2569f227ae8e -r 612dfa1d8aad src/hotspot/share/runtime/os.hpp --- a/src/hotspot/share/runtime/os.hpp Thu Jan 11 11:28:51 2018 +0100 +++ b/src/hotspot/share/runtime/os.hpp Thu Jan 11 18:42:36 2018 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2018, 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 @@ -778,7 +778,6 @@ static void* signal(int signal_number, void* handler); static void signal_raise(int signal_number); static int signal_wait(); - static int signal_lookup(); static void* user_handler(); static void terminate_signal_thread(); static int sigexitnum_pd();