On Fri, 23 Dec 2022 00:26:02 GMT, Serguei Spitsyn <sspit...@openjdk.org> wrote:

>> src/hotspot/share/prims/jvmtiThreadState.cpp line 315:
>> 
>>> 313:     ml.wait(10); // wait while the virtual thread is in transition
>>> 314:   }
>>> 315:   java_lang_Thread::inc_VTMS_transition_disable_count(vth());
>> 
>> I think this sequence coupled with how start_VTMS_transition() works can 
>> have races. So the check vstate->is_in_VTMS_transition() could return false, 
>> but before we execute inc_VTMS_transition_disable_count() the target could 
>> have already called and returned from start_VTMS_transition(). 
>> Just to test this I added a nanosleep() call in between those two, and an 
>> assert before returning from 
>> JvmtiVTMSTransitionDisabler::JvmtiVTMSTransitionDisabler(jthread thread) 
>> that the target is not in the middle of a transition. Running the 
>> serviceability/jvmti/vthread/ tests gives me some crashes in that assert. 
>> Test patch: 
>> https://github.com/pchilano/jdk/commit/9bc22771bf324f69bc4f5a9786f1b21937aab3c7
>> 
>> If I compare with how the "disable all" case works, in there, the target 
>> transitioning sets a variable(_VTMS_transition_count) and then reads another 
>> one(_VTMS_transition_disable_for_all_count) set by the transition disabler. 
>> The transition disabler does the same but with the variables reversed, i.e. 
>> sets _VTMS_transition_disable_for_all_count and then reads 
>> _VTMS_transition_count. This correctly makes sure that if we read the value 
>> that allow us to return from the method then we have already written the 
>> flag that will stop the other thread. But in this "single" case I don't see 
>> the same pattern.
>
> I see the problem. Good catch, thanks!

Yep my bad in earlier review. The one case needs the same 
synchronization/coordination as the all case.

-------------

PR: https://git.openjdk.org/jdk/pull/11690

Reply via email to