mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 23:07:35 +00:00
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.
This commit is contained in:
parent
4c1e27ec65
commit
12cf6f8650
9 changed files with 182 additions and 97 deletions
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue