Auto merge of #1342 - divergentdave:pause-instruction, r=RalfJung
Handle std::sync::atomic::spin_loop_hint() This PR adds support for `std::sync::atomic::spin_loop_hint()` by implementing the `llvm.x86.sse2.pause` intrinsic when the target is x86-based. It appears this is the first LLVM intrinsic in foreign_items, so I added a couple match blocks to handle it or fall through to the different OS-specific methods. I added a basic smoke test to `tests/run-pass/sync.rs`. I came across this by way of `crossbeam::utils::Backoff::spin()`, FWIW.
This commit is contained in:
commit
763782aa08
@ -433,7 +433,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
this.write_scalar(Scalar::from_f64(res), dest)?;
|
||||
}
|
||||
|
||||
// Target-specific shims
|
||||
// Architecture-specific shims
|
||||
"llvm.x86.sse2.pause" if this.tcx.sess.target.target.arch == "x86" || this.tcx.sess.target.target.arch == "x86_64" => {}
|
||||
|
||||
// Platform-specific shims
|
||||
_ => match this.tcx.sess.target.target.target_os.as_str() {
|
||||
"linux" | "macos" => return posix::EvalContextExt::emulate_foreign_item_by_name(this, link_name, args, dest, ret),
|
||||
"windows" => return windows::EvalContextExt::emulate_foreign_item_by_name(this, link_name, args, dest, ret),
|
||||
|
@ -312,6 +312,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
// We do not support forking, so there is nothing to do here.
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
"sched_yield" => {
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
|
||||
// Incomplete shims that we "stub out" just to get pre-main initialization code to work.
|
||||
// These shims are enabled only when the caller is in the standard library.
|
||||
|
@ -201,6 +201,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
// FIXME: we should set last_error, but to what?
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
"SwitchToThread" => {
|
||||
// Note that once Miri supports concurrency, this will need to return a nonzero
|
||||
// value if this call does result in switching to another thread.
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
|
||||
// Better error for attempts to create a thread
|
||||
"CreateThread" => {
|
||||
|
@ -1,6 +1,7 @@
|
||||
#![feature(rustc_private)]
|
||||
|
||||
use std::sync::{Mutex, TryLockError};
|
||||
use std::sync::atomic;
|
||||
|
||||
fn main() {
|
||||
test_mutex_stdlib();
|
||||
@ -8,6 +9,8 @@ fn main() {
|
||||
{
|
||||
test_rwlock_stdlib();
|
||||
}
|
||||
test_spin_loop_hint();
|
||||
test_thread_yield_now();
|
||||
}
|
||||
|
||||
fn test_mutex_stdlib() {
|
||||
@ -50,3 +53,11 @@ impl<T> TryLockErrorExt<T> for TryLockError<T> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn test_spin_loop_hint() {
|
||||
atomic::spin_loop_hint();
|
||||
}
|
||||
|
||||
fn test_thread_yield_now() {
|
||||
std::thread::yield_now();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user