Skip to content

Commit 2cb263d

Browse files
committed
Add documentation
* to volatile read/write methods * Float assignment may not be atomic
1 parent 3384363 commit 2cb263d

File tree

2 files changed

+8
-3
lines changed

2 files changed

+8
-3
lines changed

doc/synchronization.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,13 +139,14 @@ We are interested in following behaviors:
139139

140140
### Variables
141141

142-
- **Local variables** - atomic assignment, non-volatile.
142+
- **Local variables** - atomic assignment (only Integer and Object), non-volatile.
143143
- Consequence: a lambda defined on `thread1` executing on `thread2` may not see updated values in local variables captured in its closure.
144144
- Reason: local variables are non-volatile on Jruby and Rubinius.
145-
- **Instance variables** - atomic assignment, non-volatile.
145+
- **Instance variables** - atomic assignment (only Integer and Object), non-volatile.
146146
- Consequence: Different thread may see old values; different thread may see not fully-initialized object.
147147
- Reason: local variables are non-volatile on Jruby and Rubinius.
148148
- **Constants** - atomic assignment, volatile.
149+
- **Assignments of Float** may not be atomic (some implementations (e.g. Truffle) may use native double).
149150

150151
Other:
151152

ext/com/concurrent_ruby/ext/SynchronizationLibrary.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,10 +121,12 @@ public IRubyObject ensureIvarVisibilityBang(ThreadContext context) {
121121
@JRubyMethod(name = "instance_variable_get_volatile", visibility = Visibility.PROTECTED)
122122
public IRubyObject instanceVariableGetVolatile(ThreadContext context, IRubyObject name) {
123123
if (UnsafeHolder.U == null) {
124+
// TODO: Possibly dangerous, there may be a deadlock on the this
124125
synchronized (this) {
125126
return instance_variable_get(context, name);
126127
}
127128
} else if (UnsafeHolder.SUPPORTS_FENCES) {
129+
// ensure we see latest value
128130
UnsafeHolder.loadFence();
129131
return instance_variable_get(context, name);
130132
} else {
@@ -136,11 +138,13 @@ public IRubyObject instanceVariableGetVolatile(ThreadContext context, IRubyObjec
136138
@JRubyMethod(name = "instance_variable_set_volatile", visibility = Visibility.PROTECTED)
137139
public IRubyObject InstanceVariableSetVolatile(ThreadContext context, IRubyObject name, IRubyObject value) {
138140
if (UnsafeHolder.U == null) {
141+
// TODO: Possibly dangerous, there may be a deadlock on the this
139142
synchronized (this) {
140143
return instance_variable_set(name, value);
141144
}
142145
} else if (UnsafeHolder.SUPPORTS_FENCES) {
143-
IRubyObject result = instance_variable_set(name, value);
146+
final IRubyObject result = instance_variable_set(name, value);
147+
// ensure we make latest value visible
144148
UnsafeHolder.storeFence();
145149
return result;
146150
} else {

0 commit comments

Comments
 (0)