Преглед изворни кода

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.
Zaggy1024 пре 1 година
родитељ
комит
db2a8725c6
1 измењених фајлова са 21 додато и 22 уклоњено
  1. 21 22
      Userland/Libraries/LibCore/EventLoopImplementationUnix.cpp

+ 21 - 22
Userland/Libraries/LibCore/EventLoopImplementationUnix.cpp

@@ -169,13 +169,12 @@ retry:
 
 
     // Figure out how long to wait at maximum.
     // 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.
     // 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 };
     struct timeval timeout = { 0, 0 };
     bool should_wait_forever = false;
     bool should_wait_forever = false;
     if (mode == EventLoopImplementation::PumpMode::WaitForEvents && !has_pending_events) {
     if (mode == EventLoopImplementation::PumpMode::WaitForEvents && !has_pending_events) {
         auto next_timer_expiration = get_next_timer_expiration();
         auto next_timer_expiration = get_next_timer_expiration();
         if (next_timer_expiration.has_value()) {
         if (next_timer_expiration.has_value()) {
-            now = MonotonicTime::now();
+            auto now = MonotonicTime::now_coarse();
             auto computed_timeout = next_timer_expiration.value() - now;
             auto computed_timeout = next_timer_expiration.value() - now;
             if (computed_timeout.is_negative())
             if (computed_timeout.is_negative())
                 computed_timeout = Duration::zero();
                 computed_timeout = Duration::zero();
@@ -228,28 +227,28 @@ try_select_again:
             goto retry;
             goto retry;
     }
     }
 
 
-    if (!thread_data.timers.is_empty()) {
-        now = MonotonicTime::now_coarse();
-    }
-
     // Handle expired timers.
     // 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();
+
+        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<TimerEvent>(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();
+            if (owner)
+                ThreadEventQueue::current().post_event(*owner, make<TimerEvent>(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();
+            }
         }
         }
     }
     }