2022-06-06 16:44:16 -05:00
|
|
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
2022-06-20 17:30:34 -05:00
|
|
|
use std::thread;
|
2022-06-06 16:44:16 -05:00
|
|
|
|
|
|
|
static FLAG: AtomicUsize = AtomicUsize::new(0);
|
|
|
|
|
|
|
|
fn spin() {
|
|
|
|
let j = thread::spawn(|| {
|
|
|
|
while FLAG.load(Ordering::Acquire) == 0 {
|
|
|
|
// We do *not* yield, and yet this should terminate eventually.
|
|
|
|
}
|
|
|
|
});
|
|
|
|
thread::yield_now(); // schedule the other thread
|
|
|
|
FLAG.store(1, Ordering::Release);
|
|
|
|
j.join().unwrap();
|
|
|
|
}
|
|
|
|
|
|
|
|
fn two_player_ping_pong() {
|
|
|
|
static FLAG: AtomicUsize = AtomicUsize::new(0);
|
|
|
|
|
|
|
|
let waiter1 = thread::spawn(|| {
|
|
|
|
while FLAG.load(Ordering::Acquire) == 0 {
|
|
|
|
// We do *not* yield, and yet this should terminate eventually.
|
|
|
|
}
|
|
|
|
});
|
|
|
|
let waiter2 = thread::spawn(|| {
|
|
|
|
while FLAG.load(Ordering::Acquire) == 0 {
|
|
|
|
// We do *not* yield, and yet this should terminate eventually.
|
|
|
|
}
|
|
|
|
});
|
|
|
|
let progress = thread::spawn(|| {
|
|
|
|
FLAG.store(1, Ordering::Release);
|
|
|
|
});
|
|
|
|
// The first `join` blocks the main thread and thus takes it out of the equation.
|
|
|
|
waiter1.join().unwrap();
|
|
|
|
waiter2.join().unwrap();
|
|
|
|
progress.join().unwrap();
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
spin();
|
|
|
|
two_player_ping_pong();
|
|
|
|
}
|