Skip to content

Commit f036bd6

Browse files
author
duke
committedAug 5, 2021
Automatic merge of jdk:master into master
2 parents 87f19a3 + 62e72ad commit f036bd6

File tree

4 files changed

+33
-41
lines changed

4 files changed

+33
-41
lines changed
 

‎src/hotspot/share/prims/jvmtiRawMonitor.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ void JvmtiRawMonitor::raw_enter(Thread* self) {
332332
for (;;) {
333333
ExitOnSuspend eos(this);
334334
{
335-
ThreadBlockInVMPreprocess<ExitOnSuspend> tbivmp(jt, eos);
335+
ThreadBlockInVMPreprocess<ExitOnSuspend> tbivmp(jt, eos, true /* allow_suspend */);
336336
simple_enter(jt);
337337
}
338338
if (!eos.monitor_exited()) {
@@ -384,7 +384,7 @@ int JvmtiRawMonitor::raw_wait(jlong millis, Thread* self) {
384384
for (;;) {
385385
ExitOnSuspend eos(this);
386386
{
387-
ThreadBlockInVMPreprocess<ExitOnSuspend> tbivmp(jt, eos);
387+
ThreadBlockInVMPreprocess<ExitOnSuspend> tbivmp(jt, eos, true /* allow_suspend */);
388388
simple_enter(jt);
389389
}
390390
if (!eos.monitor_exited()) {

‎src/hotspot/share/runtime/interfaceSupport.inline.hpp

+5-26
Original file line numberDiff line numberDiff line change
@@ -239,13 +239,13 @@ class ThreadToNativeFromVM : public ThreadStateTransition {
239239
// SafepointMechanism::process_if_requested when returning to the VM. This allows us
240240
// to perform an "undo" action if we might block processing a safepoint/handshake operation
241241
// (such as thread suspension).
242-
template <typename PRE_PROC>
242+
template <typename PRE_PROC = void(JavaThread*)>
243243
class ThreadBlockInVMPreprocess : public ThreadStateTransition {
244244
private:
245245
PRE_PROC& _pr;
246246
bool _allow_suspend;
247247
public:
248-
ThreadBlockInVMPreprocess(JavaThread* thread, PRE_PROC& pr, bool allow_suspend = true)
248+
ThreadBlockInVMPreprocess(JavaThread* thread, PRE_PROC& pr = emptyOp, bool allow_suspend = false)
249249
: ThreadStateTransition(thread), _pr(pr), _allow_suspend(allow_suspend) {
250250
assert(thread->thread_state() == _thread_in_vm, "coming from wrong thread state");
251251
thread->check_possible_safepoint();
@@ -266,33 +266,12 @@ class ThreadBlockInVMPreprocess : public ThreadStateTransition {
266266

267267
_thread->set_thread_state(_thread_in_vm);
268268
}
269-
};
270269

271-
class InFlightMutexRelease {
272-
private:
273-
Mutex** _in_flight_mutex_addr;
274-
public:
275-
InFlightMutexRelease(Mutex** in_flight_mutex_addr) : _in_flight_mutex_addr(in_flight_mutex_addr) {}
276-
void operator()(JavaThread* current) {
277-
if (_in_flight_mutex_addr != NULL && *_in_flight_mutex_addr != NULL) {
278-
(*_in_flight_mutex_addr)->release_for_safepoint();
279-
*_in_flight_mutex_addr = NULL;
280-
}
281-
}
270+
static void emptyOp(JavaThread* current) {}
282271
};
283272

284-
// Parameter in_flight_mutex_addr is only used by class Mutex to avoid certain deadlock
285-
// scenarios while making transitions that might block for a safepoint or handshake.
286-
// It's the address of a pointer to the mutex we are trying to acquire. This will be used to
287-
// access and release said mutex when transitioning back from blocked to vm (destructor) in
288-
// case we need to stop for a safepoint or handshake.
289-
class ThreadBlockInVM {
290-
InFlightMutexRelease _ifmr;
291-
ThreadBlockInVMPreprocess<InFlightMutexRelease> _tbivmpp;
292-
public:
293-
ThreadBlockInVM(JavaThread* thread, Mutex** in_flight_mutex_addr = NULL)
294-
: _ifmr(in_flight_mutex_addr), _tbivmpp(thread, _ifmr, /* allow_suspend= */ false) {}
295-
};
273+
typedef ThreadBlockInVMPreprocess<> ThreadBlockInVM;
274+
296275

297276
// Debug class instantiated in JRT_ENTRY macro.
298277
// Can be used to verify properties on enter/exit of the VM.

‎src/hotspot/share/runtime/mutex.cpp

+23-10
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,20 @@
3333
#include "utilities/events.hpp"
3434
#include "utilities/macros.hpp"
3535

36+
class InFlightMutexRelease {
37+
private:
38+
Mutex* _in_flight_mutex;
39+
public:
40+
InFlightMutexRelease(Mutex* in_flight_mutex) : _in_flight_mutex(in_flight_mutex) {
41+
assert(in_flight_mutex != NULL, "must be");
42+
}
43+
void operator()(JavaThread* current) {
44+
_in_flight_mutex->release_for_safepoint();
45+
_in_flight_mutex = NULL;
46+
}
47+
bool not_released() { return _in_flight_mutex != NULL; }
48+
};
49+
3650
#ifdef ASSERT
3751
void Mutex::check_block_state(Thread* thread) {
3852
if (!_allow_vm_block && thread->is_VM_thread()) {
@@ -72,7 +86,6 @@ void Mutex::check_no_safepoint_state(Thread* thread) {
7286
#endif // ASSERT
7387

7488
void Mutex::lock_contended(Thread* self) {
75-
Mutex *in_flight_mutex = NULL;
7689
DEBUG_ONLY(int retry_cnt = 0;)
7790
bool is_active_Java_thread = self->is_active_Java_thread();
7891
do {
@@ -84,13 +97,14 @@ void Mutex::lock_contended(Thread* self) {
8497

8598
// Is it a JavaThread participating in the safepoint protocol.
8699
if (is_active_Java_thread) {
100+
InFlightMutexRelease ifmr(this);
87101
assert(rank() > Mutex::special, "Potential deadlock with special or lesser rank mutex");
88-
{ ThreadBlockInVM tbivmdc(JavaThread::cast(self), &in_flight_mutex);
89-
in_flight_mutex = this; // save for ~ThreadBlockInVM
102+
{
103+
ThreadBlockInVMPreprocess<InFlightMutexRelease> tbivmdc(JavaThread::cast(self), ifmr);
90104
_lock.lock();
91105
}
92-
if (in_flight_mutex != NULL) {
93-
// Not unlocked by ~ThreadBlockInVM
106+
if (ifmr.not_released()) {
107+
// Not unlocked by ~ThreadBlockInVMPreprocess
94108
break;
95109
}
96110
} else {
@@ -234,18 +248,17 @@ bool Monitor::wait(int64_t timeout) {
234248
check_safepoint_state(self);
235249

236250
int wait_status;
237-
Mutex* in_flight_mutex = NULL;
251+
InFlightMutexRelease ifmr(this);
238252

239253
{
240-
ThreadBlockInVM tbivmdc(self, &in_flight_mutex);
254+
ThreadBlockInVMPreprocess<InFlightMutexRelease> tbivmdc(self, ifmr);
241255
OSThreadWaitState osts(self->osthread(), false /* not Object.wait() */);
242256

243257
wait_status = _lock.wait(timeout);
244-
in_flight_mutex = this; // save for ~ThreadBlockInVM
245258
}
246259

247-
if (in_flight_mutex != NULL) {
248-
// Not unlocked by ~ThreadBlockInVM
260+
if (ifmr.not_released()) {
261+
// Not unlocked by ~ThreadBlockInVMPreprocess
249262
assert_owner(NULL);
250263
// Conceptually reestablish ownership of the lock.
251264
set_owner(self);

‎src/hotspot/share/runtime/objectMonitor.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ bool ObjectMonitor::enter(JavaThread* current) {
430430
for (;;) {
431431
ExitOnSuspend eos(this);
432432
{
433-
ThreadBlockInVMPreprocess<ExitOnSuspend> tbivs(current, eos);
433+
ThreadBlockInVMPreprocess<ExitOnSuspend> tbivs(current, eos, true /* allow_suspend */);
434434
EnterI(current);
435435
current->set_current_pending_monitor(NULL);
436436
// We can go to a safepoint at the end of this block. If we
@@ -975,7 +975,7 @@ void ObjectMonitor::ReenterI(JavaThread* current, ObjectWaiter* currentNode) {
975975

976976
{
977977
ClearSuccOnSuspend csos(this);
978-
ThreadBlockInVMPreprocess<ClearSuccOnSuspend> tbivs(current, csos);
978+
ThreadBlockInVMPreprocess<ClearSuccOnSuspend> tbivs(current, csos, true /* allow_suspend */);
979979
current->_ParkEvent->park();
980980
}
981981
}
@@ -1536,7 +1536,7 @@ void ObjectMonitor::wait(jlong millis, bool interruptible, TRAPS) {
15361536

15371537
{
15381538
ClearSuccOnSuspend csos(this);
1539-
ThreadBlockInVMPreprocess<ClearSuccOnSuspend> tbivs(current, csos);
1539+
ThreadBlockInVMPreprocess<ClearSuccOnSuspend> tbivs(current, csos, true /* allow_suspend */);
15401540
if (interrupted || HAS_PENDING_EXCEPTION) {
15411541
// Intentionally empty
15421542
} else if (node._notified == 0) {

0 commit comments

Comments
 (0)
Please sign in to comment.