< prev index next >
src/hotspot/share/runtime/handshake.hpp
Print this page
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2020, 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.
@@ -28,17 +28,21 @@
#include "memory/allocation.hpp"
#include "memory/iterator.hpp"
#include "runtime/flags/flagSetting.hpp"
#include "runtime/semaphore.hpp"
+class HandshakeOperation;
class JavaThread;
// A handshake closure is a callback that is executed for each JavaThread
// while that thread is in a safepoint safe state. The callback is executed
-// either by the thread itself or by the VM thread while keeping the thread
-// in a blocked state. A handshake can be performed with a single
-// JavaThread as well.
+// either by the target JavaThread itself or by the VMThread while keeping
+// the target thread in a blocked state. A handshake can be performed with a
+// single JavaThread as well. In that case, the callback is executed either
+// by the target JavaThread itself or, depending on whether the operation is
+// a direct handshake or not, by the JavaThread that requested the handshake
+// or the VMThread respectively.
class HandshakeClosure : public ThreadClosure {
const char* const _name;
public:
HandshakeClosure(const char* name) : _name(name) {}
const char* name() const {
@@ -50,51 +54,55 @@
class Handshake : public AllStatic {
public:
// Execution of handshake operation
static void execute(HandshakeClosure* hs_cl);
static bool execute(HandshakeClosure* hs_cl, JavaThread* target);
+ static bool execute_direct(HandshakeClosure* hs_cl, JavaThread* target);
};
-class HandshakeOperation;
-
-// The HandshakeState keep tracks of an ongoing handshake for one JavaThread.
-// VM thread and JavaThread are serialized with the semaphore making sure
-// the operation is only done by either VM thread on behalf of the JavaThread
-// or the JavaThread itself.
+// The HandshakeState keeps track of an ongoing handshake for this JavaThread.
+// VMThread/Handshaker and JavaThread are serialized with semaphore _processing_sem
+// making sure the operation is only done by either VMThread/Handshaker on behalf
+// of the JavaThread or by the target JavaThread itself.
class HandshakeState {
+ JavaThread* _handshakee;
HandshakeOperation* volatile _operation;
+ HandshakeOperation* volatile _operation_direct;
- Semaphore _semaphore;
+ Semaphore _handshake_turn_sem; // Used to serialize direct handshakes for this JavaThread.
+ Semaphore _processing_sem;
bool _thread_in_process_handshake;
- bool claim_handshake_for_vmthread();
- bool vmthread_can_process_handshake(JavaThread* target);
+ bool claim_handshake(bool is_direct);
+ bool possibly_can_process_handshake();
+ bool can_process_handshake();
+ void clear_handshake(bool is_direct);
- void clear_handshake(JavaThread* thread);
+ void process_self_inner();
- void process_self_inner(JavaThread* thread);
public:
HandshakeState();
- void set_operation(JavaThread* thread, HandshakeOperation* op);
+ void set_handshakee(JavaThread* thread) { _handshakee = thread; }
- bool has_operation() const {
- return _operation != NULL;
+ void set_operation(HandshakeOperation* op);
+ bool has_operation() const { return _operation != NULL || _operation_direct != NULL; }
+ bool has_specific_operation(bool is_direct) const {
+ return is_direct ? _operation_direct != NULL : _operation != NULL;
}
- void process_by_self(JavaThread* thread) {
+ void process_by_self() {
if (!_thread_in_process_handshake) {
FlagSetting fs(_thread_in_process_handshake, true);
- process_self_inner(thread);
+ process_self_inner();
}
}
-
- bool try_process_by_vmThread(JavaThread* target);
+ bool try_process(HandshakeOperation* op);
#ifdef ASSERT
- bool _vmthread_processing_handshake;
- bool is_vmthread_processing_handshake() const { return _vmthread_processing_handshake; }
+ Thread* _active_handshaker;
+ Thread* active_handshaker() const { return _active_handshaker; }
#endif
};
#endif // SHARE_RUNTIME_HANDSHAKE_HPP
< prev index next >