mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-08-17 00:00:11 +02:00
sync: add spin_loop_hint to atomic waker (#1608)
The algorithm backing `AtomicWaker` effectively uses a spin lock backed by notifying & yielding the current task. This adds a `spin_lock_hint` annotation to cover this case. While, in practice, the omission of `spin_lock_hint` would not cause problems, there are platforms that do not handle spin locks very well and could enter a deadlock in pathological cases.
This commit is contained in:
committed by
Jon Gjengset
parent
b71b7b36be
commit
032b39487c
@@ -1,4 +1,5 @@
|
||||
use crate::loom::{sync::atomic::AtomicUsize, sync::CausalCell};
|
||||
use crate::loom::sync::atomic::{self, AtomicUsize};
|
||||
use crate::loom::sync::CausalCell;
|
||||
|
||||
use std::fmt;
|
||||
use std::sync::atomic::Ordering::{AcqRel, Acquire, Release};
|
||||
@@ -171,6 +172,7 @@ impl AtomicWaker {
|
||||
debug!(" + register_task");
|
||||
match self.state.compare_and_swap(WAITING, REGISTERING, Acquire) {
|
||||
WAITING => {
|
||||
debug!(" + WAITING");
|
||||
unsafe {
|
||||
// Locked acquired, update the waker cell
|
||||
self.waker.with_mut(|t| *t = Some(waker.into_waker()));
|
||||
@@ -211,10 +213,14 @@ impl AtomicWaker {
|
||||
}
|
||||
}
|
||||
WAKING => {
|
||||
debug!(" + WAKING");
|
||||
// Currently in the process of waking the task, i.e.,
|
||||
// `wake` is currently being called on the old waker.
|
||||
// So, we call wake on the new waker.
|
||||
waker.wake();
|
||||
|
||||
// This is equivalent to a spin lock, so use a spin hint.
|
||||
atomic::spin_loop_hint();
|
||||
}
|
||||
state => {
|
||||
// In this case, a concurrent thread is holding the
|
||||
|
||||
Reference in New Issue
Block a user