|
28 | 28 | // M. Batty, S. Owens, S. Sarkar, P. Sewell and T. Weber,
|
29 | 29 | // "Mathematizing C++ concurrency", ACM SIGPLAN Notices, vol. 46, no. 1, pp. 55-66, 2011.
|
30 | 30 | // Available: https://ss265.host.cs.st-andrews.ac.uk/papers/n3132.pdf.
|
| 31 | +#![feature(atomic_from_mut)] |
31 | 32 |
|
32 | 33 | use std::sync::atomic::Ordering::*;
|
33 |
| -use std::sync::atomic::{fence, AtomicUsize}; |
| 34 | +use std::sync::atomic::{fence, AtomicU16, AtomicU32, AtomicUsize}; |
34 | 35 | use std::thread::{spawn, yield_now};
|
35 | 36 |
|
36 | 37 | #[derive(Copy, Clone)]
|
@@ -196,6 +197,26 @@ fn test_mixed_access() {
|
196 | 197 | assert_eq!(r2, 2);
|
197 | 198 | }
|
198 | 199 |
|
| 200 | +// Strictly speaking, atomic accesses that imperfectly overlap with existing |
| 201 | +// atomic objects are UB. Nonetheless we'd like to provide a sane value when |
| 202 | +// the access is not racy. |
| 203 | +fn test_imperfectly_overlapping_access() { |
| 204 | + let mut qword = AtomicU32::new(42); |
| 205 | + assert_eq!(qword.load(Relaxed), 42); |
| 206 | + qword.store(u32::to_be(0xabbafafa), Relaxed); |
| 207 | + |
| 208 | + let qword_mut = qword.get_mut(); |
| 209 | + |
| 210 | + let dwords_mut = unsafe { std::mem::transmute::<&mut u32, &mut [u16; 2]>(qword_mut) }; |
| 211 | + |
| 212 | + let (hi_mut, lo_mut) = dwords_mut.split_at_mut(1); |
| 213 | + |
| 214 | + let (hi, lo) = (AtomicU16::from_mut(&mut hi_mut[0]), AtomicU16::from_mut(&mut lo_mut[0])); |
| 215 | + |
| 216 | + assert_eq!(u16::from_be(hi.load(Relaxed)), 0xabba); |
| 217 | + assert_eq!(u16::from_be(lo.load(Relaxed)), 0xfafa); |
| 218 | +} |
| 219 | + |
199 | 220 | // The following two tests are taken from Repairing Sequential Consistency in C/C++11
|
200 | 221 | // by Lahav et al.
|
201 | 222 | // https://plv.mpi-sws.org/scfix/paper.pdf
|
@@ -270,6 +291,7 @@ fn test_cpp20_rwc_syncs() {
|
270 | 291 | }
|
271 | 292 |
|
272 | 293 | pub fn main() {
|
| 294 | + test_imperfectly_overlapping_access(); |
273 | 295 | // TODO: does this make chances of spurious success
|
274 | 296 | // "sufficiently low"? This also takes a long time to run,
|
275 | 297 | // prehaps each function should be its own test case so they
|
|
0 commit comments