Does transition_and_fence really assume TSO?

Daniel D. Daugherty daniel.daugherty at oracle.com
Thu Sep 29 21:38:23 UTC 2016


On 8/2/16 6:25 PM, David Holmes wrote:
> Hi Andrew,
>
> On 3/08/2016 10:04 AM, Andrew Haley wrote:
>> Here's an interesting comment:
>>
>>   static inline void transition_and_fence(JavaThread *thread, 
>> JavaThreadState from, JavaThreadState to) {
>>     assert(thread->thread_state() == from, "coming from wrong thread 
>> state");
>>     assert((from & 1) == 0 && (to & 1) == 0, "odd numbers are 
>> transitions states");
>>     // Change to transition state (assumes total store ordering!  -Urs)
>>     thread->set_thread_state((JavaThreadState)(from + 1));
>>
>> The "assumes total store ordering!" comment is rather alarming. My
>> processor is not TSO.  But as far as I can see, all this really
>> requires is single-variable coherency.  Is that right?
>
> That comment is pre-historic. The code does not assume TSO. There is a 
> direct, or implicit, full fence between the two stores:
>
>     // Make sure new state is seen by VM thread
>     if (os::is_MP()) {
>       if (UseMembar) {
>         // Force a fence between the write above and read below
>         OrderAccess::fence();
>       } else {
>         // Must use this rather than serialization page in particular 
> on Windows
>         InterfaceSupport::serialize_memory(thread);
>       }
>     }
>
> Cheers,
> David
>
>> Andrew.
>>

Filling in the history here. There are three instances of
"assumes total store ordering" in src/share/vm/runtime/interfaceSupport.hpp:

$ sgv src/share/vm/runtime/interfaceSupport.hpp | grep 'assumes total 
store ordering'
1.178
1.86        // Change to transition state (assumes total store 
ordering!  -Urs)
1.168       // Change to transition state (assumes total store 
ordering!  -Urs)
1.139.2.1           // Change to transition state (assumes total store 
ordering!  -Urs)
568 lines
No id keywords (cm7)


$ sp -r1.86 src/share/vm/runtime/interfaceSupport.hpp
src/share/vm/runtime/SCCS/s.interfaceSupport.hpp:

D 1.86 98/06/10 11:10:44 urs 151 150    00005/00004/00290
MRs:
COMMENTS:
optimizations to entry & exit code of runtime routines


$ sp -r1.139.2.1 src/share/vm/runtime/interfaceSupport.hpp
src/share/vm/runtime/SCCS/s.interfaceSupport.hpp:

D 1.139.2.1 02/10/22 00:51:52 huanghui 259 249  00017/00003/00455
MRs:
COMMENTS:
4683006 add transition_from_native(), which also checks for pending 
suspend request


$ sp -r1.168 src/share/vm/runtime/interfaceSupport.hpp
src/share/vm/runtime/SCCS/s.interfaceSupport.hpp:

D 1.168 05/08/29 15:14:41 kbr 290 289   00045/00020/00515
MRs:
COMMENTS:
6304225 hotspot/runtime_syst IE crashes with b44 libjvm.dll


The oldest delta has no bug ID:

D 1.86 98/06/10 11:10:44 urs 151 150    00005/00004/00290
MRs:
COMMENTS:
optimizations to entry & exit code of runtime routines

and here's the relevant part of the diff:

67,68c68,69
<     assert(thread->thread_state() == from, "comming from wrong thread 
state");
<     // Change to transition state
---
 >     assert(thread->thread_state() == from, "coming from wrong thread 
state");
 >     // Change to transition state (assumes total store ordering!  -Urs)


The change from Hui has a nice comment:

D 1.139.2.1 02/10/22 00:51:52 huanghui 259 249  00017/00003/00455
MRs:
COMMENTS:
4683006 add transition_from_native(), which also checks for pending 
suspend request

so we know that when Hui added transition_from_native() the comment
was copied. Here's the relevant diffs:

102a104,115
 >
 >   static inline void transition_from_native(JavaThread *thread, 
JavaThreadState to) {
 >     assert((to & 1) == 0, "odd numbers are transitions states");
 >     assert(thread->thread_state() == _thread_in_native, "coming from 
wrong thread state");
 >     // Change to transition state (assumes total store ordering!  -Urs)
 >     thread->set_thread_state(_thread_in_native_trans);
 >     if (os::is_MP()) atomic::membar();
 >     if (SafepointSynchronize::do_call_back() || 
thread->is_external_suspend()) {
 >       JavaThread::check_safepoint_and_suspend(thread);
 >     }
 >     thread->set_thread_state(to);
 >   }


The change from Ken has a bug ID:

D 1.168 05/08/29 15:14:41 kbr 290 289   00045/00020/00515
MRs:
COMMENTS:
6304225 hotspot/runtime_syst IE crashes with b44 libjvm.dll

Here's the relevant diffs:

 >   // transition_and_fence must be used on any thread state transition
 >   // where there might not be a Java call stub on the stack, in
 >   // particular on Windows where the Structured Exception Handler is
 >   // set up in the call stub. os::write_memory_serialize_page() can
 >   // fault and we can't recover from it on Windows without a SEH in
 >   // place.
 >   static inline void transition_and_fence(JavaThread *thread, 
JavaThreadState from, JavaThreadState to) {
 >     assert(thread->thread_state() == from, "coming from wrong thread 
state");
 >     assert((from & 1) == 0 && (to & 1) == 0, "odd numbers are 
transitions states");
 >     // Change to transition state (assumes total store ordering!  -Urs)
 >     thread->set_thread_state((JavaThreadState)(from + 1));
 >
 >     // Make sure new state is seen by VM thread
 >     if (os::is_MP()) {
 >       // Must use this rather than serialization page in particular 
on Windows
 >       InterfaceSupport::serialize_memory(thread);
 >     }
 >
 >     if (SafepointSynchronize::do_call_back()) {
 >       SafepointSynchronize::block(thread);
 >     }
 >     thread->set_thread_state(to);
 >
 > CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
 >   }


Filed the following bug:

JDK-8166927 interfaceSupport.hpp has ancient comments about TSO
https://bugs.openjdk.java.net/browse/JDK-8166927

Dan


More information about the hotspot-dev mailing list