Path: blob/master/src/hotspot/share/runtime/handshake.cpp
64440 views
/*1* Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "jvm_io.h"26#include "logging/log.hpp"27#include "logging/logStream.hpp"28#include "memory/resourceArea.hpp"29#include "runtime/atomic.hpp"30#include "runtime/handshake.hpp"31#include "runtime/interfaceSupport.inline.hpp"32#include "runtime/os.hpp"33#include "runtime/osThread.hpp"34#include "runtime/stackWatermarkSet.hpp"35#include "runtime/task.hpp"36#include "runtime/thread.hpp"37#include "runtime/threadSMR.hpp"38#include "runtime/vmThread.hpp"39#include "utilities/formatBuffer.hpp"40#include "utilities/filterQueue.inline.hpp"41#include "utilities/globalDefinitions.hpp"42#include "utilities/preserveException.hpp"4344class HandshakeOperation : public CHeapObj<mtThread> {45friend class HandshakeState;46protected:47HandshakeClosure* _handshake_cl;48// Keeps track of emitted and completed handshake operations.49// Once it reaches zero all handshake operations have been performed.50int32_t _pending_threads;51JavaThread* _target;52Thread* _requester;5354// Must use AsyncHandshakeOperation when using AsyncHandshakeClosure.55HandshakeOperation(AsyncHandshakeClosure* cl, JavaThread* target, Thread* requester) :56_handshake_cl(cl),57_pending_threads(1),58_target(target),59_requester(requester) {}6061public:62HandshakeOperation(HandshakeClosure* cl, JavaThread* target, Thread* requester) :63_handshake_cl(cl),64_pending_threads(1),65_target(target),66_requester(requester) {}67virtual ~HandshakeOperation() {}68void prepare(JavaThread* current_target, Thread* executing_thread);69void do_handshake(JavaThread* thread);70bool is_completed() {71int32_t val = Atomic::load(&_pending_threads);72assert(val >= 0, "_pending_threads=%d cannot be negative", val);73return val == 0;74}75void add_target_count(int count) { Atomic::add(&_pending_threads, count); }76int32_t pending_threads() { return Atomic::load(&_pending_threads); }77const char* name() { return _handshake_cl->name(); }78bool is_async() { return _handshake_cl->is_async(); }79bool is_suspend() { return _handshake_cl->is_suspend(); }80};8182class AsyncHandshakeOperation : public HandshakeOperation {83private:84jlong _start_time_ns;85public:86AsyncHandshakeOperation(AsyncHandshakeClosure* cl, JavaThread* target, jlong start_ns)87: HandshakeOperation(cl, target, NULL), _start_time_ns(start_ns) {}88virtual ~AsyncHandshakeOperation() { delete _handshake_cl; }89jlong start_time() const { return _start_time_ns; }90};9192// Performing handshakes requires a custom yielding strategy because without it93// there is a clear performance regression vs plain spinning. We keep track of94// when we last saw progress by looking at why each targeted thread has not yet95// completed its handshake. After spinning for a while with no progress we will96// yield, but as long as there is progress, we keep spinning. Thus we avoid97// yielding when there is potential work to be done or the handshake is close98// to being finished.99class HandshakeSpinYield : public StackObj {100private:101jlong _start_time_ns;102jlong _last_spin_start_ns;103jlong _spin_time_ns;104105int _result_count[2][HandshakeState::_number_states];106int _prev_result_pos;107108int current_result_pos() { return (_prev_result_pos + 1) & 0x1; }109110void wait_raw(jlong now) {111// We start with fine-grained nanosleeping until a millisecond has112// passed, at which point we resort to plain naked_short_sleep.113if (now - _start_time_ns < NANOSECS_PER_MILLISEC) {114os::naked_short_nanosleep(10 * (NANOUNITS / MICROUNITS));115} else {116os::naked_short_sleep(1);117}118}119120void wait_blocked(JavaThread* self, jlong now) {121ThreadBlockInVM tbivm(self);122wait_raw(now);123}124125bool state_changed() {126for (int i = 0; i < HandshakeState::_number_states; i++) {127if (_result_count[0][i] != _result_count[1][i]) {128return true;129}130}131return false;132}133134void reset_state() {135_prev_result_pos++;136for (int i = 0; i < HandshakeState::_number_states; i++) {137_result_count[current_result_pos()][i] = 0;138}139}140141public:142HandshakeSpinYield(jlong start_time) :143_start_time_ns(start_time), _last_spin_start_ns(start_time),144_spin_time_ns(0), _result_count(), _prev_result_pos(0) {145146const jlong max_spin_time_ns = 100 /* us */ * (NANOUNITS / MICROUNITS);147int free_cpus = os::active_processor_count() - 1;148_spin_time_ns = (5 /* us */ * (NANOUNITS / MICROUNITS)) * free_cpus; // zero on UP149_spin_time_ns = _spin_time_ns > max_spin_time_ns ? max_spin_time_ns : _spin_time_ns;150}151152void add_result(HandshakeState::ProcessResult pr) {153_result_count[current_result_pos()][pr]++;154}155156void process() {157jlong now = os::javaTimeNanos();158if (state_changed()) {159reset_state();160// We spin for x amount of time since last state change.161_last_spin_start_ns = now;162return;163}164jlong wait_target = _last_spin_start_ns + _spin_time_ns;165if (wait_target < now) {166// On UP this is always true.167Thread* self = Thread::current();168if (self->is_Java_thread()) {169wait_blocked(self->as_Java_thread(), now);170} else {171wait_raw(now);172}173_last_spin_start_ns = os::javaTimeNanos();174}175reset_state();176}177};178179static void handle_timeout(HandshakeOperation* op, JavaThread* target) {180JavaThreadIteratorWithHandle jtiwh;181182log_error(handshake)("Handshake timeout: %s(" INTPTR_FORMAT "), pending threads: " INT32_FORMAT,183op->name(), p2i(op), op->pending_threads());184185if (target == NULL) {186for ( ; JavaThread* thr = jtiwh.next(); ) {187if (thr->handshake_state()->operation_pending(op)) {188log_error(handshake)("JavaThread " INTPTR_FORMAT " has not cleared handshake op: " INTPTR_FORMAT, p2i(thr), p2i(op));189// Remember the last one found for more diagnostics below.190target = thr;191}192}193} else {194log_error(handshake)("JavaThread " INTPTR_FORMAT " has not cleared handshake op: " INTPTR_FORMAT, p2i(target), p2i(op));195}196197if (target != NULL) {198if (os::signal_thread(target, SIGILL, "cannot be handshaked")) {199// Give target a chance to report the error and terminate the VM.200os::naked_sleep(3000);201}202} else {203log_error(handshake)("No thread with an unfinished handshake op(" INTPTR_FORMAT ") found.", p2i(op));204}205fatal("Handshake timeout");206}207208static void check_handshake_timeout(jlong start_time, HandshakeOperation* op, JavaThread* target = NULL) {209// Check if handshake operation has timed out210jlong timeout_ns = millis_to_nanos(HandshakeTimeout);211if (timeout_ns > 0) {212if (os::javaTimeNanos() >= (start_time + timeout_ns)) {213handle_timeout(op, target);214}215}216}217218static void log_handshake_info(jlong start_time_ns, const char* name, int targets, int emitted_handshakes_executed, const char* extra = NULL) {219if (log_is_enabled(Info, handshake)) {220jlong completion_time = os::javaTimeNanos() - start_time_ns;221log_info(handshake)("Handshake \"%s\", Targeted threads: %d, Executed by requesting thread: %d, Total completion time: " JLONG_FORMAT " ns%s%s",222name, targets,223emitted_handshakes_executed,224completion_time,225extra != NULL ? ", " : "",226extra != NULL ? extra : "");227}228}229230class VM_HandshakeAllThreads: public VM_Operation {231HandshakeOperation* const _op;232public:233VM_HandshakeAllThreads(HandshakeOperation* op) : _op(op) {}234235bool evaluate_at_safepoint() const { return false; }236237void doit() {238jlong start_time_ns = os::javaTimeNanos();239240JavaThreadIteratorWithHandle jtiwh;241int number_of_threads_issued = 0;242for (JavaThread* thr = jtiwh.next(); thr != NULL; thr = jtiwh.next()) {243thr->handshake_state()->add_operation(_op);244number_of_threads_issued++;245}246247if (number_of_threads_issued < 1) {248log_handshake_info(start_time_ns, _op->name(), 0, 0, "no threads alive");249return;250}251// _op was created with a count == 1 so don't double count.252_op->add_target_count(number_of_threads_issued - 1);253254log_trace(handshake)("Threads signaled, begin processing blocked threads by VMThread");255HandshakeSpinYield hsy(start_time_ns);256// Keeps count on how many of own emitted handshakes257// this thread execute.258int emitted_handshakes_executed = 0;259do {260// Check if handshake operation has timed out261check_handshake_timeout(start_time_ns, _op);262263// Have VM thread perform the handshake operation for blocked threads.264// Observing a blocked state may of course be transient but the processing is guarded265// by mutexes and we optimistically begin by working on the blocked threads266jtiwh.rewind();267for (JavaThread* thr = jtiwh.next(); thr != NULL; thr = jtiwh.next()) {268// A new thread on the ThreadsList will not have an operation,269// hence it is skipped in handshake_try_process.270HandshakeState::ProcessResult pr = thr->handshake_state()->try_process(_op);271hsy.add_result(pr);272if (pr == HandshakeState::_succeeded) {273emitted_handshakes_executed++;274}275}276hsy.process();277} while (!_op->is_completed());278279// This pairs up with the release store in do_handshake(). It prevents future280// loads from floating above the load of _pending_threads in is_completed()281// and thus prevents reading stale data modified in the handshake closure282// by the Handshakee.283OrderAccess::acquire();284285log_handshake_info(start_time_ns, _op->name(), number_of_threads_issued, emitted_handshakes_executed);286}287288VMOp_Type type() const { return VMOp_HandshakeAllThreads; }289};290291void HandshakeOperation::prepare(JavaThread* current_target, Thread* executing_thread) {292if (current_target->is_terminated()) {293// Will never execute any handshakes on this thread.294return;295}296if (current_target != executing_thread) {297// Only when the target is not executing the handshake itself.298StackWatermarkSet::start_processing(current_target, StackWatermarkKind::gc);299}300if (_requester != NULL && _requester != executing_thread && _requester->is_Java_thread()) {301// The handshake closure may contain oop Handles from the _requester.302// We must make sure we can use them.303StackWatermarkSet::start_processing(_requester->as_Java_thread(), StackWatermarkKind::gc);304}305}306307void HandshakeOperation::do_handshake(JavaThread* thread) {308jlong start_time_ns = 0;309if (log_is_enabled(Debug, handshake, task)) {310start_time_ns = os::javaTimeNanos();311}312313// Only actually execute the operation for non terminated threads.314if (!thread->is_terminated()) {315NoSafepointVerifier nsv;316_handshake_cl->do_thread(thread);317}318319if (start_time_ns != 0) {320jlong completion_time = os::javaTimeNanos() - start_time_ns;321log_debug(handshake, task)("Operation: %s for thread " PTR_FORMAT ", is_vm_thread: %s, completed in " JLONG_FORMAT " ns",322name(), p2i(thread), BOOL_TO_STR(Thread::current()->is_VM_thread()), completion_time);323}324325// Inform VMThread/Handshaker that we have completed the operation.326// When this is executed by the Handshakee we need a release store327// here to make sure memory operations executed in the handshake328// closure are visible to the VMThread/Handshaker after it reads329// that the operation has completed.330Atomic::dec(&_pending_threads);331// Trailing fence, used to make sure removal of the operation strictly332// happened after we completed the operation.333334// It is no longer safe to refer to 'this' as the VMThread/Handshaker may have destroyed this operation335}336337void Handshake::execute(HandshakeClosure* hs_cl) {338HandshakeOperation cto(hs_cl, NULL, Thread::current());339VM_HandshakeAllThreads handshake(&cto);340VMThread::execute(&handshake);341}342343void Handshake::execute(HandshakeClosure* hs_cl, JavaThread* target) {344JavaThread* self = JavaThread::current();345HandshakeOperation op(hs_cl, target, Thread::current());346347jlong start_time_ns = os::javaTimeNanos();348349ThreadsListHandle tlh;350if (tlh.includes(target)) {351target->handshake_state()->add_operation(&op);352} else {353char buf[128];354jio_snprintf(buf, sizeof(buf), "(thread= " INTPTR_FORMAT " dead)", p2i(target));355log_handshake_info(start_time_ns, op.name(), 0, 0, buf);356return;357}358359// Keeps count on how many of own emitted handshakes360// this thread execute.361int emitted_handshakes_executed = 0;362HandshakeSpinYield hsy(start_time_ns);363while (!op.is_completed()) {364HandshakeState::ProcessResult pr = target->handshake_state()->try_process(&op);365if (pr == HandshakeState::_succeeded) {366emitted_handshakes_executed++;367}368if (op.is_completed()) {369break;370}371372// Check if handshake operation has timed out373check_handshake_timeout(start_time_ns, &op, target);374375hsy.add_result(pr);376// Check for pending handshakes to avoid possible deadlocks where our377// target is trying to handshake us.378if (SafepointMechanism::should_process(self)) {379// Will not suspend here.380ThreadBlockInVM tbivm(self);381}382hsy.process();383}384385// This pairs up with the release store in do_handshake(). It prevents future386// loads from floating above the load of _pending_threads in is_completed()387// and thus prevents reading stale data modified in the handshake closure388// by the Handshakee.389OrderAccess::acquire();390391log_handshake_info(start_time_ns, op.name(), 1, emitted_handshakes_executed);392}393394void Handshake::execute(AsyncHandshakeClosure* hs_cl, JavaThread* target) {395jlong start_time_ns = os::javaTimeNanos();396AsyncHandshakeOperation* op = new AsyncHandshakeOperation(hs_cl, target, start_time_ns);397398ThreadsListHandle tlh;399if (tlh.includes(target)) {400target->handshake_state()->add_operation(op);401} else {402log_handshake_info(start_time_ns, op->name(), 0, 0, "(thread dead)");403delete op;404}405}406407HandshakeState::HandshakeState(JavaThread* target) :408_handshakee(target),409_queue(),410_lock(Monitor::leaf, "HandshakeState", Mutex::_allow_vm_block_flag, Monitor::_safepoint_check_never),411_active_handshaker(),412_suspended(false),413_async_suspend_handshake(false)414{415}416417void HandshakeState::add_operation(HandshakeOperation* op) {418// Adds are done lock free and so is arming.419_queue.push(op);420SafepointMechanism::arm_local_poll_release(_handshakee);421}422423bool HandshakeState::operation_pending(HandshakeOperation* op) {424MutexLocker ml(&_lock, Mutex::_no_safepoint_check_flag);425MatchOp mo(op);426return _queue.contains(mo);427}428429static bool no_suspend_filter(HandshakeOperation* op) {430return !op->is_suspend();431}432433HandshakeOperation* HandshakeState::get_op_for_self(bool allow_suspend) {434assert(_handshakee == Thread::current(), "Must be called by self");435assert(_lock.owned_by_self(), "Lock must be held");436if (allow_suspend) {437return _queue.peek();438} else {439return _queue.peek(no_suspend_filter);440}441}442443static bool non_self_queue_filter(HandshakeOperation* op) {444return !op->is_async();445}446447bool HandshakeState::have_non_self_executable_operation() {448assert(_handshakee != Thread::current(), "Must not be called by self");449assert(_lock.owned_by_self(), "Lock must be held");450return _queue.contains(non_self_queue_filter);451}452453bool HandshakeState::has_a_non_suspend_operation() {454MutexLocker ml(&_lock, Mutex::_no_safepoint_check_flag);455return _queue.contains(no_suspend_filter);456}457458HandshakeOperation* HandshakeState::get_op() {459assert(_handshakee != Thread::current(), "Must not be called by self");460assert(_lock.owned_by_self(), "Lock must be held");461return _queue.peek(non_self_queue_filter);462};463464void HandshakeState::remove_op(HandshakeOperation* op) {465assert(_lock.owned_by_self(), "Lock must be held");466MatchOp mo(op);467HandshakeOperation* ret = _queue.pop(mo);468assert(ret == op, "Popped op must match requested op");469};470471bool HandshakeState::process_by_self(bool allow_suspend) {472assert(Thread::current() == _handshakee, "should call from _handshakee");473assert(!_handshakee->is_terminated(), "should not be a terminated thread");474assert(_handshakee->thread_state() != _thread_blocked, "should not be in a blocked state");475assert(_handshakee->thread_state() != _thread_in_native, "should not be in native");476477ThreadInVMForHandshake tivm(_handshakee);478// Handshakes cannot safely safepoint.479// The exception to this rule is the asynchronous suspension handshake.480// It by-passes the NSV by manually doing the transition.481NoSafepointVerifier nsv;482483while (has_operation()) {484MutexLocker ml(&_lock, Mutex::_no_safepoint_check_flag);485486HandshakeOperation* op = get_op_for_self(allow_suspend);487if (op != NULL) {488assert(op->_target == NULL || op->_target == Thread::current(), "Wrong thread");489bool async = op->is_async();490log_trace(handshake)("Proc handshake %s " INTPTR_FORMAT " on " INTPTR_FORMAT " by self",491async ? "asynchronous" : "synchronous", p2i(op), p2i(_handshakee));492op->prepare(_handshakee, _handshakee);493if (!async) {494HandleMark hm(_handshakee);495PreserveExceptionMark pem(_handshakee);496op->do_handshake(_handshakee); // acquire, op removed after497remove_op(op);498} else {499// An asynchronous handshake may put the JavaThread in blocked state (safepoint safe).500// The destructor ~PreserveExceptionMark touches the exception oop so it must not be executed,501// since a safepoint may be in-progress when returning from the async handshake.502op->do_handshake(_handshakee); // acquire, op removed after503remove_op(op);504log_handshake_info(((AsyncHandshakeOperation*)op)->start_time(), op->name(), 1, 0, "asynchronous");505delete op;506return true; // Must check for safepoints507}508} else {509return false;510}511}512return false;513}514515bool HandshakeState::can_process_handshake() {516// handshake_safe may only be called with polls armed.517// Handshaker controls this by first claiming the handshake via claim_handshake().518return SafepointSynchronize::handshake_safe(_handshakee);519}520521bool HandshakeState::possibly_can_process_handshake() {522// Note that this method is allowed to produce false positives.523if (_handshakee->is_terminated()) {524return true;525}526switch (_handshakee->thread_state()) {527case _thread_in_native:528// native threads are safe if they have no java stack or have walkable stack529return !_handshakee->has_last_Java_frame() || _handshakee->frame_anchor()->walkable();530531case _thread_blocked:532return true;533534default:535return false;536}537}538539bool HandshakeState::claim_handshake() {540if (!_lock.try_lock()) {541return false;542}543// Operations are added lock free and then the poll is armed.544// If all handshake operations for the handshakee are finished and someone545// just adds an operation we may see it here. But if the handshakee is not546// armed yet it is not safe to proceed.547if (have_non_self_executable_operation()) {548OrderAccess::loadload(); // Matches the implicit storestore in add_operation()549if (SafepointMechanism::local_poll_armed(_handshakee)) {550return true;551}552}553_lock.unlock();554return false;555}556557HandshakeState::ProcessResult HandshakeState::try_process(HandshakeOperation* match_op) {558if (!has_operation()) {559// JT has already cleared its handshake560return HandshakeState::_no_operation;561}562563if (!possibly_can_process_handshake()) {564// JT is observed in an unsafe state, it must notice the handshake itself565return HandshakeState::_not_safe;566}567568// Claim the mutex if there still an operation to be executed.569if (!claim_handshake()) {570return HandshakeState::_claim_failed;571}572573// If we own the mutex at this point and while owning the mutex we574// can observe a safe state the thread cannot possibly continue without575// getting caught by the mutex.576if (!can_process_handshake()) {577_lock.unlock();578return HandshakeState::_not_safe;579}580581Thread* current_thread = Thread::current();582583HandshakeOperation* op = get_op();584585assert(op != NULL, "Must have an op");586assert(SafepointMechanism::local_poll_armed(_handshakee), "Must be");587assert(op->_target == NULL || _handshakee == op->_target, "Wrong thread");588589log_trace(handshake)("Processing handshake " INTPTR_FORMAT " by %s(%s)", p2i(op),590op == match_op ? "handshaker" : "cooperative",591current_thread->is_VM_thread() ? "VM Thread" : "JavaThread");592593op->prepare(_handshakee, current_thread);594595set_active_handshaker(current_thread);596op->do_handshake(_handshakee); // acquire, op removed after597set_active_handshaker(NULL);598remove_op(op);599600_lock.unlock();601602log_trace(handshake)("%s(" INTPTR_FORMAT ") executed an op for JavaThread: " INTPTR_FORMAT " %s target op: " INTPTR_FORMAT,603current_thread->is_VM_thread() ? "VM Thread" : "JavaThread",604p2i(current_thread), p2i(_handshakee),605op == match_op ? "including" : "excluding", p2i(match_op));606607return op == match_op ? HandshakeState::_succeeded : HandshakeState::_processed;608}609610void HandshakeState::do_self_suspend() {611assert(Thread::current() == _handshakee, "should call from _handshakee");612assert(_lock.owned_by_self(), "Lock must be held");613assert(!_handshakee->has_last_Java_frame() || _handshakee->frame_anchor()->walkable(), "should have walkable stack");614assert(_handshakee->thread_state() == _thread_blocked, "Caller should have transitioned to _thread_blocked");615616while (is_suspended()) {617log_trace(thread, suspend)("JavaThread:" INTPTR_FORMAT " suspended", p2i(_handshakee));618_lock.wait_without_safepoint_check();619}620log_trace(thread, suspend)("JavaThread:" INTPTR_FORMAT " resumed", p2i(_handshakee));621}622623// This is the closure that prevents a suspended JavaThread from624// escaping the suspend request.625class ThreadSelfSuspensionHandshake : public AsyncHandshakeClosure {626public:627ThreadSelfSuspensionHandshake() : AsyncHandshakeClosure("ThreadSelfSuspensionHandshake") {}628void do_thread(Thread* thr) {629JavaThread* current = thr->as_Java_thread();630assert(current == Thread::current(), "Must be self executed.");631JavaThreadState jts = current->thread_state();632633current->set_thread_state(_thread_blocked);634current->handshake_state()->do_self_suspend();635current->set_thread_state(jts);636current->handshake_state()->set_async_suspend_handshake(false);637}638virtual bool is_suspend() { return true; }639};640641bool HandshakeState::suspend_with_handshake() {642if (_handshakee->is_exiting() ||643_handshakee->threadObj() == NULL) {644log_trace(thread, suspend)("JavaThread:" INTPTR_FORMAT " exiting", p2i(_handshakee));645return false;646}647if (has_async_suspend_handshake()) {648if (is_suspended()) {649// Target is already suspended.650log_trace(thread, suspend)("JavaThread:" INTPTR_FORMAT " already suspended", p2i(_handshakee));651return false;652} else {653// Target is going to wake up and leave suspension.654// Let's just stop the thread from doing that.655log_trace(thread, suspend)("JavaThread:" INTPTR_FORMAT " re-suspended", p2i(_handshakee));656set_suspended(true);657return true;658}659}660// no suspend request661assert(!is_suspended(), "cannot be suspended without a suspend request");662// Thread is safe, so it must execute the request, thus we can count it as suspended663// from this point.664set_suspended(true);665set_async_suspend_handshake(true);666log_trace(thread, suspend)("JavaThread:" INTPTR_FORMAT " suspended, arming ThreadSuspension", p2i(_handshakee));667ThreadSelfSuspensionHandshake* ts = new ThreadSelfSuspensionHandshake();668Handshake::execute(ts, _handshakee);669return true;670}671672// This is the closure that synchronously honors the suspend request.673class SuspendThreadHandshake : public HandshakeClosure {674bool _did_suspend;675public:676SuspendThreadHandshake() : HandshakeClosure("SuspendThread"), _did_suspend(false) {}677void do_thread(Thread* thr) {678JavaThread* target = thr->as_Java_thread();679_did_suspend = target->handshake_state()->suspend_with_handshake();680}681bool did_suspend() { return _did_suspend; }682};683684bool HandshakeState::suspend() {685JavaThread* self = JavaThread::current();686if (_handshakee == self) {687// If target is the current thread we can bypass the handshake machinery688// and just suspend directly689ThreadBlockInVM tbivm(self);690MutexLocker ml(&_lock, Mutex::_no_safepoint_check_flag);691set_suspended(true);692do_self_suspend();693return true;694} else {695SuspendThreadHandshake st;696Handshake::execute(&st, _handshakee);697return st.did_suspend();698}699}700701bool HandshakeState::resume() {702if (!is_suspended()) {703return false;704}705MutexLocker ml(&_lock, Mutex::_no_safepoint_check_flag);706if (!is_suspended()) {707assert(!_handshakee->is_suspended(), "cannot be suspended without a suspend request");708return false;709}710// Resume the thread.711set_suspended(false);712_lock.notify();713return true;714}715716717