Path: blob/master/src/hotspot/share/runtime/handshake.hpp
40951 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#ifndef SHARE_RUNTIME_HANDSHAKE_HPP25#define SHARE_RUNTIME_HANDSHAKE_HPP2627#include "memory/allocation.hpp"28#include "memory/iterator.hpp"29#include "runtime/flags/flagSetting.hpp"30#include "runtime/mutex.hpp"31#include "utilities/filterQueue.hpp"3233class HandshakeOperation;34class JavaThread;35class SuspendThreadHandshake;36class ThreadSelfSuspensionHandshake;3738// A handshake closure is a callback that is executed for a JavaThread39// while it is in a safepoint/handshake-safe state. Depending on the40// nature of the closure, the callback may be executed by the initiating41// thread, the target thread, or the VMThread. If the callback is not executed42// by the target thread it will remain in a blocked state until the callback completes.43class HandshakeClosure : public ThreadClosure, public CHeapObj<mtThread> {44const char* const _name;45public:46HandshakeClosure(const char* name) : _name(name) {}47virtual ~HandshakeClosure() {}48const char* name() const { return _name; }49virtual bool is_async() { return false; }50virtual void do_thread(Thread* thread) = 0;51};5253class AsyncHandshakeClosure : public HandshakeClosure {54public:55AsyncHandshakeClosure(const char* name) : HandshakeClosure(name) {}56virtual ~AsyncHandshakeClosure() {}57virtual bool is_async() { return true; }58};5960class Handshake : public AllStatic {61public:62// Execution of handshake operation63static void execute(HandshakeClosure* hs_cl);64static void execute(HandshakeClosure* hs_cl, JavaThread* target);65static void execute(AsyncHandshakeClosure* hs_cl, JavaThread* target);66};6768class JvmtiRawMonitor;6970// The HandshakeState keeps track of an ongoing handshake for this JavaThread.71// VMThread/Handshaker and JavaThread are serialized with _lock making sure the72// operation is only done by either VMThread/Handshaker on behalf of the73// JavaThread or by the target JavaThread itself.74class HandshakeState {75friend ThreadSelfSuspensionHandshake;76friend SuspendThreadHandshake;77friend JavaThread;78// This a back reference to the JavaThread,79// the target for all operation in the queue.80JavaThread* _handshakee;81// The queue containing handshake operations to be performed on _handshakee.82FilterQueue<HandshakeOperation*> _queue;83// Provides mutual exclusion to this state and queue. Also used for84// JavaThread suspend/resume operations.85Monitor _lock;86// Set to the thread executing the handshake operation.87Thread* _active_handshaker;8889bool claim_handshake();90bool possibly_can_process_handshake();91bool can_process_handshake();9293// Returns false if the JavaThread finished all its handshake operations.94// If the method returns true there is still potential work to be done,95// but we need to check for a safepoint before.96// (This is due to a suspension handshake which put the JavaThread in blocked97// state so a safepoint may be in-progress.)98bool process_self_inner();99100bool have_non_self_executable_operation();101HandshakeOperation* pop_for_self();102HandshakeOperation* pop();103104public:105HandshakeState(JavaThread* thread);106107void add_operation(HandshakeOperation* op);108109bool has_operation() {110return !_queue.is_empty();111}112113bool operation_pending(HandshakeOperation* op);114115// Both _queue and _lock must be checked. If a thread has seen this _handshakee116// as safe it will execute all possible handshake operations in a loop while117// holding _lock. We use lock free addition to the queue, which means it is118// possible for the queue to be seen as empty by _handshakee but as non-empty119// by the thread executing in the loop. To avoid the _handshakee continuing120// while handshake operations are being executed, the _handshakee121// must take slow path, process_by_self(), if _lock is held.122bool should_process() {123// The holder of the _lock can add an asynchronous handshake to queue.124// To make sure it is seen by the handshakee, the handshakee must first125// check the _lock, and if held go to slow path.126// Since the handshakee is unsafe if _lock gets locked after this check127// we know other threads cannot process any handshakes.128// Now we can check the queue to see if there is anything we should processs.129if (_lock.is_locked()) {130return true;131}132// Lock check must be done before queue check, force ordering.133OrderAccess::loadload();134return !_queue.is_empty();135}136137bool process_by_self();138139enum ProcessResult {140_no_operation = 0,141_not_safe,142_claim_failed,143_processed,144_succeeded,145_number_states146};147ProcessResult try_process(HandshakeOperation* match_op);148149Thread* active_handshaker() const { return _active_handshaker; }150151// Suspend/resume support152private:153// This flag is true when the thread owning this154// HandshakeState (the _handshakee) is suspended.155volatile bool _suspended;156// This flag is true while there is async handshake (trap)157// on queue. Since we do only need one, we can reuse it if158// thread gets suspended again (after a resume)159// and we have not yet processed it.160bool _async_suspend_handshake;161162// Called from the suspend handshake.163bool suspend_with_handshake();164// Called from the async handshake (the trap)165// to stop a thread from continuing execution when suspended.166void do_self_suspend();167168bool is_suspended() { return Atomic::load(&_suspended); }169void set_suspended(bool to) { return Atomic::store(&_suspended, to); }170bool has_async_suspend_handshake() { return _async_suspend_handshake; }171void set_async_suspend_handshake(bool to) { _async_suspend_handshake = to; }172173bool suspend();174bool resume();175};176177#endif // SHARE_RUNTIME_HANDSHAKE_HPP178179180