-
Notifications
You must be signed in to change notification settings - Fork 347
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature request: make std::thread::yield_now()
work
#3538
Comments
|
Huh, any idea why fn no_race_with_is_abandoned() {
static mut V: u32 = 0;
let (p, c) = RingBuffer::<u8>::new(7);
let t = std::thread::spawn(move || {
unsafe { V = 10 };
drop(p);
});
std::thread::yield_now();
if c.is_abandoned() {
unsafe { V = 20 };
} else {
panic!("no");
// This is not synchronized, both Miri and ThreadSanitizer should detect a data race:
//unsafe { V = 30 };
}
t.join().unwrap();
} Interestingly, 3 yields in a loop triggers UB:
But if I write them out manually 3 times it doesn't work and I have to write 6 of them. |
|
Are you sure the UB just needs the right schedule? There is other non-determinism, like the weak memory emulation. You might be just probing various random executions here. Try running Miri with different seeds and just a single |
Also, that code references the undefined symbol |
Nice! A seed of 1 worked lol. Here's a self contained repro for reference: fn no_race_with_is_abandoned() {
static mut V: u32 = 0;
let arc = std::sync::Arc::new(());
let arc2 = arc.clone();
let t = std::thread::spawn(move || {
unsafe { V = 10 };
drop(arc2);
});
std::thread::yield_now();
if std::sync::Arc::strong_count(&arc) == 1 {
unsafe { V = 20 };
} else {
panic!("no");
// This is not synchronized, both Miri and ThreadSanitizer should detect a data race:
//unsafe { V = 30 };
}
t.join().unwrap();
} I still don't understand where that extra non-determinism is coming from. Here's a really neat feature idea: would it be possible to log every non-determinism choice made? Then I could hopefully get a sense of the paths being explored by which seeds. |
I think you'd drown in output.^^ There's at least one non-deterministic choice made for each local variable that gets allocated (to pick its absolute address). That's a lot. You can use Also, sometimes cross-thread address reuse leads to unintended synchronization, so you can use |
Ohhhhh, ok well fun idea in theory but probably not so useful in reality. :)
TIL! That's neat. And it was the culprit!
So basically miri made Fun stuff! Thanks for helping me get to the bottom of it. |
Over in rust-lang/rust#117485, it'd be nice to be able to force pre-emption, but I can't seem to get miri to consistently preempt. It'd be nice if
std::thread::yield_now()
forced a miri thread preemption.The text was updated successfully, but these errors were encountered: