mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 22:47:44 +00:00
Kernel: Make TimeManagement use AK::Time internally
I don't dare touch the multi-threading logic and locking mechanism, so it stays timespec for now. However, this could and should be changed to AK::Time, and I bet it will simplify the "increment_time_since_boot()" code.
This commit is contained in:
parent
91c72faa3c
commit
c040e64b7d
8 changed files with 39 additions and 38 deletions
|
@ -383,7 +383,7 @@ int Process::alloc_fd(int first_candidate_fd)
|
||||||
|
|
||||||
timeval kgettimeofday()
|
timeval kgettimeofday()
|
||||||
{
|
{
|
||||||
return TimeManagement::now_as_timeval();
|
return TimeManagement::now().to_timeval();
|
||||||
}
|
}
|
||||||
|
|
||||||
void kgettimeofday(timeval& tv)
|
void kgettimeofday(timeval& tv)
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
|
// FIXME: Should use AK::Time internally
|
||||||
timeval kgettimeofday();
|
timeval kgettimeofday();
|
||||||
void kgettimeofday(timeval&);
|
void kgettimeofday(timeval&);
|
||||||
|
|
||||||
|
|
|
@ -45,8 +45,7 @@ KResultOr<unsigned> Process::sys$alarm(unsigned seconds)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (seconds > 0) {
|
if (seconds > 0) {
|
||||||
// FIXME: Should use AK::Time internally
|
auto deadline = TimeManagement::the().current_time(CLOCK_REALTIME_COARSE).value();
|
||||||
auto deadline = Time::from_timespec(TimeManagement::the().current_time(CLOCK_REALTIME_COARSE).value());
|
|
||||||
deadline = deadline + Time::from_seconds(seconds);
|
deadline = deadline + Time::from_seconds(seconds);
|
||||||
m_alarm_timer = TimerQueue::the().add_timer_without_id(CLOCK_REALTIME_COARSE, deadline, [this]() {
|
m_alarm_timer = TimerQueue::the().add_timer_without_id(CLOCK_REALTIME_COARSE, deadline, [this]() {
|
||||||
[[maybe_unused]] auto rc = send_signal(SIGALRM, nullptr);
|
[[maybe_unused]] auto rc = send_signal(SIGALRM, nullptr);
|
||||||
|
|
|
@ -34,11 +34,12 @@ KResultOr<int> Process::sys$clock_gettime(clockid_t clock_id, Userspace<timespec
|
||||||
{
|
{
|
||||||
REQUIRE_PROMISE(stdio);
|
REQUIRE_PROMISE(stdio);
|
||||||
|
|
||||||
auto ts = TimeManagement::the().current_time(clock_id);
|
auto time = TimeManagement::the().current_time(clock_id);
|
||||||
if (ts.is_error())
|
if (time.is_error())
|
||||||
return ts.error();
|
return time.error();
|
||||||
|
|
||||||
if (!copy_to_user(user_ts, &ts.value()))
|
auto ts = time.value().to_timespec();
|
||||||
|
if (!copy_to_user(user_ts, &ts))
|
||||||
return EFAULT;
|
return EFAULT;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -56,8 +57,7 @@ KResultOr<int> Process::sys$clock_settime(clockid_t clock_id, Userspace<const ti
|
||||||
|
|
||||||
switch (clock_id) {
|
switch (clock_id) {
|
||||||
case CLOCK_REALTIME:
|
case CLOCK_REALTIME:
|
||||||
// FIXME: Should use AK::Time internally
|
TimeManagement::the().set_epoch_time(ts.value());
|
||||||
TimeManagement::the().set_epoch_time(ts->to_timespec());
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
|
@ -42,8 +42,7 @@ Thread::BlockTimeout::BlockTimeout(bool is_absolute, const Time* time, const Tim
|
||||||
m_time = *time;
|
m_time = *time;
|
||||||
m_should_block = true;
|
m_should_block = true;
|
||||||
}
|
}
|
||||||
// FIXME: Should use AK::Time internally
|
m_start_time = start_time ? *start_time : TimeManagement::the().current_time(clock_id).value();
|
||||||
m_start_time = start_time ? *start_time : Time::from_timespec(TimeManagement::the().current_time(clock_id).value());
|
|
||||||
if (!is_absolute)
|
if (!is_absolute)
|
||||||
m_time = m_time + m_start_time;
|
m_time = m_time + m_start_time;
|
||||||
}
|
}
|
||||||
|
@ -349,8 +348,7 @@ void Thread::SleepBlocker::calculate_remaining()
|
||||||
{
|
{
|
||||||
if (!m_remaining)
|
if (!m_remaining)
|
||||||
return;
|
return;
|
||||||
// FIXME: Should use AK::Time internally
|
auto time_now = TimeManagement::the().current_time(m_deadline.clock_id()).value();
|
||||||
auto time_now = Time::from_timespec(TimeManagement::the().current_time(m_deadline.clock_id()).value());
|
|
||||||
if (time_now < m_deadline.absolute_time())
|
if (time_now < m_deadline.absolute_time())
|
||||||
*m_remaining = m_deadline.absolute_time() - time_now;
|
*m_remaining = m_deadline.absolute_time() - time_now;
|
||||||
else
|
else
|
||||||
|
|
|
@ -64,7 +64,7 @@ bool TimeManagement::is_valid_clock_id(clockid_t clock_id)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
KResultOr<timespec> TimeManagement::current_time(clockid_t clock_id) const
|
KResultOr<Time> TimeManagement::current_time(clockid_t clock_id) const
|
||||||
{
|
{
|
||||||
switch (clock_id) {
|
switch (clock_id) {
|
||||||
case CLOCK_MONOTONIC:
|
case CLOCK_MONOTONIC:
|
||||||
|
@ -87,14 +87,15 @@ bool TimeManagement::is_system_timer(const HardwareTimerBase& timer) const
|
||||||
return &timer == m_system_timer.ptr();
|
return &timer == m_system_timer.ptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimeManagement::set_epoch_time(timespec ts)
|
void TimeManagement::set_epoch_time(Time ts)
|
||||||
{
|
{
|
||||||
InterruptDisabler disabler;
|
InterruptDisabler disabler;
|
||||||
m_epoch_time = ts;
|
// FIXME: Should use AK::Time internally
|
||||||
|
m_epoch_time = ts.to_timespec();
|
||||||
m_remaining_epoch_time_adjustment = { 0, 0 };
|
m_remaining_epoch_time_adjustment = { 0, 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
timespec TimeManagement::monotonic_time(TimePrecision precision) const
|
Time TimeManagement::monotonic_time(TimePrecision precision) const
|
||||||
{
|
{
|
||||||
// This is the time when last updated by an interrupt.
|
// This is the time when last updated by an interrupt.
|
||||||
u64 seconds;
|
u64 seconds;
|
||||||
|
@ -122,10 +123,10 @@ timespec TimeManagement::monotonic_time(TimePrecision precision) const
|
||||||
VERIFY(ticks < m_time_ticks_per_second);
|
VERIFY(ticks < m_time_ticks_per_second);
|
||||||
u64 ns = ((u64)ticks * 1000000000ull) / m_time_ticks_per_second;
|
u64 ns = ((u64)ticks * 1000000000ull) / m_time_ticks_per_second;
|
||||||
VERIFY(ns < 1000000000ull);
|
VERIFY(ns < 1000000000ull);
|
||||||
return { (long)seconds, (long)ns };
|
return Time::from_timespec({ (i64)seconds, (i32)ns });
|
||||||
}
|
}
|
||||||
|
|
||||||
timespec TimeManagement::epoch_time(TimePrecision) const
|
Time TimeManagement::epoch_time(TimePrecision) const
|
||||||
{
|
{
|
||||||
// TODO: Take into account precision
|
// TODO: Take into account precision
|
||||||
timespec ts;
|
timespec ts;
|
||||||
|
@ -134,12 +135,14 @@ timespec TimeManagement::epoch_time(TimePrecision) const
|
||||||
update_iteration = m_update1.load(AK::MemoryOrder::memory_order_acquire);
|
update_iteration = m_update1.load(AK::MemoryOrder::memory_order_acquire);
|
||||||
ts = m_epoch_time;
|
ts = m_epoch_time;
|
||||||
} while (update_iteration != m_update2.load(AK::MemoryOrder::memory_order_acquire));
|
} while (update_iteration != m_update2.load(AK::MemoryOrder::memory_order_acquire));
|
||||||
return ts;
|
return Time::from_timespec(ts);
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 TimeManagement::uptime_ms() const
|
u64 TimeManagement::uptime_ms() const
|
||||||
{
|
{
|
||||||
auto mtime = monotonic_time();
|
auto mtime = monotonic_time().to_timespec();
|
||||||
|
// This overflows after 292 million years of uptime.
|
||||||
|
// Since this is only used for performance timestamps and sys$times, that's probably enough.
|
||||||
u64 ms = mtime.tv_sec * 1000ull;
|
u64 ms = mtime.tv_sec * 1000ull;
|
||||||
ms += mtime.tv_nsec / 1000000;
|
ms += mtime.tv_nsec / 1000000;
|
||||||
return ms;
|
return ms;
|
||||||
|
@ -211,12 +214,9 @@ UNMAP_AFTER_INIT TimeManagement::TimeManagement()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
timeval TimeManagement::now_as_timeval()
|
Time TimeManagement::now()
|
||||||
{
|
{
|
||||||
timespec ts = s_the.ptr()->epoch_time();
|
return s_the.ptr()->epoch_time();
|
||||||
timeval tv;
|
|
||||||
timespec_to_timeval(ts, tv);
|
|
||||||
return tv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<HardwareTimerBase*> TimeManagement::scan_and_initialize_periodic_timers()
|
Vector<HardwareTimerBase*> TimeManagement::scan_and_initialize_periodic_timers()
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#include <AK/NonnullRefPtrVector.h>
|
#include <AK/NonnullRefPtrVector.h>
|
||||||
#include <AK/RefPtr.h>
|
#include <AK/RefPtr.h>
|
||||||
|
#include <AK/Time.h>
|
||||||
#include <AK/Types.h>
|
#include <AK/Types.h>
|
||||||
#include <Kernel/KResult.h>
|
#include <Kernel/KResult.h>
|
||||||
#include <Kernel/UnixTypes.h>
|
#include <Kernel/UnixTypes.h>
|
||||||
|
@ -53,15 +54,15 @@ public:
|
||||||
static TimeManagement& the();
|
static TimeManagement& the();
|
||||||
|
|
||||||
static bool is_valid_clock_id(clockid_t);
|
static bool is_valid_clock_id(clockid_t);
|
||||||
KResultOr<timespec> current_time(clockid_t) const;
|
KResultOr<Time> current_time(clockid_t) const;
|
||||||
timespec monotonic_time(TimePrecision = TimePrecision::Coarse) const;
|
Time monotonic_time(TimePrecision = TimePrecision::Coarse) const;
|
||||||
timespec monotonic_time_raw() const
|
Time monotonic_time_raw() const
|
||||||
{
|
{
|
||||||
// TODO: implement
|
// TODO: implement
|
||||||
return monotonic_time(TimePrecision::Precise);
|
return monotonic_time(TimePrecision::Precise);
|
||||||
}
|
}
|
||||||
timespec epoch_time(TimePrecision = TimePrecision::Precise) const;
|
Time epoch_time(TimePrecision = TimePrecision::Precise) const;
|
||||||
void set_epoch_time(timespec);
|
void set_epoch_time(Time);
|
||||||
time_t ticks_per_second() const;
|
time_t ticks_per_second() const;
|
||||||
time_t boot_time() const;
|
time_t boot_time() const;
|
||||||
|
|
||||||
|
@ -75,9 +76,13 @@ public:
|
||||||
static bool is_hpet_periodic_mode_allowed();
|
static bool is_hpet_periodic_mode_allowed();
|
||||||
|
|
||||||
u64 uptime_ms() const;
|
u64 uptime_ms() const;
|
||||||
static timeval now_as_timeval();
|
static Time now();
|
||||||
|
|
||||||
|
// FIXME: Should use AK::Time internally
|
||||||
|
// FIXME: Also, most likely broken, because it does not check m_update[12] for in-progress updates.
|
||||||
timespec remaining_epoch_time_adjustment() const { return m_remaining_epoch_time_adjustment; }
|
timespec remaining_epoch_time_adjustment() const { return m_remaining_epoch_time_adjustment; }
|
||||||
|
// FIXME: Should use AK::Time internally
|
||||||
|
// FIXME: Also, most likely broken, because it does not check m_update[12] for in-progress updates.
|
||||||
void set_remaining_epoch_time_adjustment(const timespec& adjustment) { m_remaining_epoch_time_adjustment = adjustment; }
|
void set_remaining_epoch_time_adjustment(const timespec& adjustment) { m_remaining_epoch_time_adjustment = adjustment; }
|
||||||
|
|
||||||
bool can_query_precise_time() const { return m_can_query_precise_time; }
|
bool can_query_precise_time() const { return m_can_query_precise_time; }
|
||||||
|
@ -95,6 +100,7 @@ private:
|
||||||
Atomic<u32> m_update1 { 0 };
|
Atomic<u32> m_update1 { 0 };
|
||||||
u32 m_ticks_this_second { 0 };
|
u32 m_ticks_this_second { 0 };
|
||||||
u64 m_seconds_since_boot { 0 };
|
u64 m_seconds_since_boot { 0 };
|
||||||
|
// FIXME: Should use AK::Time internally
|
||||||
timespec m_epoch_time { 0, 0 };
|
timespec m_epoch_time { 0, 0 };
|
||||||
timespec m_remaining_epoch_time_adjustment { 0, 0 };
|
timespec m_remaining_epoch_time_adjustment { 0, 0 };
|
||||||
Atomic<u32> m_update2 { 0 };
|
Atomic<u32> m_update2 { 0 };
|
||||||
|
|
|
@ -64,8 +64,7 @@ Time Timer::now(bool is_firing) const
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// FIXME: Should use AK::Time internally
|
return TimeManagement::the().current_time(clock_id).value();
|
||||||
return Time::from_timespec(TimeManagement::the().current_time(clock_id).value());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TimerQueue& TimerQueue::the()
|
TimerQueue& TimerQueue::the()
|
||||||
|
@ -80,8 +79,7 @@ UNMAP_AFTER_INIT TimerQueue::TimerQueue()
|
||||||
|
|
||||||
RefPtr<Timer> TimerQueue::add_timer_without_id(clockid_t clock_id, const Time& deadline, Function<void()>&& callback)
|
RefPtr<Timer> TimerQueue::add_timer_without_id(clockid_t clock_id, const Time& deadline, Function<void()>&& callback)
|
||||||
{
|
{
|
||||||
// FIXME: Should use AK::Time internally
|
if (deadline <= TimeManagement::the().current_time(clock_id).value())
|
||||||
if (deadline <= Time::from_timespec(TimeManagement::the().current_time(clock_id).value()))
|
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
// Because timer handlers can execute on any processor and there is
|
// Because timer handlers can execute on any processor and there is
|
||||||
|
@ -139,8 +137,7 @@ void TimerQueue::add_timer_locked(NonnullRefPtr<Timer> timer)
|
||||||
|
|
||||||
TimerId TimerQueue::add_timer(clockid_t clock_id, const Time& deadline, Function<void()>&& callback)
|
TimerId TimerQueue::add_timer(clockid_t clock_id, const Time& deadline, Function<void()>&& callback)
|
||||||
{
|
{
|
||||||
// FIXME: Should use AK::Time internally
|
auto expires = TimeManagement::the().current_time(clock_id).value();
|
||||||
auto expires = Time::from_timespec(TimeManagement::the().current_time(clock_id).value());
|
|
||||||
expires = expires + deadline;
|
expires = expires + deadline;
|
||||||
return add_timer(adopt(*new Timer(clock_id, expires, move(callback))));
|
return add_timer(adopt(*new Timer(clock_id, expires, move(callback))));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue