Skip to content

Commit

Permalink
Auto merge of #41207 - sstewartgallus:spinpause, r=alexcrichton
Browse files Browse the repository at this point in the history
Spin loop pause function redux

GitHub's interface is screwy.

This is the same PR as #40537
  • Loading branch information
bors committed May 2, 2017
2 parents ed1f26d + f4fe3cd commit 6a5fc9e
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/doc/unstable-book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@
- [future_atomic_orderings](library-features/future-atomic-orderings.md)
- [get_type_id](library-features/get-type-id.md)
- [heap_api](library-features/heap-api.md)
- [hint_core_should_pause](library-features/hint-core-should-pause.md)
- [i128](library-features/i128.md)
- [inclusive_range](library-features/inclusive-range.md)
- [integer_atomics](library-features/integer-atomics.md)
Expand Down
Original file line number Diff line number Diff line change
@@ -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`.
23 changes: 23 additions & 0 deletions src/libcore/sync/atomic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,29 @@ use intrinsics;
use cell::UnsafeCell;
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.
///
/// This type has the same in-memory representation as a `bool`.
Expand Down

0 comments on commit 6a5fc9e

Please sign in to comment.