1.1 --- a/src/share/vm/runtime/objectMonitor.cpp Wed Feb 26 18:51:19 2014 +0100 1.2 +++ b/src/share/vm/runtime/objectMonitor.cpp Wed Feb 26 17:36:20 2014 -0800 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -382,6 +382,12 @@ 1.11 DTRACE_MONITOR_PROBE(contended__enter, this, object(), jt); 1.12 if (JvmtiExport::should_post_monitor_contended_enter()) { 1.13 JvmtiExport::post_monitor_contended_enter(jt, this); 1.14 + 1.15 + // The current thread does not yet own the monitor and does not 1.16 + // yet appear on any queues that would get it made the successor. 1.17 + // This means that the JVMTI_EVENT_MONITOR_CONTENDED_ENTER event 1.18 + // handler cannot accidentally consume an unpark() meant for the 1.19 + // ParkEvent associated with this ObjectMonitor. 1.20 } 1.21 1.22 OSThreadContendState osts(Self->osthread()); 1.23 @@ -439,6 +445,12 @@ 1.24 DTRACE_MONITOR_PROBE(contended__entered, this, object(), jt); 1.25 if (JvmtiExport::should_post_monitor_contended_entered()) { 1.26 JvmtiExport::post_monitor_contended_entered(jt, this); 1.27 + 1.28 + // The current thread already owns the monitor and is not going to 1.29 + // call park() for the remainder of the monitor enter protocol. So 1.30 + // it doesn't matter if the JVMTI_EVENT_MONITOR_CONTENDED_ENTERED 1.31 + // event handler consumed an unpark() issued by the thread that 1.32 + // just exited the monitor. 1.33 } 1.34 1.35 if (event.should_commit()) { 1.36 @@ -1456,6 +1468,14 @@ 1.37 // Note: 'false' parameter is passed here because the 1.38 // wait was not timed out due to thread interrupt. 1.39 JvmtiExport::post_monitor_waited(jt, this, false); 1.40 + 1.41 + // In this short circuit of the monitor wait protocol, the 1.42 + // current thread never drops ownership of the monitor and 1.43 + // never gets added to the wait queue so the current thread 1.44 + // cannot be made the successor. This means that the 1.45 + // JVMTI_EVENT_MONITOR_WAITED event handler cannot accidentally 1.46 + // consume an unpark() meant for the ParkEvent associated with 1.47 + // this ObjectMonitor. 1.48 } 1.49 if (event.should_commit()) { 1.50 post_monitor_wait_event(&event, 0, millis, false); 1.51 @@ -1499,21 +1519,6 @@ 1.52 exit (true, Self) ; // exit the monitor 1.53 guarantee (_owner != Self, "invariant") ; 1.54 1.55 - // As soon as the ObjectMonitor's ownership is dropped in the exit() 1.56 - // call above, another thread can enter() the ObjectMonitor, do the 1.57 - // notify(), and exit() the ObjectMonitor. If the other thread's 1.58 - // exit() call chooses this thread as the successor and the unpark() 1.59 - // call happens to occur while this thread is posting a 1.60 - // MONITOR_CONTENDED_EXIT event, then we run the risk of the event 1.61 - // handler using RawMonitors and consuming the unpark(). 1.62 - // 1.63 - // To avoid the problem, we re-post the event. This does no harm 1.64 - // even if the original unpark() was not consumed because we are the 1.65 - // chosen successor for this monitor. 1.66 - if (node._notified != 0 && _succ == Self) { 1.67 - node._event->unpark(); 1.68 - } 1.69 - 1.70 // The thread is on the WaitSet list - now park() it. 1.71 // On MP systems it's conceivable that a brief spin before we park 1.72 // could be profitable. 1.73 @@ -1597,6 +1602,33 @@ 1.74 JvmtiExport::post_monitor_waited(jt, this, ret == OS_TIMEOUT); 1.75 } 1.76 1.77 + // Without the fix for 8028280, it is possible for the above call: 1.78 + // 1.79 + // Thread::SpinAcquire (&_WaitSetLock, "WaitSet - unlink") ; 1.80 + // 1.81 + // to consume the unpark() that was done when the successor was set. 1.82 + // The solution for this very rare possibility is to redo the unpark() 1.83 + // outside of the JvmtiExport::should_post_monitor_waited() check. 1.84 + // 1.85 + if (node._notified != 0 && _succ == Self) { 1.86 + // In this part of the monitor wait-notify-reenter protocol it 1.87 + // is possible (and normal) for another thread to do a fastpath 1.88 + // monitor enter-exit while this thread is still trying to get 1.89 + // to the reenter portion of the protocol. 1.90 + // 1.91 + // The ObjectMonitor was notified and the current thread is 1.92 + // the successor which also means that an unpark() has already 1.93 + // been done. The JVMTI_EVENT_MONITOR_WAITED event handler can 1.94 + // consume the unpark() that was done when the successor was 1.95 + // set because the same ParkEvent is shared between Java 1.96 + // monitors and JVM/TI RawMonitors (for now). 1.97 + // 1.98 + // We redo the unpark() to ensure forward progress, i.e., we 1.99 + // don't want all pending threads hanging (parked) with none 1.100 + // entering the unlocked monitor. 1.101 + node._event->unpark(); 1.102 + } 1.103 + 1.104 if (event.should_commit()) { 1.105 post_monitor_wait_event(&event, node._notifier_tid, millis, ret == OS_TIMEOUT); 1.106 }