mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-13 20:46:48 +00:00
Auto merge of #41207 - sstewartgallus:spinpause, r=alexcrichton
Spin loop pause function redux GitHub's interface is screwy. This is the same PR as https://github.com/rust-lang/rust/pull/40537
This commit is contained in:
commit
6a5fc9eece
@ -145,6 +145,7 @@
|
|||||||
- [future_atomic_orderings](library-features/future-atomic-orderings.md)
|
- [future_atomic_orderings](library-features/future-atomic-orderings.md)
|
||||||
- [get_type_id](library-features/get-type-id.md)
|
- [get_type_id](library-features/get-type-id.md)
|
||||||
- [heap_api](library-features/heap-api.md)
|
- [heap_api](library-features/heap-api.md)
|
||||||
|
- [hint_core_should_pause](library-features/hint-core-should-pause.md)
|
||||||
- [i128](library-features/i128.md)
|
- [i128](library-features/i128.md)
|
||||||
- [inclusive_range](library-features/inclusive-range.md)
|
- [inclusive_range](library-features/inclusive-range.md)
|
||||||
- [integer_atomics](library-features/integer-atomics.md)
|
- [integer_atomics](library-features/integer-atomics.md)
|
||||||
|
@ -0,0 +1,41 @@
|
|||||||
|
# `hint_core_should_pause`
|
||||||
|
|
||||||
|
The tracking issue for this feature is: [#41196]
|
||||||
|
|
||||||
|
[#41196]: https://github.com/rust-lang/rust/issues/41196
|
||||||
|
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
Many programs have spin loops like the following:
|
||||||
|
|
||||||
|
```rust,no_run
|
||||||
|
use std::sync::atomic::{AtomicBool,Ordering};
|
||||||
|
|
||||||
|
fn spin_loop(value: &AtomicBool) {
|
||||||
|
loop {
|
||||||
|
if value.load(Ordering::Acquire) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
These programs can be improved in performance like so:
|
||||||
|
|
||||||
|
```rust,no_run
|
||||||
|
#![feature(hint_core_should_pause)]
|
||||||
|
use std::sync::atomic;
|
||||||
|
use std::sync::atomic::{AtomicBool,Ordering};
|
||||||
|
|
||||||
|
fn spin_loop(value: &AtomicBool) {
|
||||||
|
loop {
|
||||||
|
if value.load(Ordering::Acquire) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
atomic::hint_core_should_pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Further improvements could combine `hint_core_should_pause` with
|
||||||
|
exponential backoff or `std::thread::yield_now`.
|
@ -94,6 +94,29 @@ use intrinsics;
|
|||||||
use cell::UnsafeCell;
|
use cell::UnsafeCell;
|
||||||
use fmt;
|
use fmt;
|
||||||
|
|
||||||
|
/// Save power or switch hyperthreads in a busy-wait spin-loop.
|
||||||
|
///
|
||||||
|
/// This function is deliberately more primitive than
|
||||||
|
/// `std::thread::yield_now` and does not directly yield to the
|
||||||
|
/// system's scheduler. In some cases it might be useful to use a
|
||||||
|
/// combination of both functions. Careful benchmarking is advised.
|
||||||
|
///
|
||||||
|
/// On some platforms this function may not do anything at all.
|
||||||
|
#[inline]
|
||||||
|
#[unstable(feature = "hint_core_should_pause", issue = "41196")]
|
||||||
|
pub fn hint_core_should_pause()
|
||||||
|
{
|
||||||
|
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||||
|
unsafe {
|
||||||
|
asm!("pause" ::: "memory" : "volatile");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
unsafe {
|
||||||
|
asm!("yield" ::: "memory" : "volatile");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A boolean type which can be safely shared between threads.
|
/// A boolean type which can be safely shared between threads.
|
||||||
///
|
///
|
||||||
/// This type has the same in-memory representation as a `bool`.
|
/// This type has the same in-memory representation as a `bool`.
|
||||||
|
Loading…
Reference in New Issue
Block a user