8289230: Move PlatformXXX class declarations out of os_xxx.hpp

Reviewed-by: coleenp, ccheung
This commit is contained in:
Ioi Lam 2022-07-02 14:45:10 +00:00
parent 44e8c462b4
commit cdf6979259
36 changed files with 782 additions and 469 deletions

View File

@ -23,6 +23,7 @@
*/
#include "jvm.h"
#include "runtime/os.hpp"
#include "utilities/decoder_elf.hpp"
#include "utilities/elfFile.hpp"

View 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

View File

@ -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;

View File

@ -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

View File

@ -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");
}

View 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

View File

@ -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;

View 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();
}
}
}

View 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

View 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

View File

@ -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,

View File

@ -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

View File

@ -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);
}

View 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

View 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;
}

View 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

View File

@ -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;

View File

@ -92,7 +92,7 @@ public:
class ShenandoahSimpleLock {
private:
os::PlatformMonitor _lock; // native lock
PlatformMonitor _lock; // native lock
public:
ShenandoahSimpleLock();

View File

@ -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();

View File

@ -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");
}

View File

@ -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

View File

@ -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 {

View File

@ -35,6 +35,7 @@
#include "runtime/mutexLocker.hpp"
#include "utilities/debug.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/ostream.hpp"
namespace metaspace {

View File

@ -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"

View File

@ -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();
}

View File

@ -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
//

View File

@ -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

View File

@ -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
};

View File

@ -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

View File

@ -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) {

View File

@ -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

View File

@ -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;

View File

@ -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 ;

View File

@ -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;

View File

@ -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);

View 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