Skip to content

Commit 4b5cb7c

Browse files
committed
Update synchronization
1 parent f99fc02 commit 4b5cb7c

File tree

1 file changed

+21
-12
lines changed

1 file changed

+21
-12
lines changed

doc/synchronization.md

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -115,13 +115,17 @@ class Event < Synchronization::Object
115115
end
116116
```
117117

118-
## Memory model (incomplete)
118+
Operations on `@Touched` field have volatile semantic.
119+
120+
## Memory model
119121

120122
*Intended for further revision, and extension.*
121123

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).
124+
When writing libraries in `concurrent-ruby` we are reasoning based on following memory model which is further extended by features provided in `Synchronization::Object` (described above).
125+
126+
The memory model is constructed based on our best effort and knowledge of the 3 main Ruby implementations (CRuby, JRuby, Rubinius). When considering certain aspect we always choose the weakest guarantee (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 for use in parallel environment (Reasons may be lack of information, or difficulty of verification).
123127

124-
This part takes in account following implementations:
128+
This takes in account following implementations:
125129

126130
- CRuby 1.9 - 2.2 (no differences found)
127131
- JRuby 1.7
@@ -135,13 +139,18 @@ We are interested in following behaviors:
135139

136140
### Variables
137141

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)
142+
- **Local variables** - atomic assignment, non-volatile.
143+
- Consequence: a lambda defined on `thread1` executing on `thread2` may not see updated values in local variables captured in its closure.
144+
- Reason: local variables are non-volatile on Jruby and Rubinius.
145+
- **Instance variables** - atomic assignment, non-volatile.
146+
- Consequence: Different thread may see old values; different thread may see not fully-initialized object.
147+
- Reason: local variables are non-volatile on Jruby and Rubinius.
148+
- **Constants** - atomic assignment, volatile.
149+
150+
Other:
151+
152+
- **Global variables** - we don't use them, omitted (atomic and volatile on JRuby and CRuby, Rubinius unknown)
153+
- **Class variables** - we don't use them, omitted (atomic and volatile on JRuby and CRuby, Rubinius unknown)
145154

146155
### Assumptions
147156

@@ -151,11 +160,11 @@ Following operations are **assumed** thread-safe, volatile and atomic on all imp
151160
- Method definition
152161
- Library requirement
153162

154-
It's best practice thought to eager load before going into parallel part of an application.
163+
It's best practice though to eager load before going into parallel part of an application.
155164

156165
### Issues to be aware of
157166

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.
167+
- **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 see 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.
159168
- **`||=`, `+=` and similar** - are not atomic.
160169

161170
### Notes/Sources on implementations

0 commit comments

Comments
 (0)