add miri_spin_loop to make hint::spin_loop work consistently
This commit is contained in:
parent
08de25c4ea
commit
c7dd19b8d6
3 changed files with 19 additions and 0 deletions
|
|
@ -269,6 +269,15 @@ pub const unsafe fn assert_unchecked(cond: bool) {
|
|||
#[stable(feature = "renamed_spin_loop", since = "1.49.0")]
|
||||
pub fn spin_loop() {
|
||||
crate::cfg_select! {
|
||||
miri => {
|
||||
unsafe extern "Rust" {
|
||||
safe fn miri_spin_loop();
|
||||
}
|
||||
|
||||
// Miri does support some of the intrinsics that are called below, but to guarantee
|
||||
// consistent behavior across targets, this custom function is used.
|
||||
miri_spin_loop();
|
||||
}
|
||||
target_arch = "x86" => {
|
||||
// SAFETY: the `cfg` attr ensures that we only execute this on x86 targets.
|
||||
crate::arch::x86::_mm_pause()
|
||||
|
|
|
|||
|
|
@ -435,6 +435,13 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Return value: 0 on success, otherwise the size it would have needed.
|
||||
this.write_int(if success { 0 } else { needed_size }, dest)?;
|
||||
}
|
||||
// Hint that a loop is spinning indefinitely.
|
||||
"miri_spin_loop" => {
|
||||
let [] = this.check_shim_sig_lenient(abi, CanonAbi::Rust, link_name, args)?;
|
||||
|
||||
// Try to run another thread to maximize the chance of finding actual bugs.
|
||||
this.yield_active_thread();
|
||||
}
|
||||
// Obtains the size of a Miri backtrace. See the README for details.
|
||||
"miri_backtrace_size" => {
|
||||
this.handle_miri_backtrace_size(abi, link_name, args, dest)?;
|
||||
|
|
|
|||
|
|
@ -155,4 +155,7 @@ extern "Rust" {
|
|||
|
||||
/// Blocks the current execution if the argument is false
|
||||
pub fn miri_genmc_assume(condition: bool);
|
||||
|
||||
/// Indicate to Miri that this thread is busy-waiting in a spin loop.
|
||||
pub fn miri_spin_loop();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue