Skip to content

Commit a48afe8

Browse files
committed
More documentation
1 parent fbb2e1f commit a48afe8

File tree

1 file changed

+48
-3
lines changed

1 file changed

+48
-3
lines changed

doc/synchronization.md

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ end
8888

8989
### Naming conventions
9090

91-
Instance variables with camel case names are final and never reassigned.
91+
Instance variables with camel case names are final and never reassigned, e.g. `@FinalVariable`.
9292

9393
## Fields with CAS operations
9494

@@ -115,7 +115,52 @@ class Event < Synchronization::Object
115115
end
116116
```
117117

118-
## Memory model (sort of)
118+
## Memory model (incomplete)
119119

120-
// TODO
120+
*Intended for further revision, and extension.*
121+
122+
`Synchronization::Object` provides an unified behavior for different Ruby implementations on top of this memory model. This part provides a summary of how Ruby (any implementation) behaves in parallel environment. It is built using the weakest behavior provided by any of the implementations for a particular language element. (E.g. local variable updates are always visible in CRuby but not in JRuby, so in this case JRuby behavior is picked.). If some Ruby behavior is omitted here it is considered unsafe foe use in parallel environment (Reasons may be lack of information, or difficulty of verification).
123+
124+
This part takes in account following implementations:
125+
126+
- CRuby 1.9 - 2.2 (no differences found)
127+
- JRuby 1.7
128+
- JRuby 9 *not examined yet, same behavior as in 1.7 assumed*
129+
- Rubinius 2.5
130+
131+
We are interested in following behaviors:
132+
133+
- **volatility** - in Java's sense. Any written value is immediately visible to any subsequent reads including all writes leading to this value.
134+
- **atomicity** - operation is either done or not as a whole.
135+
136+
### Variables
137+
138+
- **Local variables** - atomic, non-volatile.
139+
Consequence: a lambda defined on `thread1` executing on `thread2` may not see updated values in local variables captured in its closure.
140+
- **Instance variables** - atomic, non-volatile.
141+
Consequence: Different thread may see old values; different thread may see not fully-initialized object.
142+
- **Constants** - atomic, volatile.
143+
- **Global variables** - omitted (atomic and volatile on JRuby and CRuby)
144+
- **Class variables** - omitted (atomic and volatile on JRuby and CRuby)
145+
146+
### Assumptions
147+
148+
Following operations are **assumed** thread-safe, volatile and atomic on all implementations:
149+
150+
- Class definition
151+
- Method definition
152+
- Library requirement
153+
154+
It's best practice thought to eager load before going into parallel part of an application.
155+
156+
### Issues to be aware of
157+
158+
- **Initialization** - Since instance variables are not volatile and a particular implementation may preinitialize values with nils, based on shapes it already saw, a second thread obtaining reference to newly constructed may still se old preinitialized values instead of values set in `initialize` method. To fix this `ensure_ivar_visibility!` can be used or the object can be safely published in a volatile field.
159+
- **`||=`, `+=` and similar** - are not atomic.
160+
161+
### Notes/Sources on implementations
162+
163+
- [JRuby wiki page on concurrency](https://github.com/jruby/jruby/wiki/Concurrency-in-jruby)
164+
- [Rubinius page on concurrency](http://rubini.us/doc/en/systems/concurrency/)
165+
- CRuby has GVL. Any GVL release and acquire uses lock which means that all writes done by a releasing thread will be visible to the second acquiring thread. See: <https://github.com/ruby/ruby/blob/ruby_2_2/thread_pthread.c#L101-L107>
121166

0 commit comments

Comments
 (0)