From db2a8725c6d278b808fd0640caaff523eba16a17 Mon Sep 17 00:00:00 2001 From: Zaggy1024 Date: Mon, 7 Aug 2023 05:28:46 -0500 Subject: [PATCH] LibCore: Only use coarse time in the Unix event loop wait_for_events() A typo in the changes to our userland timekeeping classes caused us to make a syscall every time we want to check whether a timer is ready to fire in `EventLoopManagerUnix::wait_for_events()`. Instead, only use coarse time, and get it immediately before it is used in both cases. This reduces CPU usage by an (eyeballed) 20-30% while playing back video with VideoPlayer. --- .../LibCore/EventLoopImplementationUnix.cpp | 43 +++++++++---------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/Userland/Libraries/LibCore/EventLoopImplementationUnix.cpp b/Userland/Libraries/LibCore/EventLoopImplementationUnix.cpp index 78853c876e..91209c5a47 100644 --- a/Userland/Libraries/LibCore/EventLoopImplementationUnix.cpp +++ b/Userland/Libraries/LibCore/EventLoopImplementationUnix.cpp @@ -169,13 +169,12 @@ retry: // Figure out how long to wait at maximum. // This mainly depends on the PumpMode and whether we have pending events, but also the next expiring timer. - MonotonicTime now = MonotonicTime::now_coarse(); struct timeval timeout = { 0, 0 }; bool should_wait_forever = false; if (mode == EventLoopImplementation::PumpMode::WaitForEvents && !has_pending_events) { auto next_timer_expiration = get_next_timer_expiration(); if (next_timer_expiration.has_value()) { - now = MonotonicTime::now(); + auto now = MonotonicTime::now_coarse(); auto computed_timeout = next_timer_expiration.value() - now; if (computed_timeout.is_negative()) computed_timeout = Duration::zero(); @@ -228,28 +227,28 @@ try_select_again: goto retry; } - if (!thread_data.timers.is_empty()) { - now = MonotonicTime::now_coarse(); - } - // Handle expired timers. - for (auto& it : thread_data.timers) { - auto& timer = *it.value; - if (!timer.has_expired(now)) - continue; - auto owner = timer.owner.strong_ref(); - if (timer.fire_when_not_visible == TimerShouldFireWhenNotVisible::No - && owner && !owner->is_visible_for_timer_purposes()) { - continue; - } + if (!thread_data.timers.is_empty()) { + auto now = MonotonicTime::now_coarse(); - if (owner) - ThreadEventQueue::current().post_event(*owner, make(timer.timer_id)); - if (timer.should_reload) { - timer.reload(now); - } else { - // FIXME: Support removing expired timers that don't want to reload. - VERIFY_NOT_REACHED(); + for (auto& it : thread_data.timers) { + auto& timer = *it.value; + if (!timer.has_expired(now)) + continue; + auto owner = timer.owner.strong_ref(); + if (timer.fire_when_not_visible == TimerShouldFireWhenNotVisible::No + && owner && !owner->is_visible_for_timer_purposes()) { + continue; + } + + if (owner) + ThreadEventQueue::current().post_event(*owner, make(timer.timer_id)); + if (timer.should_reload) { + timer.reload(now); + } else { + // FIXME: Support removing expired timers that don't want to reload. + VERIFY_NOT_REACHED(); + } } }