Merge pull request #4469 from Patrick-6/add-spinloop-hints

Add std::hint::spin_loop() to tests
This commit is contained in:
Ralf Jung 2025-07-15 14:28:27 +00:00 committed by GitHub
commit 62aea72e36
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 31 additions and 15 deletions

View File

@ -41,7 +41,15 @@ fn static_atomic_bool(val: bool) -> &'static AtomicBool {
}
/// Spins until it acquires a pre-determined value.
fn loads_value(loc: &AtomicI32, ord: Ordering, val: i32) -> i32 {
fn spin_until_i32(loc: &AtomicI32, ord: Ordering, val: i32) -> i32 {
while loc.load(ord) != val {
std::hint::spin_loop();
}
val
}
/// Spins until it acquires a pre-determined boolean.
fn spin_until_bool(loc: &AtomicBool, ord: Ordering, val: bool) -> bool {
while loc.load(ord) != val {
std::hint::spin_loop();
}
@ -65,7 +73,7 @@ fn test_corr() {
}); // | |
#[rustfmt::skip] // |synchronizes-with |happens-before
let j3 = spawn(move || { // | |
loads_value(&y, Acquire, 1); // <------------+ |
spin_until_i32(&y, Acquire, 1); // <---------+ |
x.load(Relaxed) // <----------------------------------------------+
// The two reads on x are ordered by hb, so they cannot observe values
// differently from the modification order. If the first read observed
@ -90,12 +98,12 @@ fn test_wrc() {
}); // | |
#[rustfmt::skip] // |synchronizes-with |
let j2 = spawn(move || { // | |
loads_value(&x, Acquire, 1); // <------------+ |
spin_until_i32(&x, Acquire, 1); // <---------+ |
y.store(1, Release); // ---------------------+ |happens-before
}); // | |
#[rustfmt::skip] // |synchronizes-with |
let j3 = spawn(move || { // | |
loads_value(&y, Acquire, 1); // <------------+ |
spin_until_i32(&y, Acquire, 1); // <---------+ |
x.load(Relaxed) // <-----------------------------------------------+
});
@ -121,7 +129,7 @@ fn test_message_passing() {
#[rustfmt::skip] // |synchronizes-with | happens-before
let j2 = spawn(move || { // | |
let x = x; // avoid field capturing | |
loads_value(&y, Acquire, 1); // <------------+ |
spin_until_i32(&y, Acquire, 1); // <---------+ |
unsafe { *x.0 } // <---------------------------------------------+
});
@ -216,12 +224,12 @@ fn test_sync_through_rmw_and_fences() {
let go = static_atomic_bool(false);
let t1 = spawn(move || {
while !go.load(Relaxed) {}
spin_until_bool(go, Relaxed, true);
rdmw(y, x, z)
});
let t2 = spawn(move || {
while !go.load(Relaxed) {}
spin_until_bool(go, Relaxed, true);
rdmw(z, x, y)
});

View File

@ -20,7 +20,15 @@ fn static_atomic_bool(val: bool) -> &'static AtomicBool {
}
/// Spins until it acquires a pre-determined value.
fn loads_value(loc: &AtomicI32, ord: Ordering, val: i32) -> i32 {
fn spin_until_i32(loc: &AtomicI32, ord: Ordering, val: i32) -> i32 {
while loc.load(ord) != val {
std::hint::spin_loop();
}
val
}
/// Spins until it acquires a pre-determined boolean.
fn spin_until_bool(loc: &AtomicBool, ord: Ordering, val: bool) -> bool {
while loc.load(ord) != val {
std::hint::spin_loop();
}
@ -60,11 +68,11 @@ fn test_iriw_sc_rlx() {
let a = spawn(move || x.store(true, Relaxed));
let b = spawn(move || y.store(true, Relaxed));
let c = spawn(move || {
while !x.load(SeqCst) {}
spin_until_bool(x, SeqCst, true);
y.load(SeqCst)
});
let d = spawn(move || {
while !y.load(SeqCst) {}
spin_until_bool(y, SeqCst, true);
x.load(SeqCst)
});
@ -136,7 +144,7 @@ fn test_cpp20_rwc_syncs() {
});
let j2 = spawn(move || {
loads_value(&x, Relaxed, 1);
spin_until_i32(&x, Relaxed, 1);
fence(SeqCst);
y.load(Relaxed)
});

View File

@ -24,7 +24,7 @@ fn static_atomic(val: usize) -> &'static AtomicUsize {
}
// Spins until it reads the given value
fn reads_value(loc: &AtomicUsize, val: usize) -> usize {
fn spin_until(loc: &AtomicUsize, val: usize) -> usize {
while loc.load(Relaxed) != val {
std::hint::spin_loop();
}
@ -85,7 +85,7 @@ fn initialization_write(add_fence: bool) -> bool {
});
let j2 = spawn(move || {
reads_value(wait, 1);
spin_until(wait, 1);
if add_fence {
fence(AcqRel);
}
@ -119,12 +119,12 @@ fn faa_replaced_by_load() -> bool {
let go = static_atomic(0);
let t1 = spawn(move || {
while go.load(Relaxed) == 0 {}
spin_until(go, 1);
rdmw(y, x, z)
});
let t2 = spawn(move || {
while go.load(Relaxed) == 0 {}
spin_until(go, 1);
rdmw(z, x, y)
});