Skip to content

Commit

Permalink
Synchronisation support for Java 7
Browse files Browse the repository at this point in the history
  • Loading branch information
pitr-ch committed Sep 16, 2015
1 parent a9da852 commit 7b03abb
Showing 1 changed file with 28 additions and 21 deletions.
49 changes: 28 additions & 21 deletions ext/com/concurrent_ruby/ext/SynchronizationLibrary.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,17 @@ private RubyClass defineClass(Ruby runtime, RubyModule namespace, String parentN
return newClass;
}

// Facts:
// - all ivar reads are without any synchronisation of fences see
// https://github.com/jruby/jruby/blob/master/core/src/main/java/org/jruby/runtime/ivars/VariableAccessor.java#L110-110
// - writes depend on UnsafeHolder.U, null -> SynchronizedVariableAccessor, !null -> StampedVariableAccessor
// SynchronizedVariableAccessor wraps with synchronized block, StampedVariableAccessor uses fullFence or
// volatilePut

@JRubyClass(name = "JRubyObject", parent = "AbstractObject")
public static class JRubyObject extends RubyObject {
private static volatile ThreadContext threadContext = null;

public JRubyObject(Ruby runtime, RubyClass metaClass) {
super(runtime, metaClass);
}
Expand All @@ -87,10 +96,12 @@ public IRubyObject initialize(ThreadContext context) {

@JRubyMethod(name = "full_memory_barrier", visibility = Visibility.PRIVATE)
public IRubyObject fullMemoryBarrier(ThreadContext context) {
// Prevent reordering of ivar writes with publication of this instance
if (UnsafeHolder.U == null || !UnsafeHolder.SUPPORTS_FENCES) {
throw new UnsupportedOperationException(
"concurrent-ruby requires java with sun.mics.Unsafe fences support, such as Java 8. " +
"Current version is: " + System.getProperty("java.version"));
// Assuming that following volatile read and write is not eliminated it simulates fullFence.
// If it's eliminated it'll cause problems only on non-x86 platforms.
final ThreadContext oldContext = threadContext;
threadContext = context;
} else {
UnsafeHolder.fullFence();
}
Expand All @@ -99,34 +110,30 @@ public IRubyObject fullMemoryBarrier(ThreadContext context) {

@JRubyMethod(name = "instance_variable_get_volatile", visibility = Visibility.PROTECTED)
public IRubyObject instanceVariableGetVolatile(ThreadContext context, IRubyObject name) {
if (UnsafeHolder.U == null) {
synchronized (this) {
// TODO (pitr 06-Sep-2015): Possibly dangerous, there may be a deadlock here
// TODO (pitr 08-Sep-2015): maybe remove the branch since full_memory_barrier is not supported anyway
return instance_variable_get(context, name);
}
} else if (UnsafeHolder.SUPPORTS_FENCES) {
// ensure we see latest value
UnsafeHolder.loadFence();
// Ensure we ses latest value with loadFence
if (UnsafeHolder.U == null || !UnsafeHolder.SUPPORTS_FENCES) {
// piggybacking on volatile read, simulating loadFence
final ThreadContext oldContext = threadContext;
return instance_variable_get(context, name);
} else {
throw new UnsupportedOperationException();
UnsafeHolder.loadFence();
return instance_variable_get(context, name);
}
}

@JRubyMethod(name = "instance_variable_set_volatile", visibility = Visibility.PROTECTED)
public IRubyObject InstanceVariableSetVolatile(ThreadContext context, IRubyObject name, IRubyObject value) {
if (UnsafeHolder.U == null) {
synchronized (this) {
return instance_variable_set(name, value);
}
} else if (UnsafeHolder.SUPPORTS_FENCES) {
// Ensure we make last update visible
if (UnsafeHolder.U == null || !UnsafeHolder.SUPPORTS_FENCES) {
// piggybacking on volatile write, simulating storeFence
final IRubyObject result = instance_variable_set(name, value);
// ensure we make latest value visible
UnsafeHolder.storeFence();
threadContext = context;
return result;
} else {
throw new UnsupportedOperationException();
// JRuby uses StampedVariableAccessor which calls fullFence
// so no additional steps needed.
// See https://github.com/jruby/jruby/blob/master/core/src/main/java/org/jruby/runtime/ivars/StampedVariableAccessor.java#L151-L159
return instance_variable_set(name, value);
}
}
}
Expand Down

0 comments on commit 7b03abb

Please sign in to comment.