1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-19 00:45:08 +00:00

Implement event loop timers.

GObjects can now register a timer with the GEventLoop. This will eventually
cause GTimerEvents to be dispatched to the GObject.

This needed a few supporting changes in the kernel:

- The PIT now ticks 1000 times/sec.
- select() now supports an arbitrary timeout.
- gettimeofday() now returns something in the tv_usec field.

With these changes, the clock window in guitest2 finally ticks on its own.
This commit is contained in:
Andreas Kling 2019-02-01 03:50:06 +01:00
parent 9153666e72
commit 95c3442d59
10 changed files with 140 additions and 7 deletions

View file

@ -1,6 +1,8 @@
#include "Scheduler.h"
#include "Process.h"
#include "system.h"
#include "RTC.h"
#include "i8253.h"
//#define LOG_EVERY_CONTEXT_SWITCH
//#define SCHEDULER_DEBUG
@ -29,7 +31,7 @@ bool Scheduler::pick_next()
}
// Check and unblock processes whose wait conditions have been met.
Process::for_each([] (auto& process) {
Process::for_each([] (Process& process) {
if (process.state() == Process::BlockedSleep) {
if (process.wakeup_time() <= system.uptime)
process.unblock();
@ -71,6 +73,14 @@ bool Scheduler::pick_next()
process.unblock();
return true;
}
if (process.m_select_has_timeout) {
auto now_sec = RTC::now();
auto now_usec = PIT::ticks_since_boot() % 1000;
if (now_sec > process.m_select_timeout.tv_sec || (now_sec == process.m_select_timeout.tv_sec && now_usec >= process.m_select_timeout.tv_usec)) {
process.unblock();
return true;
}
}
for (int fd : process.m_select_read_fds) {
if (process.m_fds[fd].descriptor->can_read(process)) {
process.unblock();