@@ -154,15 +154,44 @@ only to data races?
154
154
155
155
# Atomics
156
156
157
- Rust pretty blatantly just inherits LLVM 's model for atomics, which in turn is
158
- largely based off of the C11 model for atomics. This is not due these models
159
- being particularly excellent or easy to understand. Indeed, these models are
160
- quite complex and are known to have several flaws. Rather, it is a pragmatic
161
- concession to the fact that * everyone * is pretty bad at modeling atomics. At very
162
- least, we can benefit from existing tooling and research around C's model .
157
+ Rust pretty blatantly just inherits C11 's memory model for atomics. This is not
158
+ due this model being particularly excellent or easy to understand. Indeed, this
159
+ model is quite complex and known to have [ several flaws ] [ C11-busted ] . Rather,
160
+ it is a pragmatic concession to the fact that * everyone * is pretty bad at modeling
161
+ atomics. At very least, we can benefit from existing tooling and research around
162
+ C .
163
163
164
- Trying to fully explain these models is fairly hopeless, so we're just going to
165
- drop that problem in LLVM's lap.
164
+ Trying to fully explain the model is fairly hopeless. If you want all the
165
+ nitty-gritty details, you should check out [ C's specification] [ C11-model ] .
166
+ Still, we'll try to cover the basics and some of the problems Rust developers
167
+ face.
168
+
169
+ The C11 memory model is fundamentally about trying to bridge the gap between C's
170
+ single-threaded semantics, common compiler optimizations, and hardware peculiarities
171
+ in the face of a multi-threaded environment. It does this by splitting memory
172
+ accesses into two worlds: data accesses, and atomic accesses.
173
+
174
+ Data accesses are the bread-and-butter of the programming world. They are
175
+ fundamentally unsynchronized and compilers are free to aggressively optimize
176
+ them. In particular data accesses are free to be reordered by the compiler
177
+ on the assumption that the program is single-threaded. The hardware is also free
178
+ to propagate the changes made in data accesses as lazily and inconsistently as
179
+ it wants to other threads. Mostly critically, data accesses are where we get data
180
+ races. These are pretty clearly awful semantics to try to write a multi-threaded
181
+ program with.
182
+
183
+ Atomic accesses are the answer to this. Each atomic access can be marked with
184
+ an * ordering* . The set of orderings Rust exposes are:
185
+
186
+ * Sequentially Consistent (SeqCst)
187
+ * Release
188
+ * Acquire
189
+ * Relaxed
190
+
191
+ (Note: We explicitly do not expose the C11 * consume* ordering)
192
+
193
+ TODO: give simple "basic" explanation of these
194
+ TODO: implementing Arc example (why does Drop need the trailing barrier?)
166
195
167
196
168
197
@@ -184,5 +213,5 @@ with everyone else's stuff.
184
213
185
214
186
215
187
- [ llvm-conc ] : http://llvm. org/docs/Atomics.html
188
- [ trpl-conc ] : https ://doc.rust-lang.org/book/concurrency.html
216
+ [ C11-busted ] : http://plv.mpi-sws. org/c11comp/popl15.pdf
217
+ [ C11-model ] : http ://en.cppreference.com/w/c/atomic/memory_order
0 commit comments