8289230: Move PlatformXXX class declarations out of os_xxx.hpp
Reviewed-by: coleenp, ccheung
This commit is contained in:
parent
44e8c462b4
commit
cdf6979259
@ -23,6 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "jvm.h"
|
||||
#include "runtime/os.hpp"
|
||||
#include "utilities/decoder_elf.hpp"
|
||||
#include "utilities/elfFile.hpp"
|
||||
|
||||
|
141
src/hotspot/os/posix/mutex_posix.hpp
Normal file
141
src/hotspot/os/posix/mutex_posix.hpp
Normal file
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef OS_POSIX_MUTEX_POSIX_HPP
|
||||
#define OS_POSIX_MUTEX_POSIX_HPP
|
||||
|
||||
#include "memory/allocation.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
|
||||
// Workaround for a bug in macOSX kernel's pthread support (fixed in Mojave?).
|
||||
// Avoid ever allocating a pthread_mutex_t at the same address as one of our
|
||||
// former pthread_cond_t, by using freelists of mutexes and condvars.
|
||||
// Conditional to avoid extra indirection and padding loss on other platforms.
|
||||
#ifdef __APPLE__
|
||||
#define PLATFORM_MONITOR_IMPL_INDIRECT 1
|
||||
#else
|
||||
#define PLATFORM_MONITOR_IMPL_INDIRECT 0
|
||||
#endif
|
||||
|
||||
// Platform specific implementations that underpin VM Mutex/Monitor classes.
|
||||
// Note that we use "normal" pthread_mutex_t attributes so that recursive
|
||||
// locking is not supported, which matches the expected semantics of the
|
||||
// VM Mutex class.
|
||||
|
||||
class PlatformMutex : public CHeapObj<mtSynchronizer> {
|
||||
#if PLATFORM_MONITOR_IMPL_INDIRECT
|
||||
class Mutex : public CHeapObj<mtSynchronizer> {
|
||||
public:
|
||||
pthread_mutex_t _mutex;
|
||||
Mutex* _next;
|
||||
|
||||
Mutex();
|
||||
~Mutex();
|
||||
};
|
||||
|
||||
Mutex* _impl;
|
||||
|
||||
static pthread_mutex_t _freelist_lock; // used for mutex and cond freelists
|
||||
static Mutex* _mutex_freelist;
|
||||
|
||||
protected:
|
||||
class WithFreeListLocked;
|
||||
pthread_mutex_t* mutex() { return &(_impl->_mutex); }
|
||||
|
||||
public:
|
||||
PlatformMutex(); // Use freelist allocation of impl.
|
||||
~PlatformMutex();
|
||||
|
||||
static void init(); // Initialize the freelist.
|
||||
|
||||
#else
|
||||
|
||||
pthread_mutex_t _mutex;
|
||||
|
||||
protected:
|
||||
pthread_mutex_t* mutex() { return &_mutex; }
|
||||
|
||||
public:
|
||||
static void init() {} // Nothing needed for the non-indirect case.
|
||||
|
||||
PlatformMutex();
|
||||
~PlatformMutex();
|
||||
|
||||
#endif // PLATFORM_MONITOR_IMPL_INDIRECT
|
||||
|
||||
private:
|
||||
NONCOPYABLE(PlatformMutex);
|
||||
|
||||
public:
|
||||
void lock();
|
||||
void unlock();
|
||||
bool try_lock();
|
||||
};
|
||||
|
||||
class PlatformMonitor : public PlatformMutex {
|
||||
#if PLATFORM_MONITOR_IMPL_INDIRECT
|
||||
class Cond : public CHeapObj<mtSynchronizer> {
|
||||
public:
|
||||
pthread_cond_t _cond;
|
||||
Cond* _next;
|
||||
|
||||
Cond();
|
||||
~Cond();
|
||||
};
|
||||
|
||||
Cond* _impl;
|
||||
|
||||
static Cond* _cond_freelist;
|
||||
|
||||
pthread_cond_t* cond() { return &(_impl->_cond); }
|
||||
|
||||
public:
|
||||
PlatformMonitor(); // Use freelist allocation of impl.
|
||||
~PlatformMonitor();
|
||||
|
||||
#else
|
||||
|
||||
pthread_cond_t _cond;
|
||||
pthread_cond_t* cond() { return &_cond; }
|
||||
|
||||
public:
|
||||
PlatformMonitor();
|
||||
~PlatformMonitor();
|
||||
|
||||
#endif // PLATFORM_MONITOR_IMPL_INDIRECT
|
||||
|
||||
private:
|
||||
NONCOPYABLE(PlatformMonitor);
|
||||
|
||||
public:
|
||||
int wait(jlong millis);
|
||||
void notify();
|
||||
void notify_all();
|
||||
};
|
||||
|
||||
#endif // OS_POSIX_MUTEX_POSIX_HPP
|
@ -43,6 +43,7 @@
|
||||
#include "runtime/atomic.hpp"
|
||||
#include "runtime/java.hpp"
|
||||
#include "runtime/orderAccess.hpp"
|
||||
#include "runtime/park.hpp"
|
||||
#include "runtime/perfMemory.hpp"
|
||||
#include "utilities/align.hpp"
|
||||
#include "utilities/events.hpp"
|
||||
@ -1155,62 +1156,6 @@ bool os::Posix::matches_effective_uid_and_gid_or_root(uid_t uid, gid_t gid) {
|
||||
return is_root(uid) || (geteuid() == uid && getegid() == gid);
|
||||
}
|
||||
|
||||
Thread* os::ThreadCrashProtection::_protected_thread = NULL;
|
||||
os::ThreadCrashProtection* os::ThreadCrashProtection::_crash_protection = NULL;
|
||||
|
||||
os::ThreadCrashProtection::ThreadCrashProtection() {
|
||||
_protected_thread = Thread::current();
|
||||
assert(_protected_thread->is_JfrSampler_thread(), "should be JFRSampler");
|
||||
}
|
||||
|
||||
/*
|
||||
* See the caveats for this class in os_posix.hpp
|
||||
* Protects the callback call so that SIGSEGV / SIGBUS jumps back into this
|
||||
* method and returns false. If none of the signals are raised, returns true.
|
||||
* The callback is supposed to provide the method that should be protected.
|
||||
*/
|
||||
bool os::ThreadCrashProtection::call(os::CrashProtectionCallback& cb) {
|
||||
sigset_t saved_sig_mask;
|
||||
|
||||
// we cannot rely on sigsetjmp/siglongjmp to save/restore the signal mask
|
||||
// since on at least some systems (OS X) siglongjmp will restore the mask
|
||||
// for the process, not the thread
|
||||
pthread_sigmask(0, NULL, &saved_sig_mask);
|
||||
if (sigsetjmp(_jmpbuf, 0) == 0) {
|
||||
// make sure we can see in the signal handler that we have crash protection
|
||||
// installed
|
||||
_crash_protection = this;
|
||||
cb.call();
|
||||
// and clear the crash protection
|
||||
_crash_protection = NULL;
|
||||
_protected_thread = NULL;
|
||||
return true;
|
||||
}
|
||||
// this happens when we siglongjmp() back
|
||||
pthread_sigmask(SIG_SETMASK, &saved_sig_mask, NULL);
|
||||
_crash_protection = NULL;
|
||||
_protected_thread = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
void os::ThreadCrashProtection::restore() {
|
||||
assert(_crash_protection != NULL, "must have crash protection");
|
||||
siglongjmp(_jmpbuf, 1);
|
||||
}
|
||||
|
||||
void os::ThreadCrashProtection::check_crash_protection(int sig,
|
||||
Thread* thread) {
|
||||
|
||||
if (thread != NULL &&
|
||||
thread == _protected_thread &&
|
||||
_crash_protection != NULL) {
|
||||
|
||||
if (sig == SIGSEGV || sig == SIGBUS) {
|
||||
_crash_protection->restore();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Shared clock/time and other supporting routines for pthread_mutex/cond
|
||||
// initialization. This is enabled on Solaris but only some of the clock/time
|
||||
// functionality is actually used there.
|
||||
@ -1237,7 +1182,7 @@ static void pthread_init_common(void) {
|
||||
if ((status = pthread_mutexattr_settype(_mutexAttr, PTHREAD_MUTEX_NORMAL)) != 0) {
|
||||
fatal("pthread_mutexattr_settype: %s", os::strerror(status));
|
||||
}
|
||||
os::PlatformMutex::init();
|
||||
PlatformMutex::init();
|
||||
}
|
||||
|
||||
static int (*_pthread_condattr_setclock)(pthread_condattr_t *, clockid_t) = NULL;
|
||||
@ -1504,11 +1449,6 @@ struct tm* os::localtime_pd(const time_t* clock, struct tm* res) {
|
||||
return localtime_r(clock, res);
|
||||
}
|
||||
|
||||
|
||||
// Shared pthread_mutex/cond based PlatformEvent implementation.
|
||||
// Not currently usable by Solaris.
|
||||
|
||||
|
||||
// PlatformEvent
|
||||
//
|
||||
// Assumption:
|
||||
@ -1524,7 +1464,7 @@ struct tm* os::localtime_pd(const time_t* clock, struct tm* res) {
|
||||
// Having three states allows for some detection of bad usage - see
|
||||
// comments on unpark().
|
||||
|
||||
os::PlatformEvent::PlatformEvent() {
|
||||
PlatformEvent::PlatformEvent() {
|
||||
int status = pthread_cond_init(_cond, _condAttr);
|
||||
assert_status(status == 0, status, "cond_init");
|
||||
status = pthread_mutex_init(_mutex, _mutexAttr);
|
||||
@ -1533,7 +1473,7 @@ os::PlatformEvent::PlatformEvent() {
|
||||
_nParked = 0;
|
||||
}
|
||||
|
||||
void os::PlatformEvent::park() { // AKA "down()"
|
||||
void PlatformEvent::park() { // AKA "down()"
|
||||
// Transitions for _event:
|
||||
// -1 => -1 : illegal
|
||||
// 1 => 0 : pass - return immediately
|
||||
@ -1575,7 +1515,7 @@ void os::PlatformEvent::park() { // AKA "down()"
|
||||
guarantee(_event >= 0, "invariant");
|
||||
}
|
||||
|
||||
int os::PlatformEvent::park(jlong millis) {
|
||||
int PlatformEvent::park(jlong millis) {
|
||||
// Transitions for _event:
|
||||
// -1 => -1 : illegal
|
||||
// 1 => 0 : pass - return immediately
|
||||
@ -1627,7 +1567,7 @@ int os::PlatformEvent::park(jlong millis) {
|
||||
return OS_OK;
|
||||
}
|
||||
|
||||
void os::PlatformEvent::unpark() {
|
||||
void PlatformEvent::unpark() {
|
||||
// Transitions for _event:
|
||||
// 0 => 1 : just return
|
||||
// 1 => 1 : just return
|
||||
@ -1670,7 +1610,7 @@ void os::PlatformEvent::unpark() {
|
||||
|
||||
// JSR166 support
|
||||
|
||||
os::PlatformParker::PlatformParker() : _counter(0), _cur_index(-1) {
|
||||
PlatformParker::PlatformParker() : _counter(0), _cur_index(-1) {
|
||||
int status = pthread_cond_init(&_cond[REL_INDEX], _condAttr);
|
||||
assert_status(status == 0, status, "cond_init rel");
|
||||
status = pthread_cond_init(&_cond[ABS_INDEX], NULL);
|
||||
@ -1679,7 +1619,7 @@ void os::PlatformEvent::unpark() {
|
||||
assert_status(status == 0, status, "mutex_init");
|
||||
}
|
||||
|
||||
os::PlatformParker::~PlatformParker() {
|
||||
PlatformParker::~PlatformParker() {
|
||||
int status = pthread_cond_destroy(&_cond[REL_INDEX]);
|
||||
assert_status(status == 0, status, "cond_destroy rel");
|
||||
status = pthread_cond_destroy(&_cond[ABS_INDEX]);
|
||||
@ -1801,25 +1741,25 @@ void Parker::unpark() {
|
||||
|
||||
#if PLATFORM_MONITOR_IMPL_INDIRECT
|
||||
|
||||
os::PlatformMutex::Mutex::Mutex() : _next(NULL) {
|
||||
PlatformMutex::Mutex::Mutex() : _next(NULL) {
|
||||
int status = pthread_mutex_init(&_mutex, _mutexAttr);
|
||||
assert_status(status == 0, status, "mutex_init");
|
||||
}
|
||||
|
||||
os::PlatformMutex::Mutex::~Mutex() {
|
||||
PlatformMutex::Mutex::~Mutex() {
|
||||
int status = pthread_mutex_destroy(&_mutex);
|
||||
assert_status(status == 0, status, "mutex_destroy");
|
||||
}
|
||||
|
||||
pthread_mutex_t os::PlatformMutex::_freelist_lock;
|
||||
os::PlatformMutex::Mutex* os::PlatformMutex::_mutex_freelist = NULL;
|
||||
pthread_mutex_t PlatformMutex::_freelist_lock;
|
||||
PlatformMutex::Mutex* PlatformMutex::_mutex_freelist = NULL;
|
||||
|
||||
void os::PlatformMutex::init() {
|
||||
void PlatformMutex::init() {
|
||||
int status = pthread_mutex_init(&_freelist_lock, _mutexAttr);
|
||||
assert_status(status == 0, status, "freelist lock init");
|
||||
}
|
||||
|
||||
struct os::PlatformMutex::WithFreeListLocked : public StackObj {
|
||||
struct PlatformMutex::WithFreeListLocked : public StackObj {
|
||||
WithFreeListLocked() {
|
||||
int status = pthread_mutex_lock(&_freelist_lock);
|
||||
assert_status(status == 0, status, "freelist lock");
|
||||
@ -1831,7 +1771,7 @@ struct os::PlatformMutex::WithFreeListLocked : public StackObj {
|
||||
}
|
||||
};
|
||||
|
||||
os::PlatformMutex::PlatformMutex() {
|
||||
PlatformMutex::PlatformMutex() {
|
||||
{
|
||||
WithFreeListLocked wfl;
|
||||
_impl = _mutex_freelist;
|
||||
@ -1844,26 +1784,26 @@ os::PlatformMutex::PlatformMutex() {
|
||||
_impl = new Mutex();
|
||||
}
|
||||
|
||||
os::PlatformMutex::~PlatformMutex() {
|
||||
PlatformMutex::~PlatformMutex() {
|
||||
WithFreeListLocked wfl;
|
||||
assert(_impl->_next == NULL, "invariant");
|
||||
_impl->_next = _mutex_freelist;
|
||||
_mutex_freelist = _impl;
|
||||
}
|
||||
|
||||
os::PlatformMonitor::Cond::Cond() : _next(NULL) {
|
||||
PlatformMonitor::Cond::Cond() : _next(NULL) {
|
||||
int status = pthread_cond_init(&_cond, _condAttr);
|
||||
assert_status(status == 0, status, "cond_init");
|
||||
}
|
||||
|
||||
os::PlatformMonitor::Cond::~Cond() {
|
||||
PlatformMonitor::Cond::~Cond() {
|
||||
int status = pthread_cond_destroy(&_cond);
|
||||
assert_status(status == 0, status, "cond_destroy");
|
||||
}
|
||||
|
||||
os::PlatformMonitor::Cond* os::PlatformMonitor::_cond_freelist = NULL;
|
||||
PlatformMonitor::Cond* PlatformMonitor::_cond_freelist = NULL;
|
||||
|
||||
os::PlatformMonitor::PlatformMonitor() {
|
||||
PlatformMonitor::PlatformMonitor() {
|
||||
{
|
||||
WithFreeListLocked wfl;
|
||||
_impl = _cond_freelist;
|
||||
@ -1876,7 +1816,7 @@ os::PlatformMonitor::PlatformMonitor() {
|
||||
_impl = new Cond();
|
||||
}
|
||||
|
||||
os::PlatformMonitor::~PlatformMonitor() {
|
||||
PlatformMonitor::~PlatformMonitor() {
|
||||
WithFreeListLocked wfl;
|
||||
assert(_impl->_next == NULL, "invariant");
|
||||
_impl->_next = _cond_freelist;
|
||||
@ -1885,22 +1825,22 @@ os::PlatformMonitor::~PlatformMonitor() {
|
||||
|
||||
#else
|
||||
|
||||
os::PlatformMutex::PlatformMutex() {
|
||||
PlatformMutex::PlatformMutex() {
|
||||
int status = pthread_mutex_init(&_mutex, _mutexAttr);
|
||||
assert_status(status == 0, status, "mutex_init");
|
||||
}
|
||||
|
||||
os::PlatformMutex::~PlatformMutex() {
|
||||
PlatformMutex::~PlatformMutex() {
|
||||
int status = pthread_mutex_destroy(&_mutex);
|
||||
assert_status(status == 0, status, "mutex_destroy");
|
||||
}
|
||||
|
||||
os::PlatformMonitor::PlatformMonitor() {
|
||||
PlatformMonitor::PlatformMonitor() {
|
||||
int status = pthread_cond_init(&_cond, _condAttr);
|
||||
assert_status(status == 0, status, "cond_init");
|
||||
}
|
||||
|
||||
os::PlatformMonitor::~PlatformMonitor() {
|
||||
PlatformMonitor::~PlatformMonitor() {
|
||||
int status = pthread_cond_destroy(&_cond);
|
||||
assert_status(status == 0, status, "cond_destroy");
|
||||
}
|
||||
@ -1908,7 +1848,7 @@ os::PlatformMonitor::~PlatformMonitor() {
|
||||
#endif // PLATFORM_MONITOR_IMPL_INDIRECT
|
||||
|
||||
// Must already be locked
|
||||
int os::PlatformMonitor::wait(jlong millis) {
|
||||
int PlatformMonitor::wait(jlong millis) {
|
||||
assert(millis >= 0, "negative timeout");
|
||||
if (millis > 0) {
|
||||
struct timespec abst;
|
||||
|
@ -96,195 +96,4 @@ public:
|
||||
static void print_active_locale(outputStream* st);
|
||||
};
|
||||
|
||||
/*
|
||||
* Crash protection for the JfrSampler thread. Wrap the callback
|
||||
* with a sigsetjmp and in case of a SIGSEGV/SIGBUS we siglongjmp
|
||||
* back.
|
||||
* To be able to use this - don't take locks, don't rely on destructors,
|
||||
* don't make OS library calls, don't allocate memory, don't print,
|
||||
* don't call code that could leave the heap / memory in an inconsistent state,
|
||||
* or anything else where we are not in control if we suddenly jump out.
|
||||
*/
|
||||
class ThreadCrashProtection : public StackObj {
|
||||
public:
|
||||
static bool is_crash_protected(Thread* thr) {
|
||||
return _crash_protection != NULL && _protected_thread == thr;
|
||||
}
|
||||
|
||||
ThreadCrashProtection();
|
||||
bool call(os::CrashProtectionCallback& cb);
|
||||
|
||||
static void check_crash_protection(int signal, Thread* thread);
|
||||
private:
|
||||
static Thread* _protected_thread;
|
||||
static ThreadCrashProtection* _crash_protection;
|
||||
void restore();
|
||||
sigjmp_buf _jmpbuf;
|
||||
};
|
||||
|
||||
/*
|
||||
* This is the platform-specific implementation underpinning
|
||||
* the ParkEvent class, which itself underpins Java-level monitor
|
||||
* operations. See park.hpp for details.
|
||||
* These event objects are type-stable and immortal - we never delete them.
|
||||
* Events are associated with a thread for the lifetime of the thread.
|
||||
*/
|
||||
class PlatformEvent : public CHeapObj<mtSynchronizer> {
|
||||
private:
|
||||
double cachePad[4]; // Increase odds that _mutex is sole occupant of cache line
|
||||
volatile int _event; // Event count/permit: -1, 0 or 1
|
||||
volatile int _nParked; // Indicates if associated thread is blocked: 0 or 1
|
||||
pthread_mutex_t _mutex[1]; // Native mutex for locking
|
||||
pthread_cond_t _cond[1]; // Native condition variable for blocking
|
||||
double postPad[2];
|
||||
|
||||
protected: // TODO-FIXME: make dtor private
|
||||
~PlatformEvent() { guarantee(false, "invariant"); } // immortal so can't delete
|
||||
|
||||
public:
|
||||
PlatformEvent();
|
||||
void park();
|
||||
int park(jlong millis);
|
||||
void unpark();
|
||||
|
||||
// Use caution with reset() and fired() -- they may require MEMBARs
|
||||
void reset() { _event = 0; }
|
||||
int fired() { return _event; }
|
||||
};
|
||||
|
||||
// JSR166 support
|
||||
// PlatformParker provides the platform dependent base class for the
|
||||
// Parker class. It basically provides the internal data structures:
|
||||
// - mutex and convars
|
||||
// which are then used directly by the Parker methods defined in the OS
|
||||
// specific implementation files.
|
||||
// There is significant overlap between the funcionality supported in the
|
||||
// combination of Parker+PlatformParker and PlatformEvent (above). If Parker
|
||||
// were more like ObjectMonitor we could use PlatformEvent in both (with some
|
||||
// API updates of course). But Parker methods use fastpaths that break that
|
||||
// level of encapsulation - so combining the two remains a future project.
|
||||
|
||||
class PlatformParker {
|
||||
NONCOPYABLE(PlatformParker);
|
||||
protected:
|
||||
enum {
|
||||
REL_INDEX = 0,
|
||||
ABS_INDEX = 1
|
||||
};
|
||||
volatile int _counter;
|
||||
int _cur_index; // which cond is in use: -1, 0, 1
|
||||
pthread_mutex_t _mutex[1];
|
||||
pthread_cond_t _cond[2]; // one for relative times and one for absolute
|
||||
|
||||
public:
|
||||
PlatformParker();
|
||||
~PlatformParker();
|
||||
};
|
||||
|
||||
// Workaround for a bug in macOSX kernel's pthread support (fixed in Mojave?).
|
||||
// Avoid ever allocating a pthread_mutex_t at the same address as one of our
|
||||
// former pthread_cond_t, by using freelists of mutexes and condvars.
|
||||
// Conditional to avoid extra indirection and padding loss on other platforms.
|
||||
#ifdef __APPLE__
|
||||
#define PLATFORM_MONITOR_IMPL_INDIRECT 1
|
||||
#else
|
||||
#define PLATFORM_MONITOR_IMPL_INDIRECT 0
|
||||
#endif
|
||||
|
||||
// Platform specific implementations that underpin VM Mutex/Monitor classes.
|
||||
// Note that we use "normal" pthread_mutex_t attributes so that recursive
|
||||
// locking is not supported, which matches the expected semantics of the
|
||||
// VM Mutex class.
|
||||
|
||||
class PlatformMutex : public CHeapObj<mtSynchronizer> {
|
||||
#if PLATFORM_MONITOR_IMPL_INDIRECT
|
||||
class Mutex : public CHeapObj<mtSynchronizer> {
|
||||
public:
|
||||
pthread_mutex_t _mutex;
|
||||
Mutex* _next;
|
||||
|
||||
Mutex();
|
||||
~Mutex();
|
||||
};
|
||||
|
||||
Mutex* _impl;
|
||||
|
||||
static pthread_mutex_t _freelist_lock; // used for mutex and cond freelists
|
||||
static Mutex* _mutex_freelist;
|
||||
|
||||
protected:
|
||||
class WithFreeListLocked;
|
||||
pthread_mutex_t* mutex() { return &(_impl->_mutex); }
|
||||
|
||||
public:
|
||||
PlatformMutex(); // Use freelist allocation of impl.
|
||||
~PlatformMutex();
|
||||
|
||||
static void init(); // Initialize the freelist.
|
||||
|
||||
#else
|
||||
|
||||
pthread_mutex_t _mutex;
|
||||
|
||||
protected:
|
||||
pthread_mutex_t* mutex() { return &_mutex; }
|
||||
|
||||
public:
|
||||
static void init() {} // Nothing needed for the non-indirect case.
|
||||
|
||||
PlatformMutex();
|
||||
~PlatformMutex();
|
||||
|
||||
#endif // PLATFORM_MONITOR_IMPL_INDIRECT
|
||||
|
||||
private:
|
||||
NONCOPYABLE(PlatformMutex);
|
||||
|
||||
public:
|
||||
void lock();
|
||||
void unlock();
|
||||
bool try_lock();
|
||||
};
|
||||
|
||||
class PlatformMonitor : public PlatformMutex {
|
||||
#if PLATFORM_MONITOR_IMPL_INDIRECT
|
||||
class Cond : public CHeapObj<mtSynchronizer> {
|
||||
public:
|
||||
pthread_cond_t _cond;
|
||||
Cond* _next;
|
||||
|
||||
Cond();
|
||||
~Cond();
|
||||
};
|
||||
|
||||
Cond* _impl;
|
||||
|
||||
static Cond* _cond_freelist;
|
||||
|
||||
pthread_cond_t* cond() { return &(_impl->_cond); }
|
||||
|
||||
public:
|
||||
PlatformMonitor(); // Use freelist allocation of impl.
|
||||
~PlatformMonitor();
|
||||
|
||||
#else
|
||||
|
||||
pthread_cond_t _cond;
|
||||
pthread_cond_t* cond() { return &_cond; }
|
||||
|
||||
public:
|
||||
PlatformMonitor();
|
||||
~PlatformMonitor();
|
||||
|
||||
#endif // PLATFORM_MONITOR_IMPL_INDIRECT
|
||||
|
||||
private:
|
||||
NONCOPYABLE(PlatformMonitor);
|
||||
|
||||
public:
|
||||
int wait(jlong millis);
|
||||
void notify();
|
||||
void notify_all();
|
||||
};
|
||||
|
||||
#endif // OS_POSIX_OS_POSIX_HPP
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2022, 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
|
||||
@ -27,6 +27,7 @@
|
||||
|
||||
// os_posix.hpp included by os.hpp
|
||||
|
||||
#include "runtime/mutex.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
|
||||
#include <unistd.h>
|
||||
@ -51,28 +52,28 @@ inline bool os::numa_has_group_homing() { AIX_ONLY(ShouldNotReachHere();) re
|
||||
|
||||
// Platform Mutex/Monitor implementation
|
||||
|
||||
inline void os::PlatformMutex::lock() {
|
||||
inline void PlatformMutex::lock() {
|
||||
int status = pthread_mutex_lock(mutex());
|
||||
assert_status(status == 0, status, "mutex_lock");
|
||||
}
|
||||
|
||||
inline void os::PlatformMutex::unlock() {
|
||||
inline void PlatformMutex::unlock() {
|
||||
int status = pthread_mutex_unlock(mutex());
|
||||
assert_status(status == 0, status, "mutex_unlock");
|
||||
}
|
||||
|
||||
inline bool os::PlatformMutex::try_lock() {
|
||||
inline bool PlatformMutex::try_lock() {
|
||||
int status = pthread_mutex_trylock(mutex());
|
||||
assert_status(status == 0 || status == EBUSY, status, "mutex_trylock");
|
||||
return status == 0;
|
||||
}
|
||||
|
||||
inline void os::PlatformMonitor::notify() {
|
||||
inline void PlatformMonitor::notify() {
|
||||
int status = pthread_cond_signal(cond());
|
||||
assert_status(status == 0, status, "cond_signal");
|
||||
}
|
||||
|
||||
inline void os::PlatformMonitor::notify_all() {
|
||||
inline void PlatformMonitor::notify_all() {
|
||||
int status = pthread_cond_broadcast(cond());
|
||||
assert_status(status == 0, status, "cond_broadcast");
|
||||
}
|
||||
|
93
src/hotspot/os/posix/park_posix.hpp
Normal file
93
src/hotspot/os/posix/park_posix.hpp
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef OS_POSIX_PARK_POSIX_HPP
|
||||
#define OS_POSIX_PARK_POSIX_HPP
|
||||
|
||||
#include "memory/allocation.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
/*
|
||||
* This is the platform-specific implementation underpinning
|
||||
* the ParkEvent class, which itself underpins Java-level monitor
|
||||
* operations. See park.hpp for details.
|
||||
* These event objects are type-stable and immortal - we never delete them.
|
||||
* Events are associated with a thread for the lifetime of the thread.
|
||||
*/
|
||||
class PlatformEvent : public CHeapObj<mtSynchronizer> {
|
||||
private:
|
||||
double cachePad[4]; // Increase odds that _mutex is sole occupant of cache line
|
||||
volatile int _event; // Event count/permit: -1, 0 or 1
|
||||
volatile int _nParked; // Indicates if associated thread is blocked: 0 or 1
|
||||
pthread_mutex_t _mutex[1]; // Native mutex for locking
|
||||
pthread_cond_t _cond[1]; // Native condition variable for blocking
|
||||
double postPad[2];
|
||||
|
||||
protected: // TODO-FIXME: make dtor private
|
||||
~PlatformEvent() { guarantee(false, "invariant"); } // immortal so can't delete
|
||||
|
||||
public:
|
||||
PlatformEvent();
|
||||
void park();
|
||||
int park(jlong millis);
|
||||
void unpark();
|
||||
|
||||
// Use caution with reset() and fired() -- they may require MEMBARs
|
||||
void reset() { _event = 0; }
|
||||
int fired() { return _event; }
|
||||
};
|
||||
|
||||
// JSR166 support
|
||||
// PlatformParker provides the platform dependent base class for the
|
||||
// Parker class. It basically provides the internal data structures:
|
||||
// - mutex and convars
|
||||
// which are then used directly by the Parker methods defined in the OS
|
||||
// specific implementation files.
|
||||
// There is significant overlap between the funcionality supported in the
|
||||
// combination of Parker+PlatformParker and PlatformEvent (above). If Parker
|
||||
// were more like ObjectMonitor we could use PlatformEvent in both (with some
|
||||
// API updates of course). But Parker methods use fastpaths that break that
|
||||
// level of encapsulation - so combining the two remains a future project.
|
||||
|
||||
class PlatformParker {
|
||||
NONCOPYABLE(PlatformParker);
|
||||
protected:
|
||||
enum {
|
||||
REL_INDEX = 0,
|
||||
ABS_INDEX = 1
|
||||
};
|
||||
volatile int _counter;
|
||||
int _cur_index; // which cond is in use: -1, 0, 1
|
||||
pthread_mutex_t _mutex[1];
|
||||
pthread_cond_t _cond[2]; // one for relative times and one for absolute
|
||||
|
||||
public:
|
||||
PlatformParker();
|
||||
~PlatformParker();
|
||||
};
|
||||
|
||||
#endif // OS_POSIX_PARK_POSIX_HPP
|
@ -38,6 +38,7 @@
|
||||
#include "runtime/osThread.hpp"
|
||||
#include "runtime/safefetch.hpp"
|
||||
#include "runtime/semaphore.inline.hpp"
|
||||
#include "runtime/threadCrashProtection.hpp"
|
||||
#include "signals_posix.hpp"
|
||||
#include "utilities/events.hpp"
|
||||
#include "utilities/ostream.hpp"
|
||||
@ -584,7 +585,7 @@ int JVM_HANDLE_XXX_SIGNAL(int sig, siginfo_t* info,
|
||||
// Handle JFR thread crash protection.
|
||||
// Note: this may cause us to longjmp away. Do not use any code before this
|
||||
// point which really needs any form of epilogue code running, eg RAII objects.
|
||||
os::ThreadCrashProtection::check_crash_protection(sig, t);
|
||||
ThreadCrashProtection::check_crash_protection(sig, t);
|
||||
|
||||
bool signal_was_handled = false;
|
||||
|
||||
|
83
src/hotspot/os/posix/threadCrashProtection_posix.cpp
Normal file
83
src/hotspot/os/posix/threadCrashProtection_posix.cpp
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2022, 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 "runtime/thread.hpp"
|
||||
#include "runtime/threadCrashProtection.hpp"
|
||||
|
||||
Thread* ThreadCrashProtection::_protected_thread = NULL;
|
||||
ThreadCrashProtection* ThreadCrashProtection::_crash_protection = NULL;
|
||||
|
||||
ThreadCrashProtection::ThreadCrashProtection() {
|
||||
_protected_thread = Thread::current();
|
||||
assert(_protected_thread->is_JfrSampler_thread(), "should be JFRSampler");
|
||||
}
|
||||
|
||||
/*
|
||||
* See the caveats for this class in threadCrashProtection_posix.hpp
|
||||
* Protects the callback call so that SIGSEGV / SIGBUS jumps back into this
|
||||
* method and returns false. If none of the signals are raised, returns true.
|
||||
* The callback is supposed to provide the method that should be protected.
|
||||
*/
|
||||
bool ThreadCrashProtection::call(CrashProtectionCallback& cb) {
|
||||
sigset_t saved_sig_mask;
|
||||
|
||||
// we cannot rely on sigsetjmp/siglongjmp to save/restore the signal mask
|
||||
// since on at least some systems (OS X) siglongjmp will restore the mask
|
||||
// for the process, not the thread
|
||||
pthread_sigmask(0, NULL, &saved_sig_mask);
|
||||
if (sigsetjmp(_jmpbuf, 0) == 0) {
|
||||
// make sure we can see in the signal handler that we have crash protection
|
||||
// installed
|
||||
_crash_protection = this;
|
||||
cb.call();
|
||||
// and clear the crash protection
|
||||
_crash_protection = NULL;
|
||||
_protected_thread = NULL;
|
||||
return true;
|
||||
}
|
||||
// this happens when we siglongjmp() back
|
||||
pthread_sigmask(SIG_SETMASK, &saved_sig_mask, NULL);
|
||||
_crash_protection = NULL;
|
||||
_protected_thread = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
void ThreadCrashProtection::restore() {
|
||||
assert(_crash_protection != NULL, "must have crash protection");
|
||||
siglongjmp(_jmpbuf, 1);
|
||||
}
|
||||
|
||||
void ThreadCrashProtection::check_crash_protection(int sig,
|
||||
Thread* thread) {
|
||||
|
||||
if (thread != NULL &&
|
||||
thread == _protected_thread &&
|
||||
_crash_protection != NULL) {
|
||||
|
||||
if (sig == SIGSEGV || sig == SIGBUS) {
|
||||
_crash_protection->restore();
|
||||
}
|
||||
}
|
||||
}
|
61
src/hotspot/os/posix/threadCrashProtection_posix.hpp
Normal file
61
src/hotspot/os/posix/threadCrashProtection_posix.hpp
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef OS_POSIX_THREADCRASHPROTECTION_POSIX_HPP
|
||||
#define OS_POSIX_THREADCRASHPROTECTION_POSIX_HPP
|
||||
|
||||
#include "memory/allocation.hpp"
|
||||
|
||||
#include <setjmp.h>
|
||||
|
||||
class CrashProtectionCallback;
|
||||
class Thread;
|
||||
|
||||
/*
|
||||
* Crash protection for the JfrSampler thread. Wrap the callback
|
||||
* with a sigsetjmp and in case of a SIGSEGV/SIGBUS we siglongjmp
|
||||
* back.
|
||||
* To be able to use this - don't take locks, don't rely on destructors,
|
||||
* don't make OS library calls, don't allocate memory, don't print,
|
||||
* don't call code that could leave the heap / memory in an inconsistent state,
|
||||
* or anything else where we are not in control if we suddenly jump out.
|
||||
*/
|
||||
class ThreadCrashProtection : public StackObj {
|
||||
public:
|
||||
static bool is_crash_protected(Thread* thr) {
|
||||
return _crash_protection != NULL && _protected_thread == thr;
|
||||
}
|
||||
|
||||
ThreadCrashProtection();
|
||||
bool call(CrashProtectionCallback& cb);
|
||||
|
||||
static void check_crash_protection(int signal, Thread* thread);
|
||||
private:
|
||||
static Thread* _protected_thread;
|
||||
static ThreadCrashProtection* _crash_protection;
|
||||
void restore();
|
||||
sigjmp_buf _jmpbuf;
|
||||
};
|
||||
|
||||
#endif // OS_POSIX_THREADCRASHPROTECTION_POSIX_HPP
|
64
src/hotspot/os/windows/mutex_windows.hpp
Normal file
64
src/hotspot/os/windows/mutex_windows.hpp
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef OS_WINDOWS_MUTEX_WINDOWS_HPP
|
||||
#define OS_WINDOWS_MUTEX_WINDOWS_HPP
|
||||
|
||||
#include "memory/allocation.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
|
||||
// Platform specific implementations that underpin VM Mutex/Monitor classes.
|
||||
// Note that CRITICAL_SECTION supports recursive locking, while the semantics
|
||||
// of the VM Mutex class does not. It is up to the Mutex class to hide this
|
||||
// difference in behaviour.
|
||||
|
||||
class PlatformMutex : public CHeapObj<mtSynchronizer> {
|
||||
NONCOPYABLE(PlatformMutex);
|
||||
|
||||
protected:
|
||||
CRITICAL_SECTION _mutex; // Native mutex for locking
|
||||
|
||||
public:
|
||||
PlatformMutex();
|
||||
~PlatformMutex();
|
||||
void lock();
|
||||
void unlock();
|
||||
bool try_lock();
|
||||
};
|
||||
|
||||
class PlatformMonitor : public PlatformMutex {
|
||||
private:
|
||||
CONDITION_VARIABLE _cond; // Native condition variable for blocking
|
||||
NONCOPYABLE(PlatformMonitor);
|
||||
|
||||
public:
|
||||
PlatformMonitor();
|
||||
~PlatformMonitor();
|
||||
int wait(jlong millis);
|
||||
void notify();
|
||||
void notify_all();
|
||||
};
|
||||
|
||||
#endif // OS_WINDOWS_MUTEX_WINDOWS_HPP
|
@ -55,6 +55,7 @@
|
||||
#include "runtime/objectMonitor.hpp"
|
||||
#include "runtime/orderAccess.hpp"
|
||||
#include "runtime/osThread.hpp"
|
||||
#include "runtime/park.hpp"
|
||||
#include "runtime/perfMemory.hpp"
|
||||
#include "runtime/safefetch.hpp"
|
||||
#include "runtime/safepointMechanism.hpp"
|
||||
@ -5099,35 +5100,6 @@ bool os::pd_unmap_memory(char* addr, size_t bytes) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Thread* os::ThreadCrashProtection::_protected_thread = NULL;
|
||||
os::ThreadCrashProtection* os::ThreadCrashProtection::_crash_protection = NULL;
|
||||
|
||||
os::ThreadCrashProtection::ThreadCrashProtection() {
|
||||
_protected_thread = Thread::current();
|
||||
assert(_protected_thread->is_JfrSampler_thread(), "should be JFRSampler");
|
||||
}
|
||||
|
||||
// See the caveats for this class in os_windows.hpp
|
||||
// Protects the callback call so that raised OS EXCEPTIONS causes a jump back
|
||||
// into this method and returns false. If no OS EXCEPTION was raised, returns
|
||||
// true.
|
||||
// The callback is supposed to provide the method that should be protected.
|
||||
//
|
||||
bool os::ThreadCrashProtection::call(os::CrashProtectionCallback& cb) {
|
||||
bool success = true;
|
||||
__try {
|
||||
_crash_protection = this;
|
||||
cb.call();
|
||||
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
||||
// only for protection, nothing to do
|
||||
success = false;
|
||||
}
|
||||
_crash_protection = NULL;
|
||||
_protected_thread = NULL;
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
class HighResolutionInterval : public CHeapObj<mtThread> {
|
||||
// The default timer resolution seems to be 10 milliseconds.
|
||||
// (Where is this written down?)
|
||||
@ -5225,7 +5197,7 @@ class HighResolutionInterval : public CHeapObj<mtThread> {
|
||||
// explicit "PARKED" == 01b and "SIGNALED" == 10b bits.
|
||||
//
|
||||
|
||||
int os::PlatformEvent::park(jlong Millis) {
|
||||
int PlatformEvent::park(jlong Millis) {
|
||||
// Transitions for _Event:
|
||||
// -1 => -1 : illegal
|
||||
// 1 => 0 : pass - return immediately
|
||||
@ -5282,7 +5254,7 @@ int os::PlatformEvent::park(jlong Millis) {
|
||||
}
|
||||
v = _Event;
|
||||
_Event = 0;
|
||||
// see comment at end of os::PlatformEvent::park() below:
|
||||
// see comment at end of PlatformEvent::park() below:
|
||||
OrderAccess::fence();
|
||||
// If we encounter a nearly simultaneous timeout expiry and unpark()
|
||||
// we return OS_OK indicating we awoke via unpark().
|
||||
@ -5290,7 +5262,7 @@ int os::PlatformEvent::park(jlong Millis) {
|
||||
return (v >= 0) ? OS_OK : OS_TIMEOUT;
|
||||
}
|
||||
|
||||
void os::PlatformEvent::park() {
|
||||
void PlatformEvent::park() {
|
||||
// Transitions for _Event:
|
||||
// -1 => -1 : illegal
|
||||
// 1 => 0 : pass - return immediately
|
||||
@ -5324,7 +5296,7 @@ void os::PlatformEvent::park() {
|
||||
guarantee(_Event >= 0, "invariant");
|
||||
}
|
||||
|
||||
void os::PlatformEvent::unpark() {
|
||||
void PlatformEvent::unpark() {
|
||||
guarantee(_ParkHandle != NULL, "Invariant");
|
||||
|
||||
// Transitions for _Event:
|
||||
@ -5397,7 +5369,7 @@ void Parker::unpark() {
|
||||
// Platform Monitor implementation
|
||||
|
||||
// Must already be locked
|
||||
int os::PlatformMonitor::wait(jlong millis) {
|
||||
int PlatformMonitor::wait(jlong millis) {
|
||||
assert(millis >= 0, "negative timeout");
|
||||
int ret = OS_TIMEOUT;
|
||||
int status = SleepConditionVariableCS(&_cond, &_mutex,
|
||||
|
@ -133,99 +133,4 @@ public:
|
||||
static inline int get_thread_ptr_offset() { return _thread_ptr_offset; }
|
||||
};
|
||||
|
||||
/*
|
||||
* Crash protection for the JfrSampler thread. Wrap the callback
|
||||
* with a __try { call() }
|
||||
* To be able to use this - don't take locks, don't rely on destructors,
|
||||
* don't make OS library calls, don't allocate memory, don't print,
|
||||
* don't call code that could leave the heap / memory in an inconsistent state,
|
||||
* or anything else where we are not in control if we suddenly jump out.
|
||||
*/
|
||||
class ThreadCrashProtection : public StackObj {
|
||||
public:
|
||||
static bool is_crash_protected(Thread* thr) {
|
||||
return _crash_protection != NULL && _protected_thread == thr;
|
||||
}
|
||||
|
||||
ThreadCrashProtection();
|
||||
bool call(os::CrashProtectionCallback& cb);
|
||||
private:
|
||||
static Thread* _protected_thread;
|
||||
static ThreadCrashProtection* _crash_protection;
|
||||
};
|
||||
|
||||
class PlatformEvent : public CHeapObj<mtSynchronizer> {
|
||||
private:
|
||||
double CachePad [4] ; // increase odds that _Event is sole occupant of cache line
|
||||
volatile int _Event ;
|
||||
HANDLE _ParkHandle ;
|
||||
|
||||
public: // TODO-FIXME: make dtor private
|
||||
~PlatformEvent() { guarantee (0, "invariant") ; }
|
||||
|
||||
public:
|
||||
PlatformEvent() {
|
||||
_Event = 0 ;
|
||||
_ParkHandle = CreateEvent (NULL, false, false, NULL) ;
|
||||
guarantee (_ParkHandle != NULL, "invariant") ;
|
||||
}
|
||||
|
||||
// Exercise caution using reset() and fired() - they may require MEMBARs
|
||||
void reset() { _Event = 0 ; }
|
||||
int fired() { return _Event; }
|
||||
void park () ;
|
||||
void unpark () ;
|
||||
int park (jlong millis) ;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
class PlatformParker {
|
||||
NONCOPYABLE(PlatformParker);
|
||||
|
||||
protected:
|
||||
HANDLE _ParkHandle;
|
||||
|
||||
public:
|
||||
PlatformParker() {
|
||||
_ParkHandle = CreateEvent (NULL, true, false, NULL) ;
|
||||
guarantee(_ParkHandle != NULL, "invariant") ;
|
||||
}
|
||||
~PlatformParker() {
|
||||
CloseHandle(_ParkHandle);
|
||||
}
|
||||
};
|
||||
|
||||
// Platform specific implementations that underpin VM Mutex/Monitor classes.
|
||||
// Note that CRITICAL_SECTION supports recursive locking, while the semantics
|
||||
// of the VM Mutex class does not. It is up to the Mutex class to hide this
|
||||
// difference in behaviour.
|
||||
|
||||
class PlatformMutex : public CHeapObj<mtSynchronizer> {
|
||||
NONCOPYABLE(PlatformMutex);
|
||||
|
||||
protected:
|
||||
CRITICAL_SECTION _mutex; // Native mutex for locking
|
||||
|
||||
public:
|
||||
PlatformMutex();
|
||||
~PlatformMutex();
|
||||
void lock();
|
||||
void unlock();
|
||||
bool try_lock();
|
||||
};
|
||||
|
||||
class PlatformMonitor : public PlatformMutex {
|
||||
private:
|
||||
CONDITION_VARIABLE _cond; // Native condition variable for blocking
|
||||
NONCOPYABLE(PlatformMonitor);
|
||||
|
||||
public:
|
||||
PlatformMonitor();
|
||||
~PlatformMonitor();
|
||||
int wait(jlong millis);
|
||||
void notify();
|
||||
void notify_all();
|
||||
};
|
||||
|
||||
#endif // OS_WINDOWS_OS_WINDOWS_HPP
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2022, 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
|
||||
@ -28,6 +28,7 @@
|
||||
// os_windows.hpp included by os.hpp
|
||||
|
||||
#include "runtime/javaThread.hpp"
|
||||
#include "runtime/mutex.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
|
||||
inline bool os::uses_stack_guard_pages() {
|
||||
@ -57,39 +58,39 @@ inline bool os::numa_has_group_homing() { return false; }
|
||||
|
||||
// Platform Mutex/Monitor implementation
|
||||
|
||||
inline os::PlatformMutex::PlatformMutex() {
|
||||
inline PlatformMutex::PlatformMutex() {
|
||||
InitializeCriticalSection(&_mutex);
|
||||
}
|
||||
|
||||
inline os::PlatformMutex::~PlatformMutex() {
|
||||
inline PlatformMutex::~PlatformMutex() {
|
||||
DeleteCriticalSection(&_mutex);
|
||||
}
|
||||
|
||||
inline os::PlatformMonitor::PlatformMonitor() {
|
||||
inline PlatformMonitor::PlatformMonitor() {
|
||||
InitializeConditionVariable(&_cond);
|
||||
}
|
||||
|
||||
inline os::PlatformMonitor::~PlatformMonitor() {
|
||||
inline PlatformMonitor::~PlatformMonitor() {
|
||||
// There is no DeleteConditionVariable API
|
||||
}
|
||||
|
||||
inline void os::PlatformMutex::lock() {
|
||||
inline void PlatformMutex::lock() {
|
||||
EnterCriticalSection(&_mutex);
|
||||
}
|
||||
|
||||
inline void os::PlatformMutex::unlock() {
|
||||
inline void PlatformMutex::unlock() {
|
||||
LeaveCriticalSection(&_mutex);
|
||||
}
|
||||
|
||||
inline bool os::PlatformMutex::try_lock() {
|
||||
inline bool PlatformMutex::try_lock() {
|
||||
return TryEnterCriticalSection(&_mutex);
|
||||
}
|
||||
|
||||
inline void os::PlatformMonitor::notify() {
|
||||
inline void PlatformMonitor::notify() {
|
||||
WakeConditionVariable(&_cond);
|
||||
}
|
||||
|
||||
inline void os::PlatformMonitor::notify_all() {
|
||||
inline void PlatformMonitor::notify_all() {
|
||||
WakeAllConditionVariable(&_cond);
|
||||
}
|
||||
|
||||
|
72
src/hotspot/os/windows/park_windows.hpp
Normal file
72
src/hotspot/os/windows/park_windows.hpp
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef OS_WINDOWS_PARK_WINDOWS_HPP
|
||||
#define OS_WINDOWS_PARK_WINDOWS_HPP
|
||||
|
||||
#include "memory/allocation.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
|
||||
class PlatformEvent : public CHeapObj<mtSynchronizer> {
|
||||
private:
|
||||
double CachePad [4] ; // increase odds that _Event is sole occupant of cache line
|
||||
volatile int _Event ;
|
||||
HANDLE _ParkHandle ;
|
||||
|
||||
public: // TODO-FIXME: make dtor private
|
||||
~PlatformEvent() { guarantee (0, "invariant") ; }
|
||||
|
||||
public:
|
||||
PlatformEvent() {
|
||||
_Event = 0 ;
|
||||
_ParkHandle = CreateEvent (NULL, false, false, NULL) ;
|
||||
guarantee (_ParkHandle != NULL, "invariant") ;
|
||||
}
|
||||
|
||||
// Exercise caution using reset() and fired() - they may require MEMBARs
|
||||
void reset() { _Event = 0 ; }
|
||||
int fired() { return _Event; }
|
||||
void park () ;
|
||||
void unpark () ;
|
||||
int park (jlong millis) ;
|
||||
};
|
||||
|
||||
class PlatformParker {
|
||||
NONCOPYABLE(PlatformParker);
|
||||
|
||||
protected:
|
||||
HANDLE _ParkHandle;
|
||||
|
||||
public:
|
||||
PlatformParker() {
|
||||
_ParkHandle = CreateEvent (NULL, true, false, NULL) ;
|
||||
guarantee(_ParkHandle != NULL, "invariant") ;
|
||||
}
|
||||
~PlatformParker() {
|
||||
CloseHandle(_ParkHandle);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // OS_WINDOWS_PARK_WINDOWS_HPP
|
55
src/hotspot/os/windows/threadCrashProtection_windows.cpp
Normal file
55
src/hotspot/os/windows/threadCrashProtection_windows.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2022, 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 "runtime/thread.hpp"
|
||||
#include "runtime/threadCrashProtection.hpp"
|
||||
|
||||
Thread* ThreadCrashProtection::_protected_thread = NULL;
|
||||
ThreadCrashProtection* ThreadCrashProtection::_crash_protection = NULL;
|
||||
|
||||
ThreadCrashProtection::ThreadCrashProtection() {
|
||||
_protected_thread = Thread::current();
|
||||
assert(_protected_thread->is_JfrSampler_thread(), "should be JFRSampler");
|
||||
}
|
||||
|
||||
// See the caveats for this class in os_windows.hpp
|
||||
// Protects the callback call so that raised OS EXCEPTIONS causes a jump back
|
||||
// into this method and returns false. If no OS EXCEPTION was raised, returns
|
||||
// true.
|
||||
// The callback is supposed to provide the method that should be protected.
|
||||
//
|
||||
bool ThreadCrashProtection::call(CrashProtectionCallback& cb) {
|
||||
bool success = true;
|
||||
__try {
|
||||
_crash_protection = this;
|
||||
cb.call();
|
||||
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
||||
// only for protection, nothing to do
|
||||
success = false;
|
||||
}
|
||||
_crash_protection = NULL;
|
||||
_protected_thread = NULL;
|
||||
return success;
|
||||
}
|
54
src/hotspot/os/windows/threadCrashProtection_windows.hpp
Normal file
54
src/hotspot/os/windows/threadCrashProtection_windows.hpp
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef OS_WINDOWS_THREADCRASHPROTECTION_WINDOWS_HPP
|
||||
#define OS_WINDOWS_THREADCRASHPROTECTION_WINDOWS_HPP
|
||||
|
||||
#include "memory/allocation.hpp"
|
||||
|
||||
class CrashProtectionCallback;
|
||||
class Thread;
|
||||
|
||||
/*
|
||||
* Crash protection for the JfrSampler thread. Wrap the callback
|
||||
* with a __try { call() }
|
||||
* To be able to use this - don't take locks, don't rely on destructors,
|
||||
* don't make OS library calls, don't allocate memory, don't print,
|
||||
* don't call code that could leave the heap / memory in an inconsistent state,
|
||||
* or anything else where we are not in control if we suddenly jump out.
|
||||
*/
|
||||
class ThreadCrashProtection : public StackObj {
|
||||
public:
|
||||
static bool is_crash_protected(Thread* thr) {
|
||||
return _crash_protection != NULL && _protected_thread == thr;
|
||||
}
|
||||
|
||||
ThreadCrashProtection();
|
||||
bool call(CrashProtectionCallback& cb);
|
||||
private:
|
||||
static Thread* _protected_thread;
|
||||
static ThreadCrashProtection* _crash_protection;
|
||||
};
|
||||
|
||||
#endif // OS_WINDOWS_THREADCRASHPROTECTION_WINDOWS_HPP
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2022, 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
|
||||
@ -25,6 +25,7 @@
|
||||
#include "gc/shared/gcLogPrecious.hpp"
|
||||
#include "runtime/mutex.hpp"
|
||||
#include "runtime/mutexLocker.hpp"
|
||||
#include "utilities/ostream.hpp"
|
||||
|
||||
stringStream* GCLogPrecious::_lines = NULL;
|
||||
stringStream* GCLogPrecious::_temp = NULL;
|
||||
|
@ -92,7 +92,7 @@ public:
|
||||
|
||||
class ShenandoahSimpleLock {
|
||||
private:
|
||||
os::PlatformMonitor _lock; // native lock
|
||||
PlatformMonitor _lock; // native lock
|
||||
public:
|
||||
ShenandoahSimpleLock();
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2022, 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
|
||||
@ -25,11 +25,11 @@
|
||||
#define SHARE_GC_Z_ZLOCK_HPP
|
||||
|
||||
#include "memory/allocation.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/mutex.hpp"
|
||||
|
||||
class ZLock {
|
||||
private:
|
||||
os::PlatformMutex _lock;
|
||||
PlatformMutex _lock;
|
||||
|
||||
public:
|
||||
void lock();
|
||||
@ -54,7 +54,7 @@ public:
|
||||
|
||||
class ZConditionLock {
|
||||
private:
|
||||
os::PlatformMonitor _lock;
|
||||
PlatformMonitor _lock;
|
||||
|
||||
public:
|
||||
void lock();
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "runtime/javaThread.inline.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/semaphore.hpp"
|
||||
#include "runtime/threadCrashProtection.hpp"
|
||||
#include "runtime/threadSMR.hpp"
|
||||
|
||||
enum JfrSampleType {
|
||||
@ -141,7 +142,7 @@ class OSThreadSampler : public os::SuspendedThreadTask {
|
||||
JfrTicks _suspend_time;
|
||||
};
|
||||
|
||||
class OSThreadSamplerCallback : public os::CrashProtectionCallback {
|
||||
class OSThreadSamplerCallback : public CrashProtectionCallback {
|
||||
public:
|
||||
OSThreadSamplerCallback(OSThreadSampler& sampler, const os::SuspendedThreadTaskContext &context) :
|
||||
_sampler(sampler), _context(context) {
|
||||
@ -163,7 +164,7 @@ void OSThreadSampler::do_task(const os::SuspendedThreadTaskContext& context) {
|
||||
|
||||
if (JfrOptionSet::sample_protection()) {
|
||||
OSThreadSamplerCallback cb(*this, context);
|
||||
os::ThreadCrashProtection crash_protection;
|
||||
ThreadCrashProtection crash_protection;
|
||||
if (!crash_protection.call(cb)) {
|
||||
log_error(jfr)("Thread method sampler crashed");
|
||||
}
|
||||
@ -204,7 +205,7 @@ void OSThreadSampler::take_sample() {
|
||||
run();
|
||||
}
|
||||
|
||||
class JfrNativeSamplerCallback : public os::CrashProtectionCallback {
|
||||
class JfrNativeSamplerCallback : public CrashProtectionCallback {
|
||||
public:
|
||||
JfrNativeSamplerCallback(JfrThreadSampleClosure& closure, JavaThread* jt, JfrStackFrame* frames, u4 max_frames) :
|
||||
_closure(closure), _jt(jt), _thread_oop(jt->threadObj()), _stacktrace(frames, max_frames), _success(false) {
|
||||
@ -272,7 +273,7 @@ bool JfrThreadSampleClosure::sample_thread_in_java(JavaThread* thread, JfrStackF
|
||||
bool JfrThreadSampleClosure::sample_thread_in_native(JavaThread* thread, JfrStackFrame* frames, u4 max_frames) {
|
||||
JfrNativeSamplerCallback cb(*this, thread, frames, max_frames);
|
||||
if (JfrOptionSet::sample_protection()) {
|
||||
os::ThreadCrashProtection crash_protection;
|
||||
ThreadCrashProtection crash_protection;
|
||||
if (!crash_protection.call(cb)) {
|
||||
log_error(jfr)("Thread method sampler crashed for native");
|
||||
}
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "logging/logDecorations.hpp"
|
||||
#include "logging/logMessageBuffer.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "runtime/mutex.hpp"
|
||||
#include "runtime/nonJavaThread.hpp"
|
||||
#include "runtime/semaphore.hpp"
|
||||
#include "utilities/resourceHash.hpp"
|
||||
@ -144,7 +145,7 @@ class AsyncLogWriter : public NonJavaThread {
|
||||
static AsyncLogWriter* _instance;
|
||||
Semaphore _flush_sem;
|
||||
// Can't use a Monitor here as we need a low-level API that can be used without Thread::current().
|
||||
os::PlatformMonitor _lock;
|
||||
PlatformMonitor _lock;
|
||||
bool _data_available;
|
||||
volatile bool _initialized;
|
||||
AsyncLogMap _stats; // statistics for dropped messages
|
||||
|
@ -30,9 +30,11 @@
|
||||
#include "memory/metaspace/metaspaceSettings.hpp"
|
||||
#include "memory/metaspace/virtualSpaceNode.hpp"
|
||||
#include "runtime/mutexLocker.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "utilities/align.hpp"
|
||||
#include "utilities/copy.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
#include "utilities/ostream.hpp"
|
||||
|
||||
namespace metaspace {
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "runtime/mutexLocker.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
#include "utilities/ostream.hpp"
|
||||
|
||||
namespace metaspace {
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2021 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -29,6 +29,7 @@
|
||||
#include "memory/metaspace/metaspaceContext.hpp"
|
||||
#include "memory/metaspace/testHelpers.hpp"
|
||||
#include "runtime/mutexLocker.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
#include "utilities/ostream.hpp"
|
||||
|
@ -3517,26 +3517,26 @@ JVM_END
|
||||
|
||||
JNIEXPORT void* JNICALL JVM_RawMonitorCreate(void) {
|
||||
VM_Exit::block_if_vm_exited();
|
||||
return new os::PlatformMutex();
|
||||
return new PlatformMutex();
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT void JNICALL JVM_RawMonitorDestroy(void *mon) {
|
||||
VM_Exit::block_if_vm_exited();
|
||||
delete ((os::PlatformMutex*) mon);
|
||||
delete ((PlatformMutex*) mon);
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jint JNICALL JVM_RawMonitorEnter(void *mon) {
|
||||
VM_Exit::block_if_vm_exited();
|
||||
((os::PlatformMutex*) mon)->lock();
|
||||
((PlatformMutex*) mon)->lock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT void JNICALL JVM_RawMonitorExit(void *mon) {
|
||||
VM_Exit::block_if_vm_exited();
|
||||
((os::PlatformMutex*) mon)->unlock();
|
||||
((PlatformMutex*) mon)->unlock();
|
||||
}
|
||||
|
||||
|
||||
|
@ -26,9 +26,11 @@
|
||||
#define SHARE_PRIMS_JVMTIRAWMONITOR_HPP
|
||||
|
||||
#include "memory/allocation.hpp"
|
||||
#include "runtime/park.hpp"
|
||||
#include "utilities/growableArray.hpp"
|
||||
|
||||
class ParkEvent;
|
||||
class Thread;
|
||||
|
||||
//
|
||||
// class JvmtiRawMonitor
|
||||
//
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2022, 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,6 +31,7 @@
|
||||
#include "runtime/os.inline.hpp"
|
||||
#include "runtime/osThread.hpp"
|
||||
#include "runtime/safepointMechanism.inline.hpp"
|
||||
#include "runtime/threadCrashProtection.hpp"
|
||||
#include "utilities/events.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
|
||||
@ -56,7 +57,7 @@ void Mutex::check_block_state(Thread* thread) {
|
||||
fatal("VM thread could block on lock that may be held by a JavaThread during safepoint: %s", name());
|
||||
}
|
||||
|
||||
assert(!os::ThreadCrashProtection::is_crash_protected(thread),
|
||||
assert(!ThreadCrashProtection::is_crash_protected(thread),
|
||||
"locking not allowed when crash protection is set");
|
||||
}
|
||||
|
||||
@ -355,6 +356,10 @@ void Mutex::print_on(outputStream* st) const {
|
||||
DEBUG_ONLY(st->print(" %s", rank_name()));
|
||||
st->cr();
|
||||
}
|
||||
|
||||
void Mutex::print() const {
|
||||
print_on(::tty);
|
||||
}
|
||||
#endif // PRODUCT
|
||||
|
||||
#ifdef ASSERT
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2022, 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
|
||||
@ -27,7 +27,13 @@
|
||||
|
||||
#include "memory/allocation.hpp"
|
||||
#include "runtime/atomic.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
|
||||
#if defined(LINUX) || defined(AIX) || defined(BSD)
|
||||
# include "mutex_posix.hpp"
|
||||
#else
|
||||
# include OS_HEADER(mutex)
|
||||
#endif
|
||||
|
||||
|
||||
// A Mutex/Monitor is a simple wrapper around a native lock plus condition
|
||||
// variable that supports lock ownership tracking, lock ranking for deadlock
|
||||
@ -89,7 +95,7 @@ class Mutex : public CHeapObj<mtSynchronizer> {
|
||||
void raw_set_owner(Thread* new_owner) { Atomic::store(&_owner, new_owner); }
|
||||
|
||||
protected: // Monitor-Mutex metadata
|
||||
os::PlatformMonitor _lock; // Native monitor implementation
|
||||
PlatformMonitor _lock; // Native monitor implementation
|
||||
const char* _name; // Name of mutex/monitor
|
||||
|
||||
// Debugging fields for naming, deadlock detection, etc. (some only used in debug mode)
|
||||
@ -192,7 +198,7 @@ class Mutex : public CHeapObj<mtSynchronizer> {
|
||||
void print_on_error(outputStream* st) const;
|
||||
#ifndef PRODUCT
|
||||
void print_on(outputStream* st) const;
|
||||
void print() const { print_on(::tty); }
|
||||
void print() const;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -29,11 +29,10 @@
|
||||
#include "memory/padded.hpp"
|
||||
#include "oops/markWord.hpp"
|
||||
#include "oops/weakHandle.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/park.hpp"
|
||||
#include "runtime/perfDataTypes.hpp"
|
||||
|
||||
class ObjectMonitor;
|
||||
class ParkEvent;
|
||||
|
||||
// ObjectWaiter serves as a "proxy" or surrogate thread.
|
||||
// TODO-FIXME: Eliminate ObjectWaiter and use the thread-specific
|
||||
|
@ -57,6 +57,7 @@
|
||||
#include "runtime/osThread.hpp"
|
||||
#include "runtime/safefetch.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "runtime/threadCrashProtection.hpp"
|
||||
#include "runtime/threadSMR.hpp"
|
||||
#include "runtime/vmOperations.hpp"
|
||||
#include "runtime/vm_version.hpp"
|
||||
@ -618,7 +619,7 @@ static bool has_reached_max_malloc_test_peak(size_t alloc_size) {
|
||||
|
||||
#ifdef ASSERT
|
||||
static void check_crash_protection() {
|
||||
assert(!os::ThreadCrashProtection::is_crash_protected(Thread::current_or_null()),
|
||||
assert(!ThreadCrashProtection::is_crash_protected(Thread::current_or_null()),
|
||||
"not allowed when crash protection is set");
|
||||
}
|
||||
static void break_if_ptr_caught(void* ptr) {
|
||||
|
@ -30,9 +30,6 @@
|
||||
#include "utilities/exceptions.hpp"
|
||||
#include "utilities/ostream.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#ifndef _WINDOWS
|
||||
# include <setjmp.h>
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
# include <mach/mach_time.h>
|
||||
#endif
|
||||
@ -872,10 +869,6 @@ class os: AllStatic {
|
||||
static bool supports_map_sync();
|
||||
|
||||
public:
|
||||
class CrashProtectionCallback : public StackObj {
|
||||
public:
|
||||
virtual void call() = 0;
|
||||
};
|
||||
|
||||
// Platform dependent stuff
|
||||
#ifndef _WINDOWS
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2022, 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
|
||||
@ -29,6 +29,7 @@
|
||||
#include "runtime/handles.hpp"
|
||||
#include "runtime/javaFrameAnchor.hpp"
|
||||
#include "runtime/objectMonitor.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
|
||||
class Monitor;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2022, 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
|
||||
@ -28,6 +28,14 @@
|
||||
#include "utilities/debug.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
|
||||
#if defined(LINUX) || defined(AIX) || defined(BSD)
|
||||
# include "park_posix.hpp"
|
||||
#else
|
||||
# include OS_HEADER(park)
|
||||
#endif
|
||||
|
||||
class Thread;
|
||||
|
||||
/*
|
||||
* Per-thread blocking support for JSR166. See the Java-level
|
||||
* documentation for rationale. Basically, park acts like wait, unpark
|
||||
@ -39,7 +47,7 @@
|
||||
* ThreadsListHandle.
|
||||
*
|
||||
* Class Parker is declared in shared code and extends the platform-specific
|
||||
* os::PlatformParker class, which contains the actual implementation
|
||||
* PlatformParker class, which contains the actual implementation
|
||||
* mechanics (condvars/events etc). The implementation for park() and unpark()
|
||||
* are also in the platform-specific os_<os>.cpp files.
|
||||
*
|
||||
@ -49,7 +57,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
class Parker : public os::PlatformParker {
|
||||
class Parker : public PlatformParker {
|
||||
private:
|
||||
NONCOPYABLE(Parker);
|
||||
public:
|
||||
@ -102,7 +110,7 @@ class Parker : public os::PlatformParker {
|
||||
// We'll want to eventually merge these redundant facilities and use ParkEvent.
|
||||
|
||||
|
||||
class ParkEvent : public os::PlatformEvent {
|
||||
class ParkEvent : public PlatformEvent {
|
||||
private:
|
||||
ParkEvent * FreeNext ;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2022, 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
|
||||
@ -30,12 +30,8 @@
|
||||
|
||||
#if defined(LINUX) || defined(AIX)
|
||||
# include "semaphore_posix.hpp"
|
||||
#elif defined(BSD)
|
||||
# include "semaphore_bsd.hpp"
|
||||
#elif defined(_WINDOWS)
|
||||
# include "semaphore_windows.hpp"
|
||||
#else
|
||||
# error "No semaphore implementation provided for this OS"
|
||||
# include OS_HEADER(semaphore)
|
||||
#endif
|
||||
|
||||
class JavaThread;
|
||||
|
@ -240,11 +240,11 @@ int dtrace_waited_probe(ObjectMonitor* monitor, Handle obj, Thread* thr) {
|
||||
}
|
||||
|
||||
static const int NINFLATIONLOCKS = 256;
|
||||
static os::PlatformMutex* gInflationLocks[NINFLATIONLOCKS];
|
||||
static PlatformMutex* gInflationLocks[NINFLATIONLOCKS];
|
||||
|
||||
void ObjectSynchronizer::initialize() {
|
||||
for (int i = 0; i < NINFLATIONLOCKS; i++) {
|
||||
gInflationLocks[i] = new os::PlatformMutex();
|
||||
gInflationLocks[i] = new PlatformMutex();
|
||||
}
|
||||
// Start the ceiling with the estimate for one thread.
|
||||
set_in_use_list_ceiling(AvgMonitorsPerThreadEstimate);
|
||||
|
42
src/hotspot/share/runtime/threadCrashProtection.hpp
Normal file
42
src/hotspot/share/runtime/threadCrashProtection.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SHARE_RUNTIME_THREADCRASHPROTECTION_HPP
|
||||
#define SHARE_RUNTIME_THREADCRASHPROTECTION_HPP
|
||||
|
||||
#include "memory/allocation.hpp"
|
||||
|
||||
class CrashProtectionCallback : public StackObj {
|
||||
public:
|
||||
virtual void call() = 0;
|
||||
};
|
||||
|
||||
#if defined(LINUX) || defined(AIX) || defined(BSD)
|
||||
# include "threadCrashProtection_posix.hpp"
|
||||
#else
|
||||
# include OS_HEADER(threadCrashProtection)
|
||||
#endif
|
||||
|
||||
#endif // SHARE_RUNTIME_THREADCRASHPROTECTION_HPP
|
Loading…
x
Reference in New Issue
Block a user