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
This commit is contained in:
parent
b0e4bce398
commit
1c41d1d3e0
@ -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.
|
* Copyright (c) 2012, 2017 SAP SE. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
@ -1723,7 +1723,7 @@ void os::signal_notify(int sig) {
|
|||||||
local_sem_post();
|
local_sem_post();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int check_pending_signals(bool wait) {
|
static int check_pending_signals() {
|
||||||
Atomic::store(0, &sigint_count);
|
Atomic::store(0, &sigint_count);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
for (int i = 0; i < NSIG + 1; i++) {
|
for (int i = 0; i < NSIG + 1; i++) {
|
||||||
@ -1732,9 +1732,6 @@ static int check_pending_signals(bool wait) {
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!wait) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
JavaThread *thread = JavaThread::current();
|
JavaThread *thread = JavaThread::current();
|
||||||
ThreadBlockInVM tbivm(thread);
|
ThreadBlockInVM tbivm(thread);
|
||||||
|
|
||||||
@ -1763,12 +1760,8 @@ static int check_pending_signals(bool wait) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int os::signal_lookup() {
|
|
||||||
return check_pending_signals(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
int os::signal_wait() {
|
int os::signal_wait() {
|
||||||
return check_pending_signals(true);
|
return check_pending_signals();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -52,13 +52,13 @@
|
|||||||
#include "runtime/orderAccess.inline.hpp"
|
#include "runtime/orderAccess.inline.hpp"
|
||||||
#include "runtime/osThread.hpp"
|
#include "runtime/osThread.hpp"
|
||||||
#include "runtime/perfMemory.hpp"
|
#include "runtime/perfMemory.hpp"
|
||||||
|
#include "runtime/semaphore.hpp"
|
||||||
#include "runtime/sharedRuntime.hpp"
|
#include "runtime/sharedRuntime.hpp"
|
||||||
#include "runtime/statSampler.hpp"
|
#include "runtime/statSampler.hpp"
|
||||||
#include "runtime/stubRoutines.hpp"
|
#include "runtime/stubRoutines.hpp"
|
||||||
#include "runtime/thread.inline.hpp"
|
#include "runtime/thread.inline.hpp"
|
||||||
#include "runtime/threadCritical.hpp"
|
#include "runtime/threadCritical.hpp"
|
||||||
#include "runtime/timer.hpp"
|
#include "runtime/timer.hpp"
|
||||||
#include "semaphore_bsd.hpp"
|
|
||||||
#include "services/attachListener.hpp"
|
#include "services/attachListener.hpp"
|
||||||
#include "services/memTracker.hpp"
|
#include "services/memTracker.hpp"
|
||||||
#include "services/runtimeService.hpp"
|
#include "services/runtimeService.hpp"
|
||||||
@ -91,7 +91,6 @@
|
|||||||
# include <time.h>
|
# include <time.h>
|
||||||
# include <pwd.h>
|
# include <pwd.h>
|
||||||
# include <poll.h>
|
# include <poll.h>
|
||||||
# include <semaphore.h>
|
|
||||||
# include <fcntl.h>
|
# include <fcntl.h>
|
||||||
# include <string.h>
|
# include <string.h>
|
||||||
# include <sys/param.h>
|
# include <sys/param.h>
|
||||||
@ -1829,135 +1828,28 @@ int os::sigexitnum_pd() {
|
|||||||
|
|
||||||
// a counter for each possible signal value
|
// a counter for each possible signal value
|
||||||
static volatile jint pending_signals[NSIG+1] = { 0 };
|
static volatile jint pending_signals[NSIG+1] = { 0 };
|
||||||
|
static Semaphore* sig_sem = NULL;
|
||||||
// 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
|
|
||||||
|
|
||||||
void os::signal_init_pd() {
|
void os::signal_init_pd() {
|
||||||
// Initialize signal structures
|
// Initialize signal structures
|
||||||
::memset((void*)pending_signals, 0, sizeof(pending_signals));
|
::memset((void*)pending_signals, 0, sizeof(pending_signals));
|
||||||
|
|
||||||
// Initialize signal semaphore
|
// Initialize signal semaphore
|
||||||
::SEM_INIT(sig_sem, 0);
|
sig_sem = new Semaphore();
|
||||||
}
|
}
|
||||||
|
|
||||||
void os::signal_notify(int sig) {
|
void os::signal_notify(int sig) {
|
||||||
Atomic::inc(&pending_signals[sig]);
|
if (sig_sem != NULL) {
|
||||||
::SEM_POST(sig_sem);
|
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);
|
Atomic::store(0, &sigint_count);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
for (int i = 0; i < NSIG + 1; i++) {
|
for (int i = 0; i < NSIG + 1; i++) {
|
||||||
@ -1966,9 +1858,6 @@ static int check_pending_signals(bool wait) {
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!wait) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
JavaThread *thread = JavaThread::current();
|
JavaThread *thread = JavaThread::current();
|
||||||
ThreadBlockInVM tbivm(thread);
|
ThreadBlockInVM tbivm(thread);
|
||||||
|
|
||||||
@ -1976,7 +1865,7 @@ static int check_pending_signals(bool wait) {
|
|||||||
do {
|
do {
|
||||||
thread->set_suspend_equivalent();
|
thread->set_suspend_equivalent();
|
||||||
// cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
|
// 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?
|
// were we externally suspended while we were waiting?
|
||||||
threadIsSuspended = thread->handle_special_suspend_equivalent_condition();
|
threadIsSuspended = thread->handle_special_suspend_equivalent_condition();
|
||||||
@ -1985,7 +1874,7 @@ static int check_pending_signals(bool wait) {
|
|||||||
// another thread suspended us. We don't want to continue running
|
// another thread suspended us. We don't want to continue running
|
||||||
// while suspended because that would surprise the thread that
|
// while suspended because that would surprise the thread that
|
||||||
// suspended us.
|
// suspended us.
|
||||||
::SEM_POST(sig_sem);
|
sig_sem->signal();
|
||||||
|
|
||||||
thread->java_suspend_self();
|
thread->java_suspend_self();
|
||||||
}
|
}
|
||||||
@ -1993,12 +1882,8 @@ static int check_pending_signals(bool wait) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int os::signal_lookup() {
|
|
||||||
return check_pending_signals(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
int os::signal_wait() {
|
int os::signal_wait() {
|
||||||
return check_pending_signals(true);
|
return check_pending_signals();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -2663,6 +2548,12 @@ static void suspend_save_context(OSThread *osthread, siginfo_t* siginfo, ucontex
|
|||||||
//
|
//
|
||||||
// Currently only ever called on the VMThread or JavaThread
|
// 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) {
|
static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) {
|
||||||
// Save and restore errno to avoid confusing native code with EINTR
|
// Save and restore errno to avoid confusing native code with EINTR
|
||||||
// after sigsuspend.
|
// after sigsuspend.
|
||||||
|
107
src/hotspot/os/bsd/semaphore_bsd.cpp
Normal file
107
src/hotspot/os/bsd/semaphore_bsd.cpp
Normal file
@ -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__
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -53,7 +53,7 @@ class OSXSemaphore : public CHeapObj<mtInternal>{
|
|||||||
bool timedwait(unsigned int sec, int nsec);
|
bool timedwait(unsigned int sec, int nsec);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static jlong currenttime();
|
static int64_t currenttime();
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef OSXSemaphore SemaphoreImpl;
|
typedef OSXSemaphore SemaphoreImpl;
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -95,7 +95,6 @@
|
|||||||
# include <sys/wait.h>
|
# include <sys/wait.h>
|
||||||
# include <pwd.h>
|
# include <pwd.h>
|
||||||
# include <poll.h>
|
# include <poll.h>
|
||||||
# include <semaphore.h>
|
|
||||||
# include <fcntl.h>
|
# include <fcntl.h>
|
||||||
# include <string.h>
|
# include <string.h>
|
||||||
# include <syscall.h>
|
# include <syscall.h>
|
||||||
@ -2479,11 +2478,11 @@ void* os::user_handler() {
|
|||||||
return CAST_FROM_FN_PTR(void*, UserHandler);
|
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;
|
struct timespec ts;
|
||||||
// Semaphore's are always associated with CLOCK_REALTIME
|
// Semaphore's are always associated with CLOCK_REALTIME
|
||||||
os::Linux::clock_gettime(CLOCK_REALTIME, &ts);
|
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) {
|
if (sec >= MAX_SECS) {
|
||||||
ts.tv_sec += MAX_SECS;
|
ts.tv_sec += MAX_SECS;
|
||||||
ts.tv_nsec = 0;
|
ts.tv_nsec = 0;
|
||||||
@ -2535,7 +2534,7 @@ int os::sigexitnum_pd() {
|
|||||||
static volatile jint pending_signals[NSIG+1] = { 0 };
|
static volatile jint pending_signals[NSIG+1] = { 0 };
|
||||||
|
|
||||||
// Linux(POSIX) specific hand shaking semaphore.
|
// Linux(POSIX) specific hand shaking semaphore.
|
||||||
static sem_t sig_sem;
|
static Semaphore* sig_sem = NULL;
|
||||||
static PosixSemaphore sr_semaphore;
|
static PosixSemaphore sr_semaphore;
|
||||||
|
|
||||||
void os::signal_init_pd() {
|
void os::signal_init_pd() {
|
||||||
@ -2543,15 +2542,21 @@ void os::signal_init_pd() {
|
|||||||
::memset((void*)pending_signals, 0, sizeof(pending_signals));
|
::memset((void*)pending_signals, 0, sizeof(pending_signals));
|
||||||
|
|
||||||
// Initialize signal semaphore
|
// Initialize signal semaphore
|
||||||
::sem_init(&sig_sem, 0, 0);
|
sig_sem = new Semaphore();
|
||||||
}
|
}
|
||||||
|
|
||||||
void os::signal_notify(int sig) {
|
void os::signal_notify(int sig) {
|
||||||
Atomic::inc(&pending_signals[sig]);
|
if (sig_sem != NULL) {
|
||||||
::sem_post(&sig_sem);
|
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);
|
Atomic::store(0, &sigint_count);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
for (int i = 0; i < NSIG + 1; i++) {
|
for (int i = 0; i < NSIG + 1; i++) {
|
||||||
@ -2560,9 +2565,6 @@ static int check_pending_signals(bool wait) {
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!wait) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
JavaThread *thread = JavaThread::current();
|
JavaThread *thread = JavaThread::current();
|
||||||
ThreadBlockInVM tbivm(thread);
|
ThreadBlockInVM tbivm(thread);
|
||||||
|
|
||||||
@ -2570,7 +2572,7 @@ static int check_pending_signals(bool wait) {
|
|||||||
do {
|
do {
|
||||||
thread->set_suspend_equivalent();
|
thread->set_suspend_equivalent();
|
||||||
// cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
|
// 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?
|
// were we externally suspended while we were waiting?
|
||||||
threadIsSuspended = thread->handle_special_suspend_equivalent_condition();
|
threadIsSuspended = thread->handle_special_suspend_equivalent_condition();
|
||||||
@ -2579,7 +2581,7 @@ static int check_pending_signals(bool wait) {
|
|||||||
// another thread suspended us. We don't want to continue running
|
// another thread suspended us. We don't want to continue running
|
||||||
// while suspended because that would surprise the thread that
|
// while suspended because that would surprise the thread that
|
||||||
// suspended us.
|
// suspended us.
|
||||||
::sem_post(&sig_sem);
|
sig_sem->signal();
|
||||||
|
|
||||||
thread->java_suspend_self();
|
thread->java_suspend_self();
|
||||||
}
|
}
|
||||||
@ -2587,12 +2589,8 @@ static int check_pending_signals(bool wait) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int os::signal_lookup() {
|
|
||||||
return check_pending_signals(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
int os::signal_wait() {
|
int os::signal_wait() {
|
||||||
return check_pending_signals(true);
|
return check_pending_signals();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -4317,7 +4315,7 @@ static bool do_suspend(OSThread* osthread) {
|
|||||||
|
|
||||||
// managed to send the signal and switch to SUSPEND_REQUEST, now wait for SUSPENDED
|
// managed to send the signal and switch to SUSPEND_REQUEST, now wait for SUSPENDED
|
||||||
while (true) {
|
while (true) {
|
||||||
if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) {
|
if (sr_semaphore.timedwait(create_semaphore_timespec(0, 2 * NANOSECS_PER_MILLISEC))) {
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
// timeout
|
// timeout
|
||||||
@ -4351,7 +4349,7 @@ static void do_resume(OSThread* osthread) {
|
|||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (sr_notify(osthread) == 0) {
|
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()) {
|
if (osthread->sr.is_running()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -31,14 +31,8 @@
|
|||||||
#include "utilities/macros.hpp"
|
#include "utilities/macros.hpp"
|
||||||
#include "utilities/vmError.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 <dlfcn.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <semaphore.h>
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
@ -1499,67 +1493,6 @@ void os::ThreadCrashProtection::check_crash_protection(int sig,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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.
|
// Shared pthread_mutex/cond based PlatformEvent implementation.
|
||||||
// Not currently usable by Solaris.
|
// Not currently usable by Solaris.
|
||||||
|
98
src/hotspot/os/posix/semaphore_posix.cpp
Normal file
98
src/hotspot/os/posix/semaphore_posix.cpp
Normal file
@ -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__
|
||||||
|
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -45,15 +45,7 @@ class PosixSemaphore : public CHeapObj<mtInternal> {
|
|||||||
void wait();
|
void wait();
|
||||||
|
|
||||||
bool trywait();
|
bool trywait();
|
||||||
bool timedwait(unsigned int sec, int nsec) {
|
|
||||||
return timedwait(create_timespec(sec, nsec));
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool timedwait(struct timespec ts);
|
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;
|
typedef PosixSemaphore SemaphoreImpl;
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -2062,7 +2062,7 @@ void* os::user_handler() {
|
|||||||
return CAST_FROM_FN_PTR(void*, UserHandler);
|
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;
|
struct timespec ts;
|
||||||
unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec);
|
unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec);
|
||||||
|
|
||||||
@ -2100,7 +2100,7 @@ static int Sigexit = 0;
|
|||||||
static jint *pending_signals = NULL;
|
static jint *pending_signals = NULL;
|
||||||
static int *preinstalled_sigs = NULL;
|
static int *preinstalled_sigs = NULL;
|
||||||
static struct sigaction *chainedsigactions = NULL;
|
static struct sigaction *chainedsigactions = NULL;
|
||||||
static sema_t sig_sem;
|
static Semaphore* sig_sem = NULL;
|
||||||
typedef int (*version_getting_t)();
|
typedef int (*version_getting_t)();
|
||||||
version_getting_t os::Solaris::get_libjsig_version = NULL;
|
version_getting_t os::Solaris::get_libjsig_version = NULL;
|
||||||
|
|
||||||
@ -2115,6 +2115,7 @@ void os::Solaris::init_signal_mem() {
|
|||||||
Sigexit = Maxsignum+1;
|
Sigexit = Maxsignum+1;
|
||||||
assert(Maxsignum >0, "Unable to obtain max signal number");
|
assert(Maxsignum >0, "Unable to obtain max signal number");
|
||||||
|
|
||||||
|
// Initialize signal structures
|
||||||
// pending_signals has one int per signal
|
// pending_signals has one int per signal
|
||||||
// The additional signal is for SIGEXIT - exit signal to signal_thread
|
// The additional signal is for SIGEXIT - exit signal to signal_thread
|
||||||
pending_signals = (jint *)os::malloc(sizeof(jint) * (Sigexit+1), mtInternal);
|
pending_signals = (jint *)os::malloc(sizeof(jint) * (Sigexit+1), mtInternal);
|
||||||
@ -2132,21 +2133,22 @@ void os::Solaris::init_signal_mem() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void os::signal_init_pd() {
|
void os::signal_init_pd() {
|
||||||
int ret;
|
// Initialize signal semaphore
|
||||||
|
sig_sem = new Semaphore();
|
||||||
ret = ::sema_init(&sig_sem, 0, NULL, NULL);
|
|
||||||
assert(ret == 0, "sema_init() failed");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void os::signal_notify(int signal_number) {
|
void os::signal_notify(int sig) {
|
||||||
int ret;
|
if (sig_sem != NULL) {
|
||||||
|
Atomic::inc(&pending_signals[sig]);
|
||||||
Atomic::inc(&pending_signals[signal_number]);
|
sig_sem->signal();
|
||||||
ret = ::sema_post(&sig_sem);
|
} else {
|
||||||
assert(ret == 0, "sema_post() failed");
|
// 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_for_signal) {
|
static int check_pending_signals() {
|
||||||
int ret;
|
int ret;
|
||||||
while (true) {
|
while (true) {
|
||||||
for (int i = 0; i < Sigexit + 1; i++) {
|
for (int i = 0; i < Sigexit + 1; i++) {
|
||||||
@ -2155,19 +2157,13 @@ static int check_pending_signals(bool wait_for_signal) {
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!wait_for_signal) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
JavaThread *thread = JavaThread::current();
|
JavaThread *thread = JavaThread::current();
|
||||||
ThreadBlockInVM tbivm(thread);
|
ThreadBlockInVM tbivm(thread);
|
||||||
|
|
||||||
bool threadIsSuspended;
|
bool threadIsSuspended;
|
||||||
do {
|
do {
|
||||||
thread->set_suspend_equivalent();
|
thread->set_suspend_equivalent();
|
||||||
// cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
|
sig_sem->wait();
|
||||||
while ((ret = ::sema_wait(&sig_sem)) == EINTR)
|
|
||||||
;
|
|
||||||
assert(ret == 0, "sema_wait() failed");
|
|
||||||
|
|
||||||
// were we externally suspended while we were waiting?
|
// were we externally suspended while we were waiting?
|
||||||
threadIsSuspended = thread->handle_special_suspend_equivalent_condition();
|
threadIsSuspended = thread->handle_special_suspend_equivalent_condition();
|
||||||
@ -2176,8 +2172,7 @@ static int check_pending_signals(bool wait_for_signal) {
|
|||||||
// another thread suspended us. We don't want to continue running
|
// another thread suspended us. We don't want to continue running
|
||||||
// while suspended because that would surprise the thread that
|
// while suspended because that would surprise the thread that
|
||||||
// suspended us.
|
// suspended us.
|
||||||
ret = ::sema_post(&sig_sem);
|
sig_sem->signal();
|
||||||
assert(ret == 0, "sema_post() failed");
|
|
||||||
|
|
||||||
thread->java_suspend_self();
|
thread->java_suspend_self();
|
||||||
}
|
}
|
||||||
@ -2185,12 +2180,8 @@ static int check_pending_signals(bool wait_for_signal) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int os::signal_lookup() {
|
|
||||||
return check_pending_signals(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
int os::signal_wait() {
|
int os::signal_wait() {
|
||||||
return check_pending_signals(true);
|
return check_pending_signals();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -3599,7 +3590,7 @@ static bool do_suspend(OSThread* osthread) {
|
|||||||
|
|
||||||
// managed to send the signal and switch to SUSPEND_REQUEST, now wait for SUSPENDED
|
// managed to send the signal and switch to SUSPEND_REQUEST, now wait for SUSPENDED
|
||||||
while (true) {
|
while (true) {
|
||||||
if (sr_semaphore.timedwait(0, 2000 * NANOSECS_PER_MILLISEC)) {
|
if (sr_semaphore.timedwait(create_semaphore_timespec(0, 2000 * NANOSECS_PER_MILLISEC))) {
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
// timeout
|
// timeout
|
||||||
@ -3633,7 +3624,7 @@ static void do_resume(OSThread* osthread) {
|
|||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (sr_notify(osthread) == 0) {
|
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()) {
|
if (osthread->sr.is_running()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,6 @@
|
|||||||
#include "runtime/threadCritical.hpp"
|
#include "runtime/threadCritical.hpp"
|
||||||
#include "runtime/timer.hpp"
|
#include "runtime/timer.hpp"
|
||||||
#include "runtime/vm_version.hpp"
|
#include "runtime/vm_version.hpp"
|
||||||
#include "semaphore_windows.hpp"
|
|
||||||
#include "services/attachListener.hpp"
|
#include "services/attachListener.hpp"
|
||||||
#include "services/memTracker.hpp"
|
#include "services/memTracker.hpp"
|
||||||
#include "services/runtimeService.hpp"
|
#include "services/runtimeService.hpp"
|
||||||
@ -1845,36 +1844,6 @@ int os::get_last_error() {
|
|||||||
return (int)error;
|
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
|
// sun.misc.Signal
|
||||||
// NOTE that this is a workaround for an apparent kernel bug where if
|
// NOTE that this is a workaround for an apparent kernel bug where if
|
||||||
// a signal handler for SIGBREAK is installed then that signal handler
|
// a signal handler for SIGBREAK is installed then that signal handler
|
||||||
@ -1966,13 +1935,14 @@ int os::sigexitnum_pd() {
|
|||||||
|
|
||||||
// a counter for each possible signal value, including signal_thread exit signal
|
// a counter for each possible signal value, including signal_thread exit signal
|
||||||
static volatile jint pending_signals[NSIG+1] = { 0 };
|
static volatile jint pending_signals[NSIG+1] = { 0 };
|
||||||
static HANDLE sig_sem = NULL;
|
static Semaphore* sig_sem = NULL;
|
||||||
|
|
||||||
void os::signal_init_pd() {
|
void os::signal_init_pd() {
|
||||||
// Initialize signal structures
|
// Initialize signal structures
|
||||||
memset((void*)pending_signals, 0, sizeof(pending_signals));
|
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
|
// Programs embedding the VM do not want it to attempt to receive
|
||||||
// events like CTRL_LOGOFF_EVENT, which are used to implement the
|
// events like CTRL_LOGOFF_EVENT, which are used to implement the
|
||||||
@ -1994,17 +1964,18 @@ void os::signal_init_pd() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void os::signal_notify(int signal_number) {
|
void os::signal_notify(int sig) {
|
||||||
BOOL ret;
|
|
||||||
if (sig_sem != NULL) {
|
if (sig_sem != NULL) {
|
||||||
Atomic::inc(&pending_signals[signal_number]);
|
Atomic::inc(&pending_signals[sig]);
|
||||||
ret = ::ReleaseSemaphore(sig_sem, 1, NULL);
|
sig_sem->signal();
|
||||||
assert(ret != 0, "ReleaseSemaphore() failed");
|
} 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_for_signal) {
|
static int check_pending_signals() {
|
||||||
DWORD ret;
|
|
||||||
while (true) {
|
while (true) {
|
||||||
for (int i = 0; i < NSIG + 1; i++) {
|
for (int i = 0; i < NSIG + 1; i++) {
|
||||||
jint n = pending_signals[i];
|
jint n = pending_signals[i];
|
||||||
@ -2012,10 +1983,6 @@ static int check_pending_signals(bool wait_for_signal) {
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!wait_for_signal) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
JavaThread *thread = JavaThread::current();
|
JavaThread *thread = JavaThread::current();
|
||||||
|
|
||||||
ThreadBlockInVM tbivm(thread);
|
ThreadBlockInVM tbivm(thread);
|
||||||
@ -2024,8 +1991,7 @@ static int check_pending_signals(bool wait_for_signal) {
|
|||||||
do {
|
do {
|
||||||
thread->set_suspend_equivalent();
|
thread->set_suspend_equivalent();
|
||||||
// cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
|
// cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
|
||||||
ret = ::WaitForSingleObject(sig_sem, INFINITE);
|
sig_sem->wait();
|
||||||
assert(ret == WAIT_OBJECT_0, "WaitForSingleObject() failed");
|
|
||||||
|
|
||||||
// were we externally suspended while we were waiting?
|
// were we externally suspended while we were waiting?
|
||||||
threadIsSuspended = thread->handle_special_suspend_equivalent_condition();
|
threadIsSuspended = thread->handle_special_suspend_equivalent_condition();
|
||||||
@ -2034,8 +2000,7 @@ static int check_pending_signals(bool wait_for_signal) {
|
|||||||
// another thread suspended us. We don't want to continue running
|
// another thread suspended us. We don't want to continue running
|
||||||
// while suspended because that would surprise the thread that
|
// while suspended because that would surprise the thread that
|
||||||
// suspended us.
|
// suspended us.
|
||||||
ret = ::ReleaseSemaphore(sig_sem, 1, NULL);
|
sig_sem->signal();
|
||||||
assert(ret != 0, "ReleaseSemaphore() failed");
|
|
||||||
|
|
||||||
thread->java_suspend_self();
|
thread->java_suspend_self();
|
||||||
}
|
}
|
||||||
@ -2043,12 +2008,8 @@ static int check_pending_signals(bool wait_for_signal) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int os::signal_lookup() {
|
|
||||||
return check_pending_signals(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
int os::signal_wait() {
|
int os::signal_wait() {
|
||||||
return check_pending_signals(true);
|
return check_pending_signals();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implicit OS exception handling
|
// Implicit OS exception handling
|
||||||
|
60
src/hotspot/os/windows/semaphore_windows.cpp
Normal file
60
src/hotspot/os/windows/semaphore_windows.cpp
Normal file
@ -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;
|
||||||
|
}
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -778,7 +778,6 @@ class os: AllStatic {
|
|||||||
static void* signal(int signal_number, void* handler);
|
static void* signal(int signal_number, void* handler);
|
||||||
static void signal_raise(int signal_number);
|
static void signal_raise(int signal_number);
|
||||||
static int signal_wait();
|
static int signal_wait();
|
||||||
static int signal_lookup();
|
|
||||||
static void* user_handler();
|
static void* user_handler();
|
||||||
static void terminate_signal_thread();
|
static void terminate_signal_thread();
|
||||||
static int sigexitnum_pd();
|
static int sigexitnum_pd();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user