Skip to content

Commit 42ab8fc

Browse files
toxaartcoleenp
authored andcommitted
8265754: Move suspend/resume API from HandshakeState
Reviewed-by: coleenp, dholmes, pchilanomate
1 parent bf7d40d commit 42ab8fc

File tree

6 files changed

+241
-159
lines changed

6 files changed

+241
-159
lines changed

src/hotspot/share/runtime/handshake.cpp

Lines changed: 2 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -465,9 +465,7 @@ HandshakeState::HandshakeState(JavaThread* target) :
465465
_queue(),
466466
_lock(Monitor::nosafepoint, "HandshakeState_lock"),
467467
_active_handshaker(),
468-
_async_exceptions_blocked(false),
469-
_suspended(false),
470-
_async_suspend_handshake(false) {
468+
_async_exceptions_blocked(false) {
471469
}
472470

473471
HandshakeState::~HandshakeState() {
@@ -699,128 +697,8 @@ HandshakeState::ProcessResult HandshakeState::try_process(HandshakeOperation* ma
699697
return op == match_op ? HandshakeState::_succeeded : HandshakeState::_processed;
700698
}
701699

702-
void HandshakeState::do_self_suspend() {
703-
assert(Thread::current() == _handshakee, "should call from _handshakee");
704-
assert(_lock.owned_by_self(), "Lock must be held");
705-
assert(!_handshakee->has_last_Java_frame() || _handshakee->frame_anchor()->walkable(), "should have walkable stack");
706-
assert(_handshakee->thread_state() == _thread_blocked, "Caller should have transitioned to _thread_blocked");
707-
708-
while (is_suspended()) {
709-
log_trace(thread, suspend)("JavaThread:" INTPTR_FORMAT " suspended", p2i(_handshakee));
710-
_lock.wait_without_safepoint_check();
711-
}
712-
log_trace(thread, suspend)("JavaThread:" INTPTR_FORMAT " resumed", p2i(_handshakee));
713-
}
714-
715-
// This is the closure that prevents a suspended JavaThread from
716-
// escaping the suspend request.
717-
class ThreadSelfSuspensionHandshake : public AsyncHandshakeClosure {
718-
public:
719-
ThreadSelfSuspensionHandshake() : AsyncHandshakeClosure("ThreadSelfSuspensionHandshake") {}
720-
void do_thread(Thread* thr) {
721-
JavaThread* current = JavaThread::cast(thr);
722-
assert(current == Thread::current(), "Must be self executed.");
723-
JavaThreadState jts = current->thread_state();
724-
725-
current->set_thread_state(_thread_blocked);
726-
current->handshake_state()->do_self_suspend();
727-
current->set_thread_state(jts);
728-
current->handshake_state()->set_async_suspend_handshake(false);
729-
}
730-
virtual bool is_suspend() { return true; }
731-
};
732-
733-
bool HandshakeState::suspend_with_handshake(bool register_vthread_SR) {
734-
assert(_handshakee->threadObj() != nullptr, "cannot suspend with a null threadObj");
735-
if (_handshakee->is_exiting()) {
736-
log_trace(thread, suspend)("JavaThread:" INTPTR_FORMAT " exiting", p2i(_handshakee));
737-
return false;
738-
}
739-
if (has_async_suspend_handshake()) {
740-
if (is_suspended()) {
741-
// Target is already suspended.
742-
log_trace(thread, suspend)("JavaThread:" INTPTR_FORMAT " already suspended", p2i(_handshakee));
743-
return false;
744-
} else {
745-
// Target is going to wake up and leave suspension.
746-
// Let's just stop the thread from doing that.
747-
log_trace(thread, suspend)("JavaThread:" INTPTR_FORMAT " re-suspended", p2i(_handshakee));
748-
set_suspended(true, register_vthread_SR);
749-
return true;
750-
}
751-
}
752-
// no suspend request
753-
assert(!is_suspended(), "cannot be suspended without a suspend request");
754-
// Thread is safe, so it must execute the request, thus we can count it as suspended
755-
// from this point.
756-
set_suspended(true, register_vthread_SR);
757-
set_async_suspend_handshake(true);
758-
log_trace(thread, suspend)("JavaThread:" INTPTR_FORMAT " suspended, arming ThreadSuspension", p2i(_handshakee));
759-
ThreadSelfSuspensionHandshake* ts = new ThreadSelfSuspensionHandshake();
760-
Handshake::execute(ts, _handshakee);
761-
return true;
762-
}
763-
764-
// This is the closure that synchronously honors the suspend request.
765-
class SuspendThreadHandshake : public HandshakeClosure {
766-
bool _register_vthread_SR;
767-
bool _did_suspend;
768-
public:
769-
SuspendThreadHandshake(bool register_vthread_SR) : HandshakeClosure("SuspendThread"),
770-
_register_vthread_SR(register_vthread_SR), _did_suspend(false) {}
771-
void do_thread(Thread* thr) {
772-
JavaThread* target = JavaThread::cast(thr);
773-
_did_suspend = target->handshake_state()->suspend_with_handshake(_register_vthread_SR);
774-
}
775-
bool did_suspend() { return _did_suspend; }
776-
};
777-
778-
bool HandshakeState::suspend(bool register_vthread_SR) {
779-
JVMTI_ONLY(assert(!_handshakee->is_in_VTMS_transition(), "no suspend allowed in VTMS transition");)
780-
JavaThread* self = JavaThread::current();
781-
if (_handshakee == self) {
782-
// If target is the current thread we can bypass the handshake machinery
783-
// and just suspend directly
784-
ThreadBlockInVM tbivm(self);
785-
MutexLocker ml(&_lock, Mutex::_no_safepoint_check_flag);
786-
set_suspended(true, register_vthread_SR);
787-
do_self_suspend();
788-
return true;
789-
} else {
790-
SuspendThreadHandshake st(register_vthread_SR);
791-
Handshake::execute(&st, _handshakee);
792-
return st.did_suspend();
793-
}
794-
}
795-
796-
bool HandshakeState::resume(bool register_vthread_SR) {
797-
MutexLocker ml(&_lock, Mutex::_no_safepoint_check_flag);
798-
if (!is_suspended()) {
799-
assert(!_handshakee->is_suspended(), "cannot be suspended without a suspend request");
800-
return false;
801-
}
802-
// Resume the thread.
803-
set_suspended(false, register_vthread_SR);
804-
_lock.notify();
805-
return true;
806-
}
807-
808-
void HandshakeState::set_suspended(bool is_suspend, bool register_vthread_SR) {
809-
#if INCLUDE_JVMTI
810-
if (register_vthread_SR) {
811-
assert(_handshakee->is_vthread_mounted(), "sanity check");
812-
if (is_suspend) {
813-
JvmtiVTSuspender::register_vthread_suspend(_handshakee->vthread());
814-
} else {
815-
JvmtiVTSuspender::register_vthread_resume(_handshakee->vthread());
816-
}
817-
}
818-
#endif
819-
Atomic::store(&_suspended, is_suspend);
820-
}
821-
822700
void HandshakeState::handle_unsafe_access_error() {
823-
if (is_suspended()) {
701+
if (_handshakee->is_suspended()) {
824702
// A suspend handshake was added to the queue after the
825703
// unsafe access error. Since the suspender has already
826704
// considered this JT as suspended and assumes it won't go

src/hotspot/share/runtime/handshake.hpp

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -35,8 +35,6 @@
3535
class HandshakeOperation;
3636
class AsyncHandshakeOperation;
3737
class JavaThread;
38-
class SuspendThreadHandshake;
39-
class ThreadSelfSuspensionHandshake;
4038
class UnsafeAccessErrorHandshake;
4139
class ThreadsListHandle;
4240

@@ -88,8 +86,6 @@ class JvmtiRawMonitor;
8886
// operation is only done by either VMThread/Handshaker on behalf of the
8987
// JavaThread or by the target JavaThread itself.
9088
class HandshakeState {
91-
friend ThreadSelfSuspensionHandshake;
92-
friend SuspendThreadHandshake;
9389
friend UnsafeAccessErrorHandshake;
9490
friend JavaThread;
9591
// This a back reference to the JavaThread,
@@ -98,7 +94,7 @@ class HandshakeState {
9894
// The queue containing handshake operations to be performed on _handshakee.
9995
FilterQueue<HandshakeOperation*> _queue;
10096
// Provides mutual exclusion to this state and queue. Also used for
101-
// JavaThread suspend/resume operations.
97+
// JavaThread suspend/resume operations performed by SuspendResumeManager.
10298
Monitor _lock;
10399
// Set to the thread executing the handshake operation.
104100
Thread* volatile _active_handshaker;
@@ -160,31 +156,5 @@ class HandshakeState {
160156
bool async_exceptions_blocked() { return _async_exceptions_blocked; }
161157
void set_async_exceptions_blocked(bool b) { _async_exceptions_blocked = b; }
162158
void handle_unsafe_access_error();
163-
164-
// Suspend/resume support
165-
private:
166-
// This flag is true when the thread owning this
167-
// HandshakeState (the _handshakee) is suspended.
168-
volatile bool _suspended;
169-
// This flag is true while there is async handshake (trap)
170-
// on queue. Since we do only need one, we can reuse it if
171-
// thread gets suspended again (after a resume)
172-
// and we have not yet processed it.
173-
bool _async_suspend_handshake;
174-
175-
// Called from the suspend handshake.
176-
bool suspend_with_handshake(bool register_vthread_SR);
177-
// Called from the async handshake (the trap)
178-
// to stop a thread from continuing execution when suspended.
179-
void do_self_suspend();
180-
181-
bool is_suspended() { return Atomic::load(&_suspended); }
182-
void set_suspended(bool to, bool register_vthread_SR);
183-
bool has_async_suspend_handshake() { return _async_suspend_handshake; }
184-
void set_async_suspend_handshake(bool to) { _async_suspend_handshake = to; }
185-
186-
bool suspend(bool register_vthread_SR);
187-
bool resume(bool register_vthread_SR);
188159
};
189-
190160
#endif // SHARE_RUNTIME_HANDSHAKE_HPP

src/hotspot/share/runtime/javaThread.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,7 @@ JavaThread::JavaThread(MemTag mem_tag) :
498498
_pending_interrupted_exception(false),
499499

500500
_handshake(this),
501+
_suspend_resume_manager(this, &_handshake._lock),
501502

502503
_popframe_preserved_args(nullptr),
503504
_popframe_preserved_args_size(0),
@@ -1200,13 +1201,13 @@ bool JavaThread::java_suspend(bool register_vthread_SR) {
12001201

12011202
guarantee(Thread::is_JavaThread_protected(/* target */ this),
12021203
"target JavaThread is not protected in calling context.");
1203-
return this->handshake_state()->suspend(register_vthread_SR);
1204+
return this->suspend_resume_manager()->suspend(register_vthread_SR);
12041205
}
12051206

12061207
bool JavaThread::java_resume(bool register_vthread_SR) {
12071208
guarantee(Thread::is_JavaThread_protected_by_TLH(/* target */ this),
12081209
"missing ThreadsListHandle in calling context.");
1209-
return this->handshake_state()->resume(register_vthread_SR);
1210+
return this->suspend_resume_manager()->resume(register_vthread_SR);
12101211
}
12111212

12121213
// Wait for another thread to perform object reallocation and relocking on behalf of

src/hotspot/share/runtime/javaThread.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "runtime/safepointMechanism.hpp"
4141
#include "runtime/stackWatermarkSet.hpp"
4242
#include "runtime/stackOverflow.hpp"
43+
#include "runtime/suspendResumeManager.hpp"
4344
#include "runtime/thread.hpp"
4445
#include "runtime/threadHeapSampler.hpp"
4546
#include "runtime/threadIdentifier.hpp"
@@ -694,9 +695,13 @@ class JavaThread: public Thread {
694695

695696
// Suspend/resume support for JavaThread
696697
// higher-level suspension/resume logic called by the public APIs
698+
private:
699+
SuspendResumeManager _suspend_resume_manager;
700+
public:
697701
bool java_suspend(bool register_vthread_SR);
698702
bool java_resume(bool register_vthread_SR);
699-
bool is_suspended() { return _handshake.is_suspended(); }
703+
bool is_suspended() { return _suspend_resume_manager.is_suspended(); }
704+
SuspendResumeManager* suspend_resume_manager() { return &_suspend_resume_manager; }
700705

701706
// Check for async exception in addition to safepoint.
702707
static void check_special_condition_for_native_trans(JavaThread *thread);

0 commit comments

Comments
 (0)