mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-08-30 00:00:16 +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::fmt;
|
||||||
use std::sync::atomic::Ordering::{AcqRel, Acquire, Release};
|
use std::sync::atomic::Ordering::{AcqRel, Acquire, Release};
|
||||||
@@ -171,6 +172,7 @@ impl AtomicWaker {
|
|||||||
debug!(" + register_task");
|
debug!(" + register_task");
|
||||||
match self.state.compare_and_swap(WAITING, REGISTERING, Acquire) {
|
match self.state.compare_and_swap(WAITING, REGISTERING, Acquire) {
|
||||||
WAITING => {
|
WAITING => {
|
||||||
|
debug!(" + WAITING");
|
||||||
unsafe {
|
unsafe {
|
||||||
// Locked acquired, update the waker cell
|
// Locked acquired, update the waker cell
|
||||||
self.waker.with_mut(|t| *t = Some(waker.into_waker()));
|
self.waker.with_mut(|t| *t = Some(waker.into_waker()));
|
||||||
@@ -211,10 +213,14 @@ impl AtomicWaker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
WAKING => {
|
WAKING => {
|
||||||
|
debug!(" + WAKING");
|
||||||
// Currently in the process of waking the task, i.e.,
|
// Currently in the process of waking the task, i.e.,
|
||||||
// `wake` is currently being called on the old waker.
|
// `wake` is currently being called on the old waker.
|
||||||
// So, we call wake on the new waker.
|
// So, we call wake on the new waker.
|
||||||
waker.wake();
|
waker.wake();
|
||||||
|
|
||||||
|
// This is equivalent to a spin lock, so use a spin hint.
|
||||||
|
atomic::spin_loop_hint();
|
||||||
}
|
}
|
||||||
state => {
|
state => {
|
||||||
// In this case, a concurrent thread is holding the
|
// In this case, a concurrent thread is holding the
|
||||||
|
|||||||
Reference in New Issue
Block a user