summaryrefslogtreecommitdiff
path: root/Kernel/TimerQueue.h
diff options
context:
space:
mode:
authorTom <tomut@yahoo.com>2020-12-01 16:53:47 -0700
committerAndreas Kling <kling@serenityos.org>2020-12-02 13:02:04 +0100
commit12cf6f86503cee499d093b7accebe6ad11bc1dae (patch)
tree4d7da8b3e662ff64a83bc3fa97f927e60ed5966c /Kernel/TimerQueue.h
parent4c1e27ec656d26e85d0a7a1991c26a67aed115a2 (diff)
downloadserenity-12cf6f86503cee499d093b7accebe6ad11bc1dae.zip
Kernel: Add CLOCK_REALTIME support to the TimerQueue
This allows us to use blocking timeouts with either monotonic or real time for all blockers. Which means that clock_nanosleep() now also supports CLOCK_REALTIME. Also, switch alarm() to use CLOCK_REALTIME as per specification.
Diffstat (limited to 'Kernel/TimerQueue.h')
-rw-r--r--Kernel/TimerQueue.h39
1 files changed, 29 insertions, 10 deletions
diff --git a/Kernel/TimerQueue.h b/Kernel/TimerQueue.h
index ffeda2fedc..33e741b388 100644
--- a/Kernel/TimerQueue.h
+++ b/Kernel/TimerQueue.h
@@ -43,8 +43,9 @@ class Timer : public RefCounted<Timer>
friend class InlineLinkedListNode<Timer>;
public:
- Timer(u64 expires, Function<void()>&& callback)
- : m_expires(expires)
+ Timer(clockid_t clock_id, u64 expires, Function<void()>&& callback)
+ : m_clock_id(clock_id)
+ , m_expires(expires)
, m_callback(move(callback))
{
}
@@ -57,6 +58,7 @@ public:
private:
TimerId m_id;
+ clockid_t m_clock_id;
u64 m_expires;
u64 m_remaining { 0 };
Function<void()> m_callback;
@@ -78,6 +80,7 @@ private:
}
bool is_queued() const { return m_queued.load(AK::MemoryOrder::memory_order_relaxed); }
void set_queued(bool queued) { m_queued.store(queued, AK::MemoryOrder::memory_order_relaxed); }
+ u64 now() const;
};
class TimerQueue {
@@ -88,8 +91,8 @@ public:
static TimerQueue& the();
TimerId add_timer(NonnullRefPtr<Timer>&&);
- RefPtr<Timer> add_timer_without_id(const timespec& timeout, Function<void()>&& callback);
- TimerId add_timer(timeval& timeout, Function<void()>&& callback);
+ RefPtr<Timer> add_timer_without_id(clockid_t, const timespec&, Function<void()>&&);
+ TimerId add_timer(clockid_t, timeval& timeout, Function<void()>&& callback);
bool cancel_timer(TimerId id);
bool cancel_timer(Timer&);
bool cancel_timer(NonnullRefPtr<Timer>&& timer)
@@ -99,17 +102,33 @@ public:
void fire();
private:
- void remove_timer_locked(Timer&);
- void update_next_timer_due();
+ struct Queue {
+ InlineLinkedList<Timer> list;
+ u64 next_timer_due { 0 };
+ };
+ void remove_timer_locked(Queue&, Timer&);
+ void update_next_timer_due(Queue&);
void add_timer_locked(NonnullRefPtr<Timer>);
- timespec ticks_to_time(u64 ticks) const;
- u64 time_to_ticks(const timespec&) const;
+ Queue& queue_for_timer(Timer& timer)
+ {
+ switch (timer.m_clock_id) {
+ case CLOCK_MONOTONIC:
+ return m_timer_queue_monotonic;
+ case CLOCK_REALTIME:
+ return m_timer_queue_realtime;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ }
+
+ timespec ticks_to_time(clockid_t, u64 ticks) const;
+ u64 time_to_ticks(clockid_t, const timespec&) const;
- u64 m_next_timer_due { 0 };
u64 m_timer_id_count { 0 };
u64 m_ticks_per_second { 0 };
- InlineLinkedList<Timer> m_timer_queue;
+ Queue m_timer_queue_monotonic;
+ Queue m_timer_queue_realtime;
InlineLinkedList<Timer> m_timers_executing;
};