Skip to content

Commit 763782a

Browse files
committed
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.
2 parents 4155fb6 + 547a4cc commit 763782a

File tree

4 files changed

+23
-1
lines changed

4 files changed

+23
-1
lines changed

src/shims/foreign_items.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
433433
this.write_scalar(Scalar::from_f64(res), dest)?;
434434
}
435435

436-
// Target-specific shims
436+
// Architecture-specific shims
437+
"llvm.x86.sse2.pause" if this.tcx.sess.target.target.arch == "x86" || this.tcx.sess.target.target.arch == "x86_64" => {}
438+
439+
// Platform-specific shims
437440
_ => match this.tcx.sess.target.target.target_os.as_str() {
438441
"linux" | "macos" => return posix::EvalContextExt::emulate_foreign_item_by_name(this, link_name, args, dest, ret),
439442
"windows" => return windows::EvalContextExt::emulate_foreign_item_by_name(this, link_name, args, dest, ret),

src/shims/foreign_items/posix.rs

+3
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
312312
// We do not support forking, so there is nothing to do here.
313313
this.write_null(dest)?;
314314
}
315+
"sched_yield" => {
316+
this.write_null(dest)?;
317+
}
315318

316319
// Incomplete shims that we "stub out" just to get pre-main initialization code to work.
317320
// These shims are enabled only when the caller is in the standard library.

src/shims/foreign_items/windows.rs

+5
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
201201
// FIXME: we should set last_error, but to what?
202202
this.write_null(dest)?;
203203
}
204+
"SwitchToThread" => {
205+
// Note that once Miri supports concurrency, this will need to return a nonzero
206+
// value if this call does result in switching to another thread.
207+
this.write_null(dest)?;
208+
}
204209

205210
// Better error for attempts to create a thread
206211
"CreateThread" => {

tests/run-pass/sync.rs

+11
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
#![feature(rustc_private)]
22

33
use std::sync::{Mutex, TryLockError};
4+
use std::sync::atomic;
45

56
fn main() {
67
test_mutex_stdlib();
78
#[cfg(not(target_os = "windows"))] // TODO: implement RwLock on Windows
89
{
910
test_rwlock_stdlib();
1011
}
12+
test_spin_loop_hint();
13+
test_thread_yield_now();
1114
}
1215

1316
fn test_mutex_stdlib() {
@@ -50,3 +53,11 @@ impl<T> TryLockErrorExt<T> for TryLockError<T> {
5053
}
5154
}
5255
}
56+
57+
fn test_spin_loop_hint() {
58+
atomic::spin_loop_hint();
59+
}
60+
61+
fn test_thread_yield_now() {
62+
std::thread::yield_now();
63+
}

0 commit comments

Comments
 (0)