mirror of
https://github.com/SerenityOS/serenity
synced 2024-07-24 11:35:13 +00:00
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.
This commit is contained in:
parent
742eff26a9
commit
db2a8725c6
|
@ -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) {
|
if (!thread_data.timers.is_empty()) {
|
||||||
auto& timer = *it.value;
|
auto now = MonotonicTime::now_coarse();
|
||||||
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)
|
for (auto& it : thread_data.timers) {
|
||||||
ThreadEventQueue::current().post_event(*owner, make<TimerEvent>(timer.timer_id));
|
auto& timer = *it.value;
|
||||||
if (timer.should_reload) {
|
if (!timer.has_expired(now))
|
||||||
timer.reload(now);
|
continue;
|
||||||
} else {
|
auto owner = timer.owner.strong_ref();
|
||||||
// FIXME: Support removing expired timers that don't want to reload.
|
if (timer.fire_when_not_visible == TimerShouldFireWhenNotVisible::No
|
||||||
VERIFY_NOT_REACHED();
|
&& 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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue