mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-08-15 00:00:15 +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
|
||||
//! 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
|
||||
//! 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
|
||||
//! 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
|
||||
//! when" internally.
|
||||
//! list when the timer is being cancelled.
|
||||
//! This is referred to as the `registered_when` internally.
|
||||
//!
|
||||
//! There is of course a race condition between timer reset and timer
|
||||
//! 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.
|
||||
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
|
||||
/// 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
|
||||
/// 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 {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
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)
|
||||
.finish()
|
||||
}
|
||||
@@ -370,7 +379,7 @@ generate_addr_of_methods! {
|
||||
impl TimerShared {
|
||||
pub(super) fn new() -> Self {
|
||||
Self {
|
||||
cached_when: AtomicU64::new(0),
|
||||
registered_when: AtomicU64::new(0),
|
||||
pointers: linked_list::Pointers::new(),
|
||||
state: StateCell::default(),
|
||||
_p: PhantomPinned,
|
||||
@@ -378,9 +387,9 @@ impl TimerShared {
|
||||
}
|
||||
|
||||
/// 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
|
||||
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
|
||||
@@ -391,7 +400,7 @@ impl TimerShared {
|
||||
pub(super) unsafe fn sync_when(&self) -> u64 {
|
||||
let true_when = self.true_when();
|
||||
|
||||
self.cached_when.store(true_when, Ordering::Relaxed);
|
||||
self.registered_when.store(true_when, Ordering::Relaxed);
|
||||
|
||||
true_when
|
||||
}
|
||||
@@ -400,8 +409,8 @@ impl TimerShared {
|
||||
///
|
||||
/// SAFETY: Must be called with the driver lock held, and when this entry is
|
||||
/// not in any timer wheel lists.
|
||||
unsafe fn set_cached_when(&self, when: u64) {
|
||||
self.cached_when.store(when, Ordering::Relaxed);
|
||||
unsafe fn set_registered_when(&self, when: u64) {
|
||||
self.registered_when.store(when, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
/// Returns the true time-of-expiration value, with relaxed memory ordering.
|
||||
@@ -416,7 +425,7 @@ impl TimerShared {
|
||||
/// in the timer wheel.
|
||||
pub(super) unsafe fn set_expiration(&self, t: u64) {
|
||||
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.
|
||||
@@ -579,8 +588,8 @@ impl TimerEntry {
|
||||
}
|
||||
|
||||
impl TimerHandle {
|
||||
pub(super) unsafe fn cached_when(&self) -> u64 {
|
||||
unsafe { self.inner.as_ref().cached_when() }
|
||||
pub(super) unsafe fn registered_when(&self) -> u64 {
|
||||
unsafe { self.inner.as_ref().registered_when() }
|
||||
}
|
||||
|
||||
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
|
||||
/// `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.
|
||||
///
|
||||
/// 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> {
|
||||
match self.inner.as_ref().state.mark_pending(not_after) {
|
||||
Ok(()) => {
|
||||
// mark this as being on the pending queue in cached_when
|
||||
self.inner.as_ref().set_cached_when(STATE_DEREGISTERED);
|
||||
// mark this as being on the pending queue in registered_when
|
||||
self.inner.as_ref().set_registered_when(STATE_DEREGISTERED);
|
||||
Ok(())
|
||||
}
|
||||
Err(tick) => {
|
||||
self.inner.as_ref().set_cached_when(tick);
|
||||
self.inner.as_ref().set_registered_when(tick);
|
||||
Err(tick)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ impl Level {
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@@ -128,7 +128,7 @@ impl Level {
|
||||
}
|
||||
|
||||
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) };
|
||||
if self.slot[slot].is_empty() {
|
||||
|
||||
@@ -117,7 +117,7 @@ impl Wheel {
|
||||
/// Removes `item` from the timing wheel.
|
||||
pub(crate) unsafe fn remove(&mut self, item: NonNull<TimerShared>) {
|
||||
unsafe {
|
||||
let when = item.as_ref().cached_when();
|
||||
let when = item.as_ref().registered_when();
|
||||
if when == STATE_DEREGISTERED {
|
||||
self.pending.remove(item);
|
||||
} else {
|
||||
@@ -231,11 +231,11 @@ impl Wheel {
|
||||
|
||||
while let Some(item) = entries.pop_back() {
|
||||
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
|
||||
// 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) } {
|
||||
Ok(()) => {
|
||||
// Item was expired
|
||||
|
||||
Reference in New Issue
Block a user