Re: RFR: 8257831: Suspend with handshakes [v10]

2021-04-21 Thread Robbin Ehn
On Wed, 21 Apr 2021 04:39:35 GMT, David Holmes  wrote:

>> Borrowing the HandshakeState lock does create an artificial coupling here. 
>> I'd prefer to see this API in a more natural place with friendship used to 
>> access the mechanism as needed. Future cleanup though.
>
> Also I think you'd have a lost-wakeup problem if two locks were involved.

You are correct, above those not work as is. We would need to protect the 
suspend flag with SomeOtherLock, thus also needing to lock SomeOtherLock when 
suspending.

-

PR: https://git.openjdk.java.net/jdk/pull/3191


Re: RFR: 8257831: Suspend with handshakes [v10]

2021-04-20 Thread David Holmes
On Wed, 21 Apr 2021 04:36:07 GMT, David Holmes  wrote:

>> When going to blocked inside the async handshake we **must** unlock the 
>> HandshakeState lock.
>> Thus _lock.wait() unlocks and gives us something to notify.
>> We could do:
>> 
>> _lock.unlock();
>> {
>>   MutexLocker(SomeOtherLock) ml;
>>   SomeOtherLock.wait();
>> }
>> _lock.lock();
>> 
>> 
>> Another alternative is to create a friend class which uses the 
>> HandshakeState lock and having the API there instead.
>
> Borrowing the HandshakeState lock does create an artificial coupling here. 
> I'd prefer to see this API in a more natural place with friendship used to 
> access the mechanism as needed. Future cleanup though.

Also I think you'd have a lost-wakeup problem if two locks were involved.

-

PR: https://git.openjdk.java.net/jdk/pull/3191


Re: RFR: 8257831: Suspend with handshakes [v10]

2021-04-20 Thread David Holmes
On Mon, 19 Apr 2021 07:13:57 GMT, Robbin Ehn  wrote:

>> src/hotspot/share/runtime/handshake.hpp line 133:
>> 
>>> 131: // check the _lock, if held go to slow path.
>>> 132: // Since the handshakee is unsafe if _lock gets locked after this 
>>> check
>>> 133: // we know another thread cannot process any handshakes.
>> 
>> I can't quite understand this comment. I'm not sure what thread is calling 
>> this method and when, in relation to what the handshakee may be doing.
>
> The handshakee is in a safe state, e.g. blocked and does:
> Point A: set_thread_state_fence(_thread_blocked_trans);
> ...
> Point B: _lock.is_locked()
> 
> While the processor thread does:
> Point X: _lock.try_lock();
> ...
> Point Z: thread->thread_state();
> 
> If point B is passed with a non-locked lock, point Z is guaranteed to see an 
> unsafe thread and will not start to process ay handshakes.
> 
> Is that make sense, maybe the comment make more sense ? :)

The comment makes more sense now :)

>> src/hotspot/share/runtime/handshake.hpp line 157:
>> 
>>> 155:   Thread* active_handshaker() const { return _active_handshaker; }
>>> 156: 
>>> 157:   // Suspend/resume support
>> 
>> Taking a step back I can't help but think that this is entirely the wrong 
>> place to have the suspend/resume API and supporting code. It is only here 
>> because we re-use the HandshakeState _lock monitor right? If we introduced a 
>> new thread-suspension monitor instead then this code would all reside 
>> somewhere else - probably in the JavaThread class.
>
> When going to blocked inside the async handshake we **must** unlock the 
> HandshakeState lock.
> Thus _lock.wait() unlocks and gives us something to notify.
> We could do:
> 
> _lock.unlock();
> {
>   MutexLocker(SomeOtherLock) ml;
>   SomeOtherLock.wait();
> }
> _lock.lock();
> 
> 
> Another alternative is to create a friend class which uses the HandshakeState 
> lock and having the API there instead.

Borrowing the HandshakeState lock does create an artificial coupling here. I'd 
prefer to see this API in a more natural place with friendship used to access 
the mechanism as needed. Future cleanup though.

-

PR: https://git.openjdk.java.net/jdk/pull/3191


Re: RFR: 8257831: Suspend with handshakes [v10]

2021-04-19 Thread Robbin Ehn
On Mon, 19 Apr 2021 06:07:54 GMT, David Holmes  wrote:

>> Robbin Ehn has updated the pull request incrementally with one additional 
>> commit since the last revision:
>> 
>>   Fixed nits
>
> src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Thread.java line 
> 83:
> 
>> 81:   }
>> 82: 
>> 83:   public boolean isExtSuspended() {
> 
> A new comment to avoid the "resolved" conversation. I'm still not sure you 
> can just delete this API from the SA. @sspitsyn do you know what the 
> obligations are with respect to the S.A here?

The SA do not have the HandshakeState class implemented, so there is a lot a 
work to make this flag work.

-

PR: https://git.openjdk.java.net/jdk/pull/3191


Re: RFR: 8257831: Suspend with handshakes [v10]

2021-04-19 Thread Robbin Ehn
On Mon, 19 Apr 2021 04:47:33 GMT, David Holmes  wrote:

>> Robbin Ehn has updated the pull request incrementally with one additional 
>> commit since the last revision:
>> 
>>   Fixed nits
>
> src/hotspot/share/runtime/mutex.hpp line 70:
> 
>> 68:tty= access +   2,
>> 69:special= tty+   3,
>> 70:oopstorage = special+   3,
> 
> Why +3? I'm assuming to keep the same numeric value as before, but that 
> doesn't seem necessary and just seems to add to the mystery of why these 
> ranks are defined in such a strange way.

Yes I wanted to keep the numeric rank.

-

PR: https://git.openjdk.java.net/jdk/pull/3191


Re: RFR: 8257831: Suspend with handshakes [v10]

2021-04-19 Thread Richard Reingruber
On Mon, 19 Apr 2021 05:48:44 GMT, David Holmes  wrote:

> It is still not at all clear to me what suspended has to do with the execution
> of this method. The new code just ignores thread suspension.

The caller enters a safe state. It can be suspended iff safe, so the old code
checked for suspension. With the new code suspension is part of handshake
processing, so it is sufficient to check for pending handshakes.

> It seems to me that the old code could also have ignored suspension if the
> checks in handle_special_runtime_exit_condition had be reordered.

In that case JavaThread::java_suspend_self_with_safepoint_check() would have to
be changed to check for `Thread::is_obj_deopt_suspend()` and handle it.

-

PR: https://git.openjdk.java.net/jdk/pull/3191


Re: RFR: 8257831: Suspend with handshakes [v10]

2021-04-19 Thread Robbin Ehn
On Mon, 19 Apr 2021 04:43:15 GMT, David Holmes  wrote:

>> Robbin Ehn has updated the pull request incrementally with one additional 
>> commit since the last revision:
>> 
>>   Fixed nits
>
> src/hotspot/share/runtime/handshake.hpp line 157:
> 
>> 155:   Thread* active_handshaker() const { return _active_handshaker; }
>> 156: 
>> 157:   // Suspend/resume support
> 
> Taking a step back I can't help but think that this is entirely the wrong 
> place to have the suspend/resume API and supporting code. It is only here 
> because we re-use the HandshakeState _lock monitor right? If we introduced a 
> new thread-suspension monitor instead then this code would all reside 
> somewhere else - probably in the JavaThread class.

When going to blocked inside the async handshake we **must** unlock the 
HandshakeState lock.
Thus _lock.wait() unlocks and gives us something to notify.
We could do:

_lock.unlock();
{
  MutexLocker(SomeOtherLock) ml;
  SomeOtherLock.wait();
}
_lock.lock();


Another alternative is to create a friend class which uses the HandshakeState 
lock and having the API there instead.

-

PR: https://git.openjdk.java.net/jdk/pull/3191


Re: RFR: 8257831: Suspend with handshakes [v10]

2021-04-19 Thread Robbin Ehn
On Mon, 19 Apr 2021 04:34:00 GMT, David Holmes  wrote:

>> Robbin Ehn has updated the pull request incrementally with one additional 
>> commit since the last revision:
>> 
>>   Fixed nits
>
> src/hotspot/share/runtime/handshake.hpp line 134:
> 
>> 132: // Since the handshakee is unsafe if _lock gets locked after this 
>> check
>> 133: // we know another thread cannot process any handshakes.
>> 134: // Now we can check queue if there is anything we should process.
> 
> // Now we can check the queue to see if there is anything we should process.

Fixed

-

PR: https://git.openjdk.java.net/jdk/pull/3191


Re: RFR: 8257831: Suspend with handshakes [v10]

2021-04-19 Thread Robbin Ehn
On Mon, 19 Apr 2021 04:19:28 GMT, David Holmes  wrote:

>> Robbin Ehn has updated the pull request incrementally with one additional 
>> commit since the last revision:
>> 
>>   Fixed nits
>
> src/hotspot/share/runtime/handshake.cpp line 630:
> 
>> 628: // This is the closure that prevents a suspended JavaThread from
>> 629: // escaping the suspend request.
>> 630: class ThreadSuspensionHandshake : public AsyncHandshakeClosure {
> 
> I still find ThreadSuspensionHandShake versus SuspendThreadHandshake to be 
> too similarly named and with no obvious way to remember which one is which. 
> Perhaps this one could be called ThreadSelfSuspensionHandshake instead?

Fixed

> src/hotspot/share/runtime/handshake.cpp line 636:
> 
>> 634: JavaThread* target = thr->as_Java_thread();
>> 635: target->handshake_state()->do_self_suspend();
>> 636:   }
> 
> As this must be the current thread we are dealing with can we rename the 
> variables to indicate that.

Fixed

> src/hotspot/share/runtime/handshake.hpp line 128:
> 
>> 126:   // must take slow path, process_by_self(), if _lock is held.
>> 127:   bool should_process() {
>> 128: // When doing thread suspension the holder of the _lock
> 
> Potentially this could be any async handshake operation - right? It seems odd 
> to talk specifically about thread suspension in the core of the handshake 
> code.

Changed

> src/hotspot/share/runtime/handshake.hpp line 131:
> 
>> 129: // can add an asynchronous handshake to queue.
>> 130: // To make sure it is seen by the handshakee, the handshakee must 
>> first
>> 131: // check the _lock, if held go to slow path.
> 
> ..., _and_ if held ...

Fixed

> src/hotspot/share/runtime/handshake.hpp line 133:
> 
>> 131: // check the _lock, if held go to slow path.
>> 132: // Since the handshakee is unsafe if _lock gets locked after this 
>> check
>> 133: // we know another thread cannot process any handshakes.
> 
> I can't quite understand this comment. I'm not sure what thread is calling 
> this method and when, in relation to what the handshakee may be doing.

The handshakee is in a safe state, e.g. blocked and does:
Point A: set_thread_state_fence(_thread_blocked_trans);
...
Point B: _lock.is_locked()

While the processor thread does:
Point X: _lock.try_lock();
...
Point Z: thread->thread_state();

If point B is passed with a non-locked lock, point Z is guaranteed to see an 
unsafe thread and will not start to process ay handshakes.

Is that make sense, maybe the comment make more sense ? :)

-

PR: https://git.openjdk.java.net/jdk/pull/3191


Re: RFR: 8257831: Suspend with handshakes [v10]

2021-04-19 Thread David Holmes
On Fri, 16 Apr 2021 06:44:06 GMT, Robbin Ehn  wrote:

>> A suspend request is done by handshaking thread target thread(s). When 
>> executing the handshake operation we know the target mutator thread is in a 
>> dormant state (as in safepoint safe state). We have a guarantee that it will 
>> check it's poll before leaving the dormant state. To stop the thread from 
>> leaving the the dormant state we install a second asynchronous handshake to 
>> be executed by the targeted thread. The asynchronous handshake will wait on 
>> a monitor while the thread is suspended. The target thread cannot not leave 
>> the dormant state without a resume request.
>> 
>> Per thread suspend requests are naturally serialized by the per thread 
>> HandshakeState lock (we can only execute one handshake at a time per thread).
>> Instead of having a separate lock we use this to our advantage and use 
>> HandshakeState lock for serializing access to the suspend flag and for 
>> wait/notify. 
>> 
>> Suspend:
>> Requesting thread -> synchronous handshake -> target thread
>> Inside synchronus handshake (HandshakeState lock is locked while
>> executing any handshake):
>>  - Set suspended flag
>>  - Install asynchronous handshake
>> 
>> Target thread -> tries to leave dormant state -> Executes handshakes
>> Target only executes asynchronous handshake:
>>  - While suspended
>>  - Go to blocked
>>  - Wait on HandshakeState lock
>> 
>> Resume:
>> Resuming thread:
>>  - Lock HandshakeState lock
>>  - Clear suspended flag
>>  - Notify HandshakeState lock
>>  - Unlock HandshakeState lock
>> 
>> The "suspend requested" flag is an optimization, without it a dormant thread 
>> could be suspended and resumed many times and each would add a new 
>> asynchronous handshake. Suspend requested flag means there is already an 
>> asynchronous suspend handshake in queue which can be re-used, only the 
>> suspend flag needs to be set.
>> 
>> 
>> Some code can be simplified or done in a smarter way but I refrained from 
>> doing such changes instead tried to keep existing code as is as far as 
>> possible. This concerns especially raw monitors.
>> 
>> 
>> Regarding the changed test, the documentation says:
>> "If the calling thread is specified in the request_list array, this function 
>> will not return until some other thread resumes it."
>> 
>> But the code:
>>   LOG("suspendTestedThreads: before JVMTI SuspendThreadList");
>>   err = jvmti->SuspendThreadList(threads_count, threads, results);
>>   ...
>>   // Allow the Main thread to inspect the result of tested threads 
>> suspension
>>   agent_unlock(jni);
>>   
>> The thread will never return from SuspendThreadList until resumed, so it 
>> cannot unlock with agent_unlock().
>> Thus main thread is stuck forever on:
>>   // Block until the suspender thread competes the tested threads suspension 
>>   agent_lock(jni);
>> 
>> And never checks and resumes the threads. So I removed that lock instead 
>> just sleep and check until all thread have the expected suspended state.
>> 
>> 
>> 
>> This version already contains updates after pre-review comments from 
>> @dcubed-ojdk, @pchilano, @coleenp.
>> (Pre-review comments here:
>> https://github.com/openjdk/jdk/pull/2625)
>> 
>>  
>> Testing t1-t8, nsk_jdi/nsk_jvmti/jdk_jdi/tck, KS24, RunThese and
>> combinations like running with -XX:ZCollectionInterval=0.01 -
>> XX:ZFragmentationLimit=0.
>> Running above some of above concurrently (load ~240), slow debug,
>> etc...
>
> Robbin Ehn has updated the pull request incrementally with one additional 
> commit since the last revision:
> 
>   Fixed nits

Hi Robbin,

I have gone through everything again in detail. A few comments on comments and 
a couple of details I'm still not really clear on.

A couple of small renaming requests, but otherwise this is good to go - with 
the caveat of a future RFE to clear up the suspend-while-locking 
implementations so things are more cleanly encapsulated.

Thanks,
David

src/hotspot/share/runtime/handshake.cpp line 630:

> 628: // This is the closure that prevents a suspended JavaThread from
> 629: // escaping the suspend request.
> 630: class ThreadSuspensionHandshake : public AsyncHandshakeClosure {

I still find ThreadSuspensionHandShake versus SuspendThreadHandshake to be too 
similarly named and with no obvious way to remember which one is which. Perhaps 
this one could be called ThreadSelfSuspensionHandshake instead?

src/hotspot/share/runtime/handshake.cpp line 636:

> 634: JavaThread* target = thr->as_Java_thread();
> 635: target->handshake_state()->do_self_suspend();
> 636:   }

As this must be the current thread we are dealing with can we rename the 
variables to indicate that.

src/hotspot/share/runtime/handshake.hpp line 128:

> 126:   // must take slow path, process_by_self(), if _lock is held.
> 127:   bool should_process() {
> 128: // When doing thread suspension the holder of the _lock


Re: RFR: 8257831: Suspend with handshakes [v10]

2021-04-16 Thread Daniel D . Daugherty
On Fri, 16 Apr 2021 06:44:06 GMT, Robbin Ehn  wrote:

>> A suspend request is done by handshaking thread target thread(s). When 
>> executing the handshake operation we know the target mutator thread is in a 
>> dormant state (as in safepoint safe state). We have a guarantee that it will 
>> check it's poll before leaving the dormant state. To stop the thread from 
>> leaving the the dormant state we install a second asynchronous handshake to 
>> be executed by the targeted thread. The asynchronous handshake will wait on 
>> a monitor while the thread is suspended. The target thread cannot not leave 
>> the dormant state without a resume request.
>> 
>> Per thread suspend requests are naturally serialized by the per thread 
>> HandshakeState lock (we can only execute one handshake at a time per thread).
>> Instead of having a separate lock we use this to our advantage and use 
>> HandshakeState lock for serializing access to the suspend flag and for 
>> wait/notify. 
>> 
>> Suspend:
>> Requesting thread -> synchronous handshake -> target thread
>> Inside synchronus handshake (HandshakeState lock is locked while
>> executing any handshake):
>>  - Set suspended flag
>>  - Install asynchronous handshake
>> 
>> Target thread -> tries to leave dormant state -> Executes handshakes
>> Target only executes asynchronous handshake:
>>  - While suspended
>>  - Go to blocked
>>  - Wait on HandshakeState lock
>> 
>> Resume:
>> Resuming thread:
>>  - Lock HandshakeState lock
>>  - Clear suspended flag
>>  - Notify HandshakeState lock
>>  - Unlock HandshakeState lock
>> 
>> The "suspend requested" flag is an optimization, without it a dormant thread 
>> could be suspended and resumed many times and each would add a new 
>> asynchronous handshake. Suspend requested flag means there is already an 
>> asynchronous suspend handshake in queue which can be re-used, only the 
>> suspend flag needs to be set.
>> 
>> 
>> Some code can be simplified or done in a smarter way but I refrained from 
>> doing such changes instead tried to keep existing code as is as far as 
>> possible. This concerns especially raw monitors.
>> 
>> 
>> Regarding the changed test, the documentation says:
>> "If the calling thread is specified in the request_list array, this function 
>> will not return until some other thread resumes it."
>> 
>> But the code:
>>   LOG("suspendTestedThreads: before JVMTI SuspendThreadList");
>>   err = jvmti->SuspendThreadList(threads_count, threads, results);
>>   ...
>>   // Allow the Main thread to inspect the result of tested threads 
>> suspension
>>   agent_unlock(jni);
>>   
>> The thread will never return from SuspendThreadList until resumed, so it 
>> cannot unlock with agent_unlock().
>> Thus main thread is stuck forever on:
>>   // Block until the suspender thread competes the tested threads suspension 
>>   agent_lock(jni);
>> 
>> And never checks and resumes the threads. So I removed that lock instead 
>> just sleep and check until all thread have the expected suspended state.
>> 
>> 
>> 
>> This version already contains updates after pre-review comments from 
>> @dcubed-ojdk, @pchilano, @coleenp.
>> (Pre-review comments here:
>> https://github.com/openjdk/jdk/pull/2625)
>> 
>>  
>> Testing t1-t8, nsk_jdi/nsk_jvmti/jdk_jdi/tck, KS24, RunThese and
>> combinations like running with -XX:ZCollectionInterval=0.01 -
>> XX:ZFragmentationLimit=0.
>> Running above some of above concurrently (load ~240), slow debug,
>> etc...
>
> Robbin Ehn has updated the pull request incrementally with one additional 
> commit since the last revision:
> 
>   Fixed nits

Reviewed the v09 incremental. Still thumbs up.

-

Marked as reviewed by dcubed (Reviewer).

PR: https://git.openjdk.java.net/jdk/pull/3191


Re: RFR: 8257831: Suspend with handshakes [v10]

2021-04-16 Thread Serguei Spitsyn
On Fri, 16 Apr 2021 06:44:06 GMT, Robbin Ehn  wrote:

>> A suspend request is done by handshaking thread target thread(s). When 
>> executing the handshake operation we know the target mutator thread is in a 
>> dormant state (as in safepoint safe state). We have a guarantee that it will 
>> check it's poll before leaving the dormant state. To stop the thread from 
>> leaving the the dormant state we install a second asynchronous handshake to 
>> be executed by the targeted thread. The asynchronous handshake will wait on 
>> a monitor while the thread is suspended. The target thread cannot not leave 
>> the dormant state without a resume request.
>> 
>> Per thread suspend requests are naturally serialized by the per thread 
>> HandshakeState lock (we can only execute one handshake at a time per thread).
>> Instead of having a separate lock we use this to our advantage and use 
>> HandshakeState lock for serializing access to the suspend flag and for 
>> wait/notify. 
>> 
>> Suspend:
>> Requesting thread -> synchronous handshake -> target thread
>> Inside synchronus handshake (HandshakeState lock is locked while
>> executing any handshake):
>>  - Set suspended flag
>>  - Install asynchronous handshake
>> 
>> Target thread -> tries to leave dormant state -> Executes handshakes
>> Target only executes asynchronous handshake:
>>  - While suspended
>>  - Go to blocked
>>  - Wait on HandshakeState lock
>> 
>> Resume:
>> Resuming thread:
>>  - Lock HandshakeState lock
>>  - Clear suspended flag
>>  - Notify HandshakeState lock
>>  - Unlock HandshakeState lock
>> 
>> The "suspend requested" flag is an optimization, without it a dormant thread 
>> could be suspended and resumed many times and each would add a new 
>> asynchronous handshake. Suspend requested flag means there is already an 
>> asynchronous suspend handshake in queue which can be re-used, only the 
>> suspend flag needs to be set.
>> 
>> 
>> Some code can be simplified or done in a smarter way but I refrained from 
>> doing such changes instead tried to keep existing code as is as far as 
>> possible. This concerns especially raw monitors.
>> 
>> 
>> Regarding the changed test, the documentation says:
>> "If the calling thread is specified in the request_list array, this function 
>> will not return until some other thread resumes it."
>> 
>> But the code:
>>   LOG("suspendTestedThreads: before JVMTI SuspendThreadList");
>>   err = jvmti->SuspendThreadList(threads_count, threads, results);
>>   ...
>>   // Allow the Main thread to inspect the result of tested threads 
>> suspension
>>   agent_unlock(jni);
>>   
>> The thread will never return from SuspendThreadList until resumed, so it 
>> cannot unlock with agent_unlock().
>> Thus main thread is stuck forever on:
>>   // Block until the suspender thread competes the tested threads suspension 
>>   agent_lock(jni);
>> 
>> And never checks and resumes the threads. So I removed that lock instead 
>> just sleep and check until all thread have the expected suspended state.
>> 
>> 
>> 
>> This version already contains updates after pre-review comments from 
>> @dcubed-ojdk, @pchilano, @coleenp.
>> (Pre-review comments here:
>> https://github.com/openjdk/jdk/pull/2625)
>> 
>>  
>> Testing t1-t8, nsk_jdi/nsk_jvmti/jdk_jdi/tck, KS24, RunThese and
>> combinations like running with -XX:ZCollectionInterval=0.01 -
>> XX:ZFragmentationLimit=0.
>> Running above some of above concurrently (load ~240), slow debug,
>> etc...
>
> Robbin Ehn has updated the pull request incrementally with one additional 
> commit since the last revision:
> 
>   Fixed nits

Marked as reviewed by sspitsyn (Reviewer).

-

PR: https://git.openjdk.java.net/jdk/pull/3191


Re: RFR: 8257831: Suspend with handshakes [v10]

2021-04-16 Thread Robbin Ehn
> A suspend request is done by handshaking thread target thread(s). When 
> executing the handshake operation we know the target mutator thread is in a 
> dormant state (as in safepoint safe state). We have a guarantee that it will 
> check it's poll before leaving the dormant state. To stop the thread from 
> leaving the the dormant state we install a second asynchronous handshake to 
> be executed by the targeted thread. The asynchronous handshake will wait on a 
> monitor while the thread is suspended. The target thread cannot not leave the 
> dormant state without a resume request.
> 
> Per thread suspend requests are naturally serialized by the per thread 
> HandshakeState lock (we can only execute one handshake at a time per thread).
> Instead of having a separate lock we use this to our advantage and use 
> HandshakeState lock for serializing access to the suspend flag and for 
> wait/notify. 
> 
> Suspend:
> Requesting thread -> synchronous handshake -> target thread
> Inside synchronus handshake (HandshakeState lock is locked while
> executing any handshake):
>   - Set suspended flag
>   - Install asynchronous handshake
> 
> Target thread -> tries to leave dormant state -> Executes handshakes
> Target only executes asynchronous handshake:
>   - While suspended
>   - Go to blocked
>   - Wait on HandshakeState lock
> 
> Resume:
> Resuming thread:
>   - Lock HandshakeState lock
>   - Clear suspended flag
>   - Notify HandshakeState lock
>   - Unlock HandshakeState lock
> 
> The "suspend requested" flag is an optimization, without it a dormant thread 
> could be suspended and resumed many times and each would add a new 
> asynchronous handshake. Suspend requested flag means there is already an 
> asynchronous suspend handshake in queue which can be re-used, only the 
> suspend flag needs to be set.
> 
> 
> Some code can be simplified or done in a smarter way but I refrained from 
> doing such changes instead tried to keep existing code as is as far as 
> possible. This concerns especially raw monitors.
> 
> 
> Regarding the changed test, the documentation says:
> "If the calling thread is specified in the request_list array, this function 
> will not return until some other thread resumes it."
> 
> But the code:
>   LOG("suspendTestedThreads: before JVMTI SuspendThreadList");
>   err = jvmti->SuspendThreadList(threads_count, threads, results);
>   ...
>   // Allow the Main thread to inspect the result of tested threads suspension 
>   agent_unlock(jni);
>   
> The thread will never return from SuspendThreadList until resumed, so it 
> cannot unlock with agent_unlock().
> Thus main thread is stuck forever on:
>   // Block until the suspender thread competes the tested threads suspension  
>   agent_lock(jni);
> 
> And never checks and resumes the threads. So I removed that lock instead just 
> sleep and check until all thread have the expected suspended state.
> 
> 
> 
> This version already contains updates after pre-review comments from 
> @dcubed-ojdk, @pchilano, @coleenp.
> (Pre-review comments here:
> https://github.com/openjdk/jdk/pull/2625)
> 
>  
> Testing t1-t8, nsk_jdi/nsk_jvmti/jdk_jdi/tck, KS24, RunThese and
> combinations like running with -XX:ZCollectionInterval=0.01 -
> XX:ZFragmentationLimit=0.
> Running above some of above concurrently (load ~240), slow debug,
> etc...

Robbin Ehn has updated the pull request incrementally with one additional 
commit since the last revision:

  Fixed nits

-

Changes:
  - all: https://git.openjdk.java.net/jdk/pull/3191/files
  - new: https://git.openjdk.java.net/jdk/pull/3191/files/27bf041c..d6e091da

Webrevs:
 - full: https://webrevs.openjdk.java.net/?repo=jdk=3191=09
 - incr: https://webrevs.openjdk.java.net/?repo=jdk=3191=08-09

  Stats: 3 lines in 1 file changed: 0 ins; 0 del; 3 mod
  Patch: https://git.openjdk.java.net/jdk/pull/3191.diff
  Fetch: git fetch https://git.openjdk.java.net/jdk pull/3191/head:pull/3191

PR: https://git.openjdk.java.net/jdk/pull/3191