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
--- 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();
}
////////////////////////////////////////////////////////////////////////////////
--- 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 <time.h>
# include <pwd.h>
# include <poll.h>
-# include <semaphore.h>
# include <fcntl.h>
# include <string.h>
# include <sys/param.h>
@@ -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.
--- /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 <semaphore.h>
+
+#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__
--- 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;
--- 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 <sys/wait.h>
# include <pwd.h>
# include <poll.h>
-# include <semaphore.h>
# include <fcntl.h>
# include <string.h>
# include <syscall.h>
@@ -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;
}
--- 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 <dlfcn.h>
#include <pthread.h>
-#include <semaphore.h>
#include <signal.h>
#include <sys/mman.h>
#include <sys/resource.h>
@@ -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.
--- /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 <semaphore.h>
+
+#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__
+
--- 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;
--- 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;
}
--- 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
--- /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 <windows.h>
+#include <errno.h>
+
+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;
+}
--- 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();