8265754: Move suspend/resume API from HandshakeState
Reviewed-by: coleenp, dholmes, pchilanomate
This commit is contained in:
parent
bf7d40d048
commit
42ab8fcfb9
@ -465,9 +465,7 @@ HandshakeState::HandshakeState(JavaThread* target) :
|
||||
_queue(),
|
||||
_lock(Monitor::nosafepoint, "HandshakeState_lock"),
|
||||
_active_handshaker(),
|
||||
_async_exceptions_blocked(false),
|
||||
_suspended(false),
|
||||
_async_suspend_handshake(false) {
|
||||
_async_exceptions_blocked(false) {
|
||||
}
|
||||
|
||||
HandshakeState::~HandshakeState() {
|
||||
@ -699,128 +697,8 @@ HandshakeState::ProcessResult HandshakeState::try_process(HandshakeOperation* ma
|
||||
return op == match_op ? HandshakeState::_succeeded : HandshakeState::_processed;
|
||||
}
|
||||
|
||||
void HandshakeState::do_self_suspend() {
|
||||
assert(Thread::current() == _handshakee, "should call from _handshakee");
|
||||
assert(_lock.owned_by_self(), "Lock must be held");
|
||||
assert(!_handshakee->has_last_Java_frame() || _handshakee->frame_anchor()->walkable(), "should have walkable stack");
|
||||
assert(_handshakee->thread_state() == _thread_blocked, "Caller should have transitioned to _thread_blocked");
|
||||
|
||||
while (is_suspended()) {
|
||||
log_trace(thread, suspend)("JavaThread:" INTPTR_FORMAT " suspended", p2i(_handshakee));
|
||||
_lock.wait_without_safepoint_check();
|
||||
}
|
||||
log_trace(thread, suspend)("JavaThread:" INTPTR_FORMAT " resumed", p2i(_handshakee));
|
||||
}
|
||||
|
||||
// This is the closure that prevents a suspended JavaThread from
|
||||
// escaping the suspend request.
|
||||
class ThreadSelfSuspensionHandshake : public AsyncHandshakeClosure {
|
||||
public:
|
||||
ThreadSelfSuspensionHandshake() : AsyncHandshakeClosure("ThreadSelfSuspensionHandshake") {}
|
||||
void do_thread(Thread* thr) {
|
||||
JavaThread* current = JavaThread::cast(thr);
|
||||
assert(current == Thread::current(), "Must be self executed.");
|
||||
JavaThreadState jts = current->thread_state();
|
||||
|
||||
current->set_thread_state(_thread_blocked);
|
||||
current->handshake_state()->do_self_suspend();
|
||||
current->set_thread_state(jts);
|
||||
current->handshake_state()->set_async_suspend_handshake(false);
|
||||
}
|
||||
virtual bool is_suspend() { return true; }
|
||||
};
|
||||
|
||||
bool HandshakeState::suspend_with_handshake(bool register_vthread_SR) {
|
||||
assert(_handshakee->threadObj() != nullptr, "cannot suspend with a null threadObj");
|
||||
if (_handshakee->is_exiting()) {
|
||||
log_trace(thread, suspend)("JavaThread:" INTPTR_FORMAT " exiting", p2i(_handshakee));
|
||||
return false;
|
||||
}
|
||||
if (has_async_suspend_handshake()) {
|
||||
if (is_suspended()) {
|
||||
// Target is already suspended.
|
||||
log_trace(thread, suspend)("JavaThread:" INTPTR_FORMAT " already suspended", p2i(_handshakee));
|
||||
return false;
|
||||
} else {
|
||||
// Target is going to wake up and leave suspension.
|
||||
// Let's just stop the thread from doing that.
|
||||
log_trace(thread, suspend)("JavaThread:" INTPTR_FORMAT " re-suspended", p2i(_handshakee));
|
||||
set_suspended(true, register_vthread_SR);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// no suspend request
|
||||
assert(!is_suspended(), "cannot be suspended without a suspend request");
|
||||
// Thread is safe, so it must execute the request, thus we can count it as suspended
|
||||
// from this point.
|
||||
set_suspended(true, register_vthread_SR);
|
||||
set_async_suspend_handshake(true);
|
||||
log_trace(thread, suspend)("JavaThread:" INTPTR_FORMAT " suspended, arming ThreadSuspension", p2i(_handshakee));
|
||||
ThreadSelfSuspensionHandshake* ts = new ThreadSelfSuspensionHandshake();
|
||||
Handshake::execute(ts, _handshakee);
|
||||
return true;
|
||||
}
|
||||
|
||||
// This is the closure that synchronously honors the suspend request.
|
||||
class SuspendThreadHandshake : public HandshakeClosure {
|
||||
bool _register_vthread_SR;
|
||||
bool _did_suspend;
|
||||
public:
|
||||
SuspendThreadHandshake(bool register_vthread_SR) : HandshakeClosure("SuspendThread"),
|
||||
_register_vthread_SR(register_vthread_SR), _did_suspend(false) {}
|
||||
void do_thread(Thread* thr) {
|
||||
JavaThread* target = JavaThread::cast(thr);
|
||||
_did_suspend = target->handshake_state()->suspend_with_handshake(_register_vthread_SR);
|
||||
}
|
||||
bool did_suspend() { return _did_suspend; }
|
||||
};
|
||||
|
||||
bool HandshakeState::suspend(bool register_vthread_SR) {
|
||||
JVMTI_ONLY(assert(!_handshakee->is_in_VTMS_transition(), "no suspend allowed in VTMS transition");)
|
||||
JavaThread* self = JavaThread::current();
|
||||
if (_handshakee == self) {
|
||||
// If target is the current thread we can bypass the handshake machinery
|
||||
// and just suspend directly
|
||||
ThreadBlockInVM tbivm(self);
|
||||
MutexLocker ml(&_lock, Mutex::_no_safepoint_check_flag);
|
||||
set_suspended(true, register_vthread_SR);
|
||||
do_self_suspend();
|
||||
return true;
|
||||
} else {
|
||||
SuspendThreadHandshake st(register_vthread_SR);
|
||||
Handshake::execute(&st, _handshakee);
|
||||
return st.did_suspend();
|
||||
}
|
||||
}
|
||||
|
||||
bool HandshakeState::resume(bool register_vthread_SR) {
|
||||
MutexLocker ml(&_lock, Mutex::_no_safepoint_check_flag);
|
||||
if (!is_suspended()) {
|
||||
assert(!_handshakee->is_suspended(), "cannot be suspended without a suspend request");
|
||||
return false;
|
||||
}
|
||||
// Resume the thread.
|
||||
set_suspended(false, register_vthread_SR);
|
||||
_lock.notify();
|
||||
return true;
|
||||
}
|
||||
|
||||
void HandshakeState::set_suspended(bool is_suspend, bool register_vthread_SR) {
|
||||
#if INCLUDE_JVMTI
|
||||
if (register_vthread_SR) {
|
||||
assert(_handshakee->is_vthread_mounted(), "sanity check");
|
||||
if (is_suspend) {
|
||||
JvmtiVTSuspender::register_vthread_suspend(_handshakee->vthread());
|
||||
} else {
|
||||
JvmtiVTSuspender::register_vthread_resume(_handshakee->vthread());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Atomic::store(&_suspended, is_suspend);
|
||||
}
|
||||
|
||||
void HandshakeState::handle_unsafe_access_error() {
|
||||
if (is_suspended()) {
|
||||
if (_handshakee->is_suspended()) {
|
||||
// A suspend handshake was added to the queue after the
|
||||
// unsafe access error. Since the suspender has already
|
||||
// considered this JT as suspended and assumes it won't go
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2017, 2025, 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
|
||||
@ -35,8 +35,6 @@
|
||||
class HandshakeOperation;
|
||||
class AsyncHandshakeOperation;
|
||||
class JavaThread;
|
||||
class SuspendThreadHandshake;
|
||||
class ThreadSelfSuspensionHandshake;
|
||||
class UnsafeAccessErrorHandshake;
|
||||
class ThreadsListHandle;
|
||||
|
||||
@ -88,8 +86,6 @@ class JvmtiRawMonitor;
|
||||
// operation is only done by either VMThread/Handshaker on behalf of the
|
||||
// JavaThread or by the target JavaThread itself.
|
||||
class HandshakeState {
|
||||
friend ThreadSelfSuspensionHandshake;
|
||||
friend SuspendThreadHandshake;
|
||||
friend UnsafeAccessErrorHandshake;
|
||||
friend JavaThread;
|
||||
// This a back reference to the JavaThread,
|
||||
@ -98,7 +94,7 @@ class HandshakeState {
|
||||
// The queue containing handshake operations to be performed on _handshakee.
|
||||
FilterQueue<HandshakeOperation*> _queue;
|
||||
// Provides mutual exclusion to this state and queue. Also used for
|
||||
// JavaThread suspend/resume operations.
|
||||
// JavaThread suspend/resume operations performed by SuspendResumeManager.
|
||||
Monitor _lock;
|
||||
// Set to the thread executing the handshake operation.
|
||||
Thread* volatile _active_handshaker;
|
||||
@ -160,31 +156,5 @@ class HandshakeState {
|
||||
bool async_exceptions_blocked() { return _async_exceptions_blocked; }
|
||||
void set_async_exceptions_blocked(bool b) { _async_exceptions_blocked = b; }
|
||||
void handle_unsafe_access_error();
|
||||
|
||||
// Suspend/resume support
|
||||
private:
|
||||
// This flag is true when the thread owning this
|
||||
// HandshakeState (the _handshakee) is suspended.
|
||||
volatile bool _suspended;
|
||||
// This flag is true while there is async handshake (trap)
|
||||
// on queue. Since we do only need one, we can reuse it if
|
||||
// thread gets suspended again (after a resume)
|
||||
// and we have not yet processed it.
|
||||
bool _async_suspend_handshake;
|
||||
|
||||
// Called from the suspend handshake.
|
||||
bool suspend_with_handshake(bool register_vthread_SR);
|
||||
// Called from the async handshake (the trap)
|
||||
// to stop a thread from continuing execution when suspended.
|
||||
void do_self_suspend();
|
||||
|
||||
bool is_suspended() { return Atomic::load(&_suspended); }
|
||||
void set_suspended(bool to, bool register_vthread_SR);
|
||||
bool has_async_suspend_handshake() { return _async_suspend_handshake; }
|
||||
void set_async_suspend_handshake(bool to) { _async_suspend_handshake = to; }
|
||||
|
||||
bool suspend(bool register_vthread_SR);
|
||||
bool resume(bool register_vthread_SR);
|
||||
};
|
||||
|
||||
#endif // SHARE_RUNTIME_HANDSHAKE_HPP
|
||||
|
@ -498,6 +498,7 @@ JavaThread::JavaThread(MemTag mem_tag) :
|
||||
_pending_interrupted_exception(false),
|
||||
|
||||
_handshake(this),
|
||||
_suspend_resume_manager(this, &_handshake._lock),
|
||||
|
||||
_popframe_preserved_args(nullptr),
|
||||
_popframe_preserved_args_size(0),
|
||||
@ -1200,13 +1201,13 @@ bool JavaThread::java_suspend(bool register_vthread_SR) {
|
||||
|
||||
guarantee(Thread::is_JavaThread_protected(/* target */ this),
|
||||
"target JavaThread is not protected in calling context.");
|
||||
return this->handshake_state()->suspend(register_vthread_SR);
|
||||
return this->suspend_resume_manager()->suspend(register_vthread_SR);
|
||||
}
|
||||
|
||||
bool JavaThread::java_resume(bool register_vthread_SR) {
|
||||
guarantee(Thread::is_JavaThread_protected_by_TLH(/* target */ this),
|
||||
"missing ThreadsListHandle in calling context.");
|
||||
return this->handshake_state()->resume(register_vthread_SR);
|
||||
return this->suspend_resume_manager()->resume(register_vthread_SR);
|
||||
}
|
||||
|
||||
// Wait for another thread to perform object reallocation and relocking on behalf of
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "runtime/safepointMechanism.hpp"
|
||||
#include "runtime/stackWatermarkSet.hpp"
|
||||
#include "runtime/stackOverflow.hpp"
|
||||
#include "runtime/suspendResumeManager.hpp"
|
||||
#include "runtime/thread.hpp"
|
||||
#include "runtime/threadHeapSampler.hpp"
|
||||
#include "runtime/threadIdentifier.hpp"
|
||||
@ -694,9 +695,13 @@ private:
|
||||
|
||||
// Suspend/resume support for JavaThread
|
||||
// higher-level suspension/resume logic called by the public APIs
|
||||
private:
|
||||
SuspendResumeManager _suspend_resume_manager;
|
||||
public:
|
||||
bool java_suspend(bool register_vthread_SR);
|
||||
bool java_resume(bool register_vthread_SR);
|
||||
bool is_suspended() { return _handshake.is_suspended(); }
|
||||
bool is_suspended() { return _suspend_resume_manager.is_suspended(); }
|
||||
SuspendResumeManager* suspend_resume_manager() { return &_suspend_resume_manager; }
|
||||
|
||||
// Check for async exception in addition to safepoint.
|
||||
static void check_special_condition_for_native_trans(JavaThread *thread);
|
||||
|
158
src/hotspot/share/runtime/suspendResumeManager.cpp
Normal file
158
src/hotspot/share/runtime/suspendResumeManager.cpp
Normal file
@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright (c) 2025, 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 "logging/log.hpp"
|
||||
#include "logging/logStream.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "prims/jvmtiThreadState.hpp"
|
||||
#include "runtime/atomic.hpp"
|
||||
#include "runtime/globals.hpp"
|
||||
#include "runtime/handshake.hpp"
|
||||
#include "runtime/interfaceSupport.inline.hpp"
|
||||
#include "runtime/javaThread.inline.hpp"
|
||||
#include "runtime/suspendResumeManager.hpp"
|
||||
|
||||
// This is the closure that prevents a suspended JavaThread from
|
||||
// escaping the suspend request.
|
||||
class ThreadSelfSuspensionHandshake : public AsyncHandshakeClosure {
|
||||
public:
|
||||
ThreadSelfSuspensionHandshake() : AsyncHandshakeClosure("ThreadSelfSuspensionHandshake") {}
|
||||
void do_thread(Thread* thr) {
|
||||
JavaThread* current = JavaThread::cast(thr);
|
||||
assert(current == Thread::current(), "Must be self executed.");
|
||||
JavaThreadState jts = current->thread_state();
|
||||
|
||||
current->set_thread_state(_thread_blocked);
|
||||
current->suspend_resume_manager()->do_owner_suspend();
|
||||
current->set_thread_state(jts);
|
||||
current->suspend_resume_manager()->set_async_suspend_handshake(false);
|
||||
}
|
||||
virtual bool is_suspend() { return true; }
|
||||
};
|
||||
|
||||
// This is the closure that synchronously honors the suspend request.
|
||||
class SuspendThreadHandshake : public HandshakeClosure {
|
||||
bool _register_vthread_SR;
|
||||
bool _did_suspend;
|
||||
public:
|
||||
SuspendThreadHandshake(bool register_vthread_SR) : HandshakeClosure("SuspendThread"),
|
||||
_register_vthread_SR(register_vthread_SR), _did_suspend(false) {
|
||||
}
|
||||
void do_thread(Thread* thr) {
|
||||
JavaThread* target = JavaThread::cast(thr);
|
||||
_did_suspend = target->suspend_resume_manager()->suspend_with_handshake(_register_vthread_SR);
|
||||
}
|
||||
bool did_suspend() { return _did_suspend; }
|
||||
};
|
||||
|
||||
void SuspendResumeManager::set_suspended(bool is_suspend, bool register_vthread_SR) {
|
||||
#if INCLUDE_JVMTI
|
||||
if (register_vthread_SR) {
|
||||
assert(_target->is_vthread_mounted(), "sanity check");
|
||||
if (is_suspend) {
|
||||
JvmtiVTSuspender::register_vthread_suspend(_target->vthread());
|
||||
}
|
||||
else {
|
||||
JvmtiVTSuspender::register_vthread_resume(_target->vthread());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Atomic::store(&_suspended, is_suspend);
|
||||
}
|
||||
|
||||
bool SuspendResumeManager::suspend(bool register_vthread_SR) {
|
||||
JVMTI_ONLY(assert(!_target->is_in_VTMS_transition(), "no suspend allowed in VTMS transition");)
|
||||
JavaThread* self = JavaThread::current();
|
||||
if (_target == self) {
|
||||
// If target is the current thread we can bypass the handshake machinery
|
||||
// and just suspend directly
|
||||
ThreadBlockInVM tbivm(self);
|
||||
MutexLocker ml(_state_lock, Mutex::_no_safepoint_check_flag);
|
||||
set_suspended(true, register_vthread_SR);
|
||||
do_owner_suspend();
|
||||
return true;
|
||||
} else {
|
||||
SuspendThreadHandshake st(register_vthread_SR);
|
||||
Handshake::execute(&st, _target);
|
||||
return st.did_suspend();
|
||||
}
|
||||
}
|
||||
|
||||
bool SuspendResumeManager::resume(bool register_vthread_SR) {
|
||||
MutexLocker ml(_state_lock, Mutex::_no_safepoint_check_flag);
|
||||
if (!is_suspended()) {
|
||||
assert(!_target->is_suspended(), "cannot be suspended without a suspend request");
|
||||
return false;
|
||||
}
|
||||
// Resume the thread.
|
||||
set_suspended(false, register_vthread_SR);
|
||||
_state_lock->notify();
|
||||
return true;
|
||||
}
|
||||
|
||||
void SuspendResumeManager::do_owner_suspend() {
|
||||
assert(Thread::current() == _target, "should call from _target");
|
||||
assert(_state_lock->owned_by_self(), "Lock must be held");
|
||||
assert(!_target->has_last_Java_frame() || _target->frame_anchor()->walkable(), "should have walkable stack");
|
||||
assert(_target->thread_state() == _thread_blocked, "Caller should have transitioned to _thread_blocked");
|
||||
|
||||
while (is_suspended()) {
|
||||
log_trace(thread, suspend)("JavaThread:" INTPTR_FORMAT " suspended", p2i(_target));
|
||||
_state_lock->wait_without_safepoint_check();
|
||||
}
|
||||
log_trace(thread, suspend)("JavaThread:" INTPTR_FORMAT " resumed", p2i(_target));
|
||||
}
|
||||
|
||||
bool SuspendResumeManager::suspend_with_handshake(bool register_vthread_SR) {
|
||||
assert(_target->threadObj() != nullptr, "cannot suspend with a null threadObj");
|
||||
if (_target->is_exiting()) {
|
||||
log_trace(thread, suspend)("JavaThread:" INTPTR_FORMAT " exiting", p2i(_target));
|
||||
return false;
|
||||
}
|
||||
if (has_async_suspend_handshake()) {
|
||||
if (is_suspended()) {
|
||||
// Target is already suspended.
|
||||
log_trace(thread, suspend)("JavaThread:" INTPTR_FORMAT " already suspended", p2i(_target));
|
||||
return false;
|
||||
} else {
|
||||
// Target is going to wake up and leave suspension.
|
||||
// Let's just stop the thread from doing that.
|
||||
log_trace(thread, suspend)("JavaThread:" INTPTR_FORMAT " re-suspended", p2i(_target));
|
||||
set_suspended(true, register_vthread_SR);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// no suspend request
|
||||
assert(!is_suspended(), "cannot be suspended without a suspend request");
|
||||
// Thread is safe, so it must execute the request, thus we can count it as suspended
|
||||
// from this point.
|
||||
set_suspended(true, register_vthread_SR);
|
||||
set_async_suspend_handshake(true);
|
||||
log_trace(thread, suspend)("JavaThread:" INTPTR_FORMAT " suspended, arming ThreadSuspension", p2i(_target));
|
||||
ThreadSelfSuspensionHandshake* ts = new ThreadSelfSuspensionHandshake();
|
||||
Handshake::execute(ts, _target);
|
||||
return true;
|
||||
}
|
||||
|
||||
SuspendResumeManager::SuspendResumeManager(JavaThread* thread, Monitor* state_lock) : _target(thread), _state_lock(state_lock), _suspended(false), _async_suspend_handshake(false) {}
|
70
src/hotspot/share/runtime/suspendResumeManager.hpp
Normal file
70
src/hotspot/share/runtime/suspendResumeManager.hpp
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2025, 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_SUSPENDRESUMEMANAGER_HPP
|
||||
#define SHARE_RUNTIME_SUSPENDRESUMEMANAGER_HPP
|
||||
|
||||
class SuspendThreadHandshake;
|
||||
class ThreadSelfSuspensionHandshake;
|
||||
|
||||
class SuspendResumeManager {
|
||||
friend SuspendThreadHandshake;
|
||||
friend ThreadSelfSuspensionHandshake;
|
||||
friend JavaThread;
|
||||
|
||||
JavaThread* _target;
|
||||
Monitor* _state_lock;
|
||||
|
||||
SuspendResumeManager(JavaThread* thread, Monitor* state_lock);
|
||||
|
||||
// This flag is true when the thread owning this
|
||||
// SuspendResumeManager (the _target) is suspended.
|
||||
volatile bool _suspended;
|
||||
// This flag is true while there is async handshake (trap)
|
||||
// on queue. Since we do only need one, we can reuse it if
|
||||
// thread gets suspended again (after a resume)
|
||||
// and we have not yet processed it.
|
||||
bool _async_suspend_handshake;
|
||||
|
||||
bool suspend(bool register_vthread_SR);
|
||||
bool resume(bool register_vthread_SR);
|
||||
|
||||
// Called from the async handshake (the trap)
|
||||
// to stop a thread from continuing execution when suspended.
|
||||
void do_owner_suspend();
|
||||
|
||||
// Called from the suspend handshake.
|
||||
bool suspend_with_handshake(bool register_vthread_SR);
|
||||
|
||||
void set_suspended(bool to, bool register_vthread_SR);
|
||||
|
||||
bool is_suspended() {
|
||||
return Atomic::load(&_suspended);
|
||||
}
|
||||
|
||||
bool has_async_suspend_handshake() { return _async_suspend_handshake; }
|
||||
void set_async_suspend_handshake(bool to) { _async_suspend_handshake = to; }
|
||||
};
|
||||
|
||||
#endif // SHARE_RUNTIME_SUSPENDRESUMEMANAGER_HPP
|
Loading…
x
Reference in New Issue
Block a user