summaryrefslogtreecommitdiff
path: root/Kernel/Scheduler.cpp
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-02-01 03:50:06 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-02-01 03:50:06 +0100
commit95c3442d595efa0a84badc33bd00bd9e10bb2034 (patch)
tree19b33c0a9ba96bb3774c4b9b58bc27d9b29ee830 /Kernel/Scheduler.cpp
parent9153666e72effdf56ce19332f953caff7d173a7e (diff)
downloadserenity-95c3442d595efa0a84badc33bd00bd9e10bb2034.zip
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.
Diffstat (limited to 'Kernel/Scheduler.cpp')
-rw-r--r--Kernel/Scheduler.cpp12
1 files changed, 11 insertions, 1 deletions
diff --git a/Kernel/Scheduler.cpp b/Kernel/Scheduler.cpp
index 54c6efad6a..8cc88c2492 100644
--- a/Kernel/Scheduler.cpp
+++ b/Kernel/Scheduler.cpp
@@ -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();