From 49c438ce320c7f1d7fb5c58164ea0a66a2650a6c Mon Sep 17 00:00:00 2001 From: Brian Gianforcaro Date: Sun, 26 Apr 2020 14:00:34 -0700 Subject: [PATCH] Kernel: Update TimerQueue next due timer only when necessary Previously we blindly just called update_next_timer_due() when ever we modified the timer list. Since we know the list is sorted this is a bit wasteful, and we can do better. This change refactors the code so we only update the next due time when necessary. In places where it was possible the code was modified to directly modify the next due time, instead of having to go to the front of the list to fetch it. --- Kernel/TimerQueue.cpp | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/Kernel/TimerQueue.cpp b/Kernel/TimerQueue.cpp index 2435c31611..cac513039f 100644 --- a/Kernel/TimerQueue.cpp +++ b/Kernel/TimerQueue.cpp @@ -49,17 +49,27 @@ TimerQueue::TimerQueue() TimerId TimerQueue::add_timer(NonnullOwnPtr&& timer) { - ASSERT(timer->expires >= g_uptime); + u64 timer_expiration = timer->expires; + ASSERT(timer_expiration >= g_uptime); timer->id = ++m_timer_id_count; - auto following_timer = m_timer_queue.find([&timer](auto& other) { return other->expires > timer->expires; }); - if (following_timer.is_end()) + if (m_timer_queue.is_empty()) { m_timer_queue.append(move(timer)); - else - m_timer_queue.insert_before(following_timer, move(timer)); + m_next_timer_due = timer_expiration; + } else { + auto following_timer = m_timer_queue.find([&timer_expiration](auto& other) { return other->expires > timer_expiration; }); - update_next_timer_due(); + if (following_timer.is_end()) { + m_timer_queue.append(move(timer)); + } else { + auto next_timer_needs_update = following_timer.is_begin(); + m_timer_queue.insert_before(following_timer, move(timer)); + + if (next_timer_needs_update) + m_next_timer_due = timer_expiration; + } + } return m_timer_id_count; } @@ -77,8 +87,13 @@ bool TimerQueue::cancel_timer(TimerId id) auto it = m_timer_queue.find([id](auto& timer) { return timer->id == id; }); if (it.is_end()) return false; + + auto was_next_timer = it.is_begin(); m_timer_queue.remove(it); - update_next_timer_due(); + + if (was_next_timer) + update_next_timer_due(); + return true; }