23
23
public class SynchronizationLibrary implements Library {
24
24
25
25
private static final Unsafe UNSAFE = loadUnsafe ();
26
+ private static final boolean FULL_FENCE = supportsFences ();
26
27
27
28
private static Unsafe loadUnsafe () {
28
29
try {
@@ -140,17 +141,17 @@ public static class JRubyAttrVolatile {
140
141
// volatile threadContext is used as a memory barrier per the JVM memory model happens-before semantic
141
142
// on volatile fields. any volatile field could have been used but using the thread context is an
142
143
// attempt to avoid code elimination.
143
- private static volatile ThreadContext threadContext = null ;
144
+ private static volatile int volatileField ;
144
145
145
146
@ JRubyMethod (name = "full_memory_barrier" , visibility = Visibility .PUBLIC )
146
147
public static IRubyObject fullMemoryBarrier (ThreadContext context , IRubyObject self ) {
147
148
// Prevent reordering of ivar writes with publication of this instance
148
- if (!supportsFences () ) {
149
+ if (!FULL_FENCE ) {
149
150
// Assuming that following volatile read and write is not eliminated it simulates fullFence.
150
151
// If it's eliminated it'll cause problems only on non-x86 platforms.
151
152
// http://shipilev.net/blog/2014/jmm-pragmatics/#_happens_before_test_your_understanding
152
- final ThreadContext oldContext = threadContext ;
153
- threadContext = context ;
153
+ final int volatileRead = volatileField ;
154
+ volatileField = context . getLine () ;
154
155
} else {
155
156
UNSAFE .fullFence ();
156
157
}
@@ -163,9 +164,9 @@ public static IRubyObject instanceVariableGetVolatile(
163
164
IRubyObject self ,
164
165
IRubyObject name ) {
165
166
// Ensure we ses latest value with loadFence
166
- if (!supportsFences () ) {
167
+ if (!FULL_FENCE ) {
167
168
// piggybacking on volatile read, simulating loadFence
168
- final ThreadContext oldContext = threadContext ;
169
+ final int volatileRead = volatileField ;
169
170
return ((RubyBasicObject ) self ).instance_variable_get (context , name );
170
171
} else {
171
172
UNSAFE .loadFence ();
@@ -180,10 +181,10 @@ public static IRubyObject InstanceVariableSetVolatile(
180
181
IRubyObject name ,
181
182
IRubyObject value ) {
182
183
// Ensure we make last update visible
183
- if (!supportsFences () ) {
184
+ if (!FULL_FENCE ) {
184
185
// piggybacking on volatile write, simulating storeFence
185
186
final IRubyObject result = ((RubyBasicObject ) self ).instance_variable_set (name , value );
186
- threadContext = context ;
187
+ volatileField = context . getLine () ;
187
188
return result ;
188
189
} else {
189
190
// JRuby uses StampedVariableAccessor which calls fullFence
0 commit comments