time: improve the readability of alternative timer (#7801)

This commit is contained in:
Tim Vilgot Mikael Fredenberg
2025-12-28 19:01:05 +08:00
committed by GitHub
parent d666068be7
commit 0a3e386269
3 changed files with 30 additions and 57 deletions
+3 -5
View File
@@ -139,11 +139,9 @@ pub(crate) fn shutdown_local_timers(
let mut wake_queue = WakeQueue::new();
// simply wake all unregistered timers
for hdl in inject {
if !hdl.is_cancelled() {
unsafe {
wake_queue.push_front(hdl);
}
for hdl in inject.into_iter().filter(|hdl| !hdl.is_cancelled()) {
unsafe {
wake_queue.push_front(hdl);
}
}
@@ -4,7 +4,7 @@ use crate::util::linked_list;
type EntryList = linked_list::LinkedList<CancellationQueueEntry, Entry>;
#[derive(Debug)]
#[derive(Debug, Default)]
struct Inner {
list: EntryList,
}
@@ -12,7 +12,9 @@ struct Inner {
impl Drop for Inner {
fn drop(&mut self) {
// consume all entries
let _ = self.iter().count();
while let Some(hdl) = self.list.pop_front() {
drop(hdl)
}
}
}
@@ -32,30 +34,18 @@ impl Inner {
self.list.push_front(hdl);
}
fn iter(&mut self) -> impl Iterator<Item = EntryHandle> {
struct Iter {
list: EntryList,
}
impl Drop for Iter {
fn drop(&mut self) {
while let Some(hdl) = self.list.pop_front() {
drop(hdl);
}
}
}
fn into_iter(self) -> impl Iterator<Item = EntryHandle> {
struct Iter(Inner);
impl Iterator for Iter {
type Item = EntryHandle;
fn next(&mut self) -> Option<Self::Item> {
self.list.pop_front()
self.0.list.pop_front()
}
}
Iter {
list: std::mem::take(&mut self.list),
}
Iter(self)
}
}
@@ -84,7 +74,7 @@ pub(crate) struct Receiver {
impl Receiver {
pub(crate) fn recv_all(&mut self) -> impl Iterator<Item = EntryHandle> {
self.inner.lock().iter()
std::mem::take(&mut *self.inner.lock()).into_iter()
}
}
+18 -33
View File
@@ -107,39 +107,31 @@ impl Wheel {
/// Advances the timer up to the instant represented by `now`.
pub(crate) fn take_expired(&mut self, now: u64, wake_queue: &mut WakeQueue) {
loop {
match self.next_expiration() {
Some(ref expiration) if expiration.deadline <= now => {
self.process_expiration(expiration, wake_queue);
while let Some(expiration) = self
.next_expiration()
.filter(|expiration| expiration.deadline <= now)
{
self.process_expiration(&expiration, wake_queue);
self.set_elapsed(expiration.deadline);
}
_ => {
// in this case the poll did not indicate an expiration
// _and_ we were not able to find a next expiration in
// the current list of timers. advance to the poll's
// current time and do nothing else.
self.set_elapsed(now);
break;
}
}
self.set_elapsed(expiration.deadline);
}
self.set_elapsed(now);
}
/// Returns the instant at which the next timeout expires.
fn next_expiration(&self) -> Option<Expiration> {
// Check all levels
for (level_num, level) in self.levels.iter().enumerate() {
if let Some(expiration) = level.next_expiration(self.elapsed) {
self.levels
.iter()
.enumerate()
.find_map(|(level_num, level)| {
let expiration = level.next_expiration(self.elapsed)?;
// There cannot be any expirations at a higher level that happen
// before this one.
debug_assert!(self.no_expirations_before(level_num + 1, expiration.deadline));
return Some(expiration);
}
}
None
Some(expiration)
})
}
/// Returns the tick at which this timer wheel next needs to perform some
@@ -150,17 +142,10 @@ impl Wheel {
/// Used for debug assertions
fn no_expirations_before(&self, start_level: usize, before: u64) -> bool {
let mut res = true;
for level in &self.levels[start_level..] {
if let Some(e2) = level.next_expiration(self.elapsed) {
if e2.deadline < before {
res = false;
}
}
}
res
self.levels[start_level..]
.iter()
.flat_map(|level| level.next_expiration(self.elapsed))
.all(|e2| before <= e2.deadline)
}
/// iteratively find entries that are between the wheel's current