mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-08-27 00:00:12 +02:00
time: rename cached_when to registered_when (#7333)
This commit is contained in:
@@ -28,7 +28,7 @@
|
|||||||
//! This single state field allows for code that is firing the timer to
|
//! This single state field allows for code that is firing the timer to
|
||||||
//! synchronize with any racing `reset` calls reliably.
|
//! synchronize with any racing `reset` calls reliably.
|
||||||
//!
|
//!
|
||||||
//! # Cached vs true timeouts
|
//! # Registered vs true timeouts
|
||||||
//!
|
//!
|
||||||
//! To allow for the use case of a timeout that is periodically reset before
|
//! To allow for the use case of a timeout that is periodically reset before
|
||||||
//! expiration to be as lightweight as possible, we support optimistically
|
//! expiration to be as lightweight as possible, we support optimistically
|
||||||
@@ -43,8 +43,8 @@
|
|||||||
//!
|
//!
|
||||||
//! We do, however, also need to track what the expiration time was when we
|
//! We do, however, also need to track what the expiration time was when we
|
||||||
//! originally registered the timer; this is used to locate the right linked
|
//! originally registered the timer; this is used to locate the right linked
|
||||||
//! list when the timer is being cancelled. This is referred to as the "cached
|
//! list when the timer is being cancelled.
|
||||||
//! when" internally.
|
//! This is referred to as the `registered_when` internally.
|
||||||
//!
|
//!
|
||||||
//! There is of course a race condition between timer reset and timer
|
//! There is of course a race condition between timer reset and timer
|
||||||
//! expiration. If the driver fails to observe the updated expiration time, it
|
//! expiration. If the driver fails to observe the updated expiration time, it
|
||||||
@@ -334,10 +334,16 @@ pub(crate) struct TimerShared {
|
|||||||
/// Only accessed under the entry lock.
|
/// Only accessed under the entry lock.
|
||||||
pointers: linked_list::Pointers<TimerShared>,
|
pointers: linked_list::Pointers<TimerShared>,
|
||||||
|
|
||||||
/// The expiration time for which this entry is currently registered.
|
/// The time when the [`TimerEntry`] was registered into the Wheel,
|
||||||
|
/// [`STATE_DEREGISTERED`] means it is not registered.
|
||||||
|
///
|
||||||
/// Generally owned by the driver, but is accessed by the entry when not
|
/// Generally owned by the driver, but is accessed by the entry when not
|
||||||
/// registered.
|
/// registered.
|
||||||
cached_when: AtomicU64,
|
///
|
||||||
|
/// We use relaxed ordering for both loading and storing since this value
|
||||||
|
/// is only accessed either when holding the driver lock or through mutable
|
||||||
|
/// references to [`TimerEntry`].
|
||||||
|
registered_when: AtomicU64,
|
||||||
|
|
||||||
/// Current state. This records whether the timer entry is currently under
|
/// Current state. This records whether the timer entry is currently under
|
||||||
/// the ownership of the driver, and if not, its current state (not
|
/// the ownership of the driver, and if not, its current state (not
|
||||||
@@ -353,7 +359,10 @@ unsafe impl Sync for TimerShared {}
|
|||||||
impl std::fmt::Debug for TimerShared {
|
impl std::fmt::Debug for TimerShared {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
f.debug_struct("TimerShared")
|
f.debug_struct("TimerShared")
|
||||||
.field("cached_when", &self.cached_when.load(Ordering::Relaxed))
|
.field(
|
||||||
|
"registered_when",
|
||||||
|
&self.registered_when.load(Ordering::Relaxed),
|
||||||
|
)
|
||||||
.field("state", &self.state)
|
.field("state", &self.state)
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
@@ -370,7 +379,7 @@ generate_addr_of_methods! {
|
|||||||
impl TimerShared {
|
impl TimerShared {
|
||||||
pub(super) fn new() -> Self {
|
pub(super) fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
cached_when: AtomicU64::new(0),
|
registered_when: AtomicU64::new(0),
|
||||||
pointers: linked_list::Pointers::new(),
|
pointers: linked_list::Pointers::new(),
|
||||||
state: StateCell::default(),
|
state: StateCell::default(),
|
||||||
_p: PhantomPinned,
|
_p: PhantomPinned,
|
||||||
@@ -378,9 +387,9 @@ impl TimerShared {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the cached time-of-expiration value.
|
/// Gets the cached time-of-expiration value.
|
||||||
pub(super) fn cached_when(&self) -> u64 {
|
pub(super) fn registered_when(&self) -> u64 {
|
||||||
// Cached-when is only accessed under the driver lock, so we can use relaxed
|
// Cached-when is only accessed under the driver lock, so we can use relaxed
|
||||||
self.cached_when.load(Ordering::Relaxed)
|
self.registered_when.load(Ordering::Relaxed)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the true time-of-expiration value, and copies it into the cached
|
/// Gets the true time-of-expiration value, and copies it into the cached
|
||||||
@@ -391,7 +400,7 @@ impl TimerShared {
|
|||||||
pub(super) unsafe fn sync_when(&self) -> u64 {
|
pub(super) unsafe fn sync_when(&self) -> u64 {
|
||||||
let true_when = self.true_when();
|
let true_when = self.true_when();
|
||||||
|
|
||||||
self.cached_when.store(true_when, Ordering::Relaxed);
|
self.registered_when.store(true_when, Ordering::Relaxed);
|
||||||
|
|
||||||
true_when
|
true_when
|
||||||
}
|
}
|
||||||
@@ -400,8 +409,8 @@ impl TimerShared {
|
|||||||
///
|
///
|
||||||
/// SAFETY: Must be called with the driver lock held, and when this entry is
|
/// SAFETY: Must be called with the driver lock held, and when this entry is
|
||||||
/// not in any timer wheel lists.
|
/// not in any timer wheel lists.
|
||||||
unsafe fn set_cached_when(&self, when: u64) {
|
unsafe fn set_registered_when(&self, when: u64) {
|
||||||
self.cached_when.store(when, Ordering::Relaxed);
|
self.registered_when.store(when, Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the true time-of-expiration value, with relaxed memory ordering.
|
/// Returns the true time-of-expiration value, with relaxed memory ordering.
|
||||||
@@ -416,7 +425,7 @@ impl TimerShared {
|
|||||||
/// in the timer wheel.
|
/// in the timer wheel.
|
||||||
pub(super) unsafe fn set_expiration(&self, t: u64) {
|
pub(super) unsafe fn set_expiration(&self, t: u64) {
|
||||||
self.state.set_expiration(t);
|
self.state.set_expiration(t);
|
||||||
self.cached_when.store(t, Ordering::Relaxed);
|
self.registered_when.store(t, Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the true time-of-expiration only if it is after the current.
|
/// Sets the true time-of-expiration only if it is after the current.
|
||||||
@@ -579,8 +588,8 @@ impl TimerEntry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl TimerHandle {
|
impl TimerHandle {
|
||||||
pub(super) unsafe fn cached_when(&self) -> u64 {
|
pub(super) unsafe fn registered_when(&self) -> u64 {
|
||||||
unsafe { self.inner.as_ref().cached_when() }
|
unsafe { self.inner.as_ref().registered_when() }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) unsafe fn sync_when(&self) -> u64 {
|
pub(super) unsafe fn sync_when(&self) -> u64 {
|
||||||
@@ -602,7 +611,7 @@ impl TimerHandle {
|
|||||||
/// Attempts to mark this entry as pending. If the expiration time is after
|
/// Attempts to mark this entry as pending. If the expiration time is after
|
||||||
/// `not_after`, however, returns an Err with the current expiration time.
|
/// `not_after`, however, returns an Err with the current expiration time.
|
||||||
///
|
///
|
||||||
/// If an `Err` is returned, the `cached_when` value will be updated to this
|
/// If an `Err` is returned, the `registered_when` value will be updated to this
|
||||||
/// new expiration time.
|
/// new expiration time.
|
||||||
///
|
///
|
||||||
/// SAFETY: The caller must ensure that the handle remains valid, the driver
|
/// SAFETY: The caller must ensure that the handle remains valid, the driver
|
||||||
@@ -611,12 +620,12 @@ impl TimerHandle {
|
|||||||
pub(super) unsafe fn mark_pending(&self, not_after: u64) -> Result<(), u64> {
|
pub(super) unsafe fn mark_pending(&self, not_after: u64) -> Result<(), u64> {
|
||||||
match self.inner.as_ref().state.mark_pending(not_after) {
|
match self.inner.as_ref().state.mark_pending(not_after) {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
// mark this as being on the pending queue in cached_when
|
// mark this as being on the pending queue in registered_when
|
||||||
self.inner.as_ref().set_cached_when(STATE_DEREGISTERED);
|
self.inner.as_ref().set_registered_when(STATE_DEREGISTERED);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Err(tick) => {
|
Err(tick) => {
|
||||||
self.inner.as_ref().set_cached_when(tick);
|
self.inner.as_ref().set_registered_when(tick);
|
||||||
Err(tick)
|
Err(tick)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ impl Level {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) unsafe fn add_entry(&mut self, item: TimerHandle) {
|
pub(crate) unsafe fn add_entry(&mut self, item: TimerHandle) {
|
||||||
let slot = slot_for(item.cached_when(), self.level);
|
let slot = slot_for(item.registered_when(), self.level);
|
||||||
|
|
||||||
self.slot[slot].push_front(item);
|
self.slot[slot].push_front(item);
|
||||||
|
|
||||||
@@ -128,7 +128,7 @@ impl Level {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) unsafe fn remove_entry(&mut self, item: NonNull<TimerShared>) {
|
pub(crate) unsafe fn remove_entry(&mut self, item: NonNull<TimerShared>) {
|
||||||
let slot = slot_for(unsafe { item.as_ref().cached_when() }, self.level);
|
let slot = slot_for(unsafe { item.as_ref().registered_when() }, self.level);
|
||||||
|
|
||||||
unsafe { self.slot[slot].remove(item) };
|
unsafe { self.slot[slot].remove(item) };
|
||||||
if self.slot[slot].is_empty() {
|
if self.slot[slot].is_empty() {
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ impl Wheel {
|
|||||||
/// Removes `item` from the timing wheel.
|
/// Removes `item` from the timing wheel.
|
||||||
pub(crate) unsafe fn remove(&mut self, item: NonNull<TimerShared>) {
|
pub(crate) unsafe fn remove(&mut self, item: NonNull<TimerShared>) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let when = item.as_ref().cached_when();
|
let when = item.as_ref().registered_when();
|
||||||
if when == STATE_DEREGISTERED {
|
if when == STATE_DEREGISTERED {
|
||||||
self.pending.remove(item);
|
self.pending.remove(item);
|
||||||
} else {
|
} else {
|
||||||
@@ -231,11 +231,11 @@ impl Wheel {
|
|||||||
|
|
||||||
while let Some(item) = entries.pop_back() {
|
while let Some(item) = entries.pop_back() {
|
||||||
if expiration.level == 0 {
|
if expiration.level == 0 {
|
||||||
debug_assert_eq!(unsafe { item.cached_when() }, expiration.deadline);
|
debug_assert_eq!(unsafe { item.registered_when() }, expiration.deadline);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to expire the entry; this is cheap (doesn't synchronize) if
|
// Try to expire the entry; this is cheap (doesn't synchronize) if
|
||||||
// the timer is not expired, and updates cached_when.
|
// the timer is not expired, and updates registered_when.
|
||||||
match unsafe { item.mark_pending(expiration.deadline) } {
|
match unsafe { item.mark_pending(expiration.deadline) } {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
// Item was expired
|
// Item was expired
|
||||||
|
|||||||
Reference in New Issue
Block a user