mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 09:48:11 +00:00
Kernel: Use UnixDateTime wherever applicable
"Wherever applicable" = most places, actually :^), especially for networking and filesystem timestamps. This includes changes to unzip, which uses DOSPackedTime, since that is changed for the FAT file systems.
This commit is contained in:
parent
c1323febc2
commit
939600d2d4
41 changed files with 115 additions and 125 deletions
|
@ -87,9 +87,9 @@ Duration TimeManagement::current_time(clockid_t clock_id) const
|
|||
case CLOCK_MONOTONIC_RAW:
|
||||
return monotonic_time_raw();
|
||||
case CLOCK_REALTIME:
|
||||
return epoch_time(TimePrecision::Precise);
|
||||
return epoch_time(TimePrecision::Precise).offset_to_epoch();
|
||||
case CLOCK_REALTIME_COARSE:
|
||||
return epoch_time(TimePrecision::Coarse);
|
||||
return epoch_time(TimePrecision::Coarse).offset_to_epoch();
|
||||
default:
|
||||
// Syscall entrypoint is missing a is_valid_clock_id(..) check?
|
||||
VERIFY_NOT_REACHED();
|
||||
|
@ -101,12 +101,13 @@ bool TimeManagement::is_system_timer(HardwareTimerBase const& timer) const
|
|||
return &timer == m_system_timer.ptr();
|
||||
}
|
||||
|
||||
void TimeManagement::set_epoch_time(Duration ts)
|
||||
void TimeManagement::set_epoch_time(UnixDateTime ts)
|
||||
{
|
||||
// FIXME: The interrupt disabler intends to enforce atomic update of epoch time and remaining adjustment,
|
||||
// but that sort of assumption is known to break on SMP.
|
||||
InterruptDisabler disabler;
|
||||
// FIXME: Should use AK::Duration internally
|
||||
m_epoch_time = ts.to_timespec();
|
||||
m_remaining_epoch_time_adjustment = { 0, 0 };
|
||||
m_epoch_time = ts;
|
||||
m_remaining_epoch_time_adjustment = {};
|
||||
}
|
||||
|
||||
Duration TimeManagement::monotonic_time(TimePrecision precision) const
|
||||
|
@ -147,16 +148,16 @@ Duration TimeManagement::monotonic_time(TimePrecision precision) const
|
|||
return Duration::from_timespec({ (i64)seconds, (i32)ns });
|
||||
}
|
||||
|
||||
Duration TimeManagement::epoch_time(TimePrecision) const
|
||||
UnixDateTime TimeManagement::epoch_time(TimePrecision) const
|
||||
{
|
||||
// TODO: Take into account precision
|
||||
timespec ts;
|
||||
UnixDateTime time;
|
||||
u32 update_iteration;
|
||||
do {
|
||||
update_iteration = m_update1.load(AK::MemoryOrder::memory_order_acquire);
|
||||
ts = m_epoch_time;
|
||||
time = m_epoch_time;
|
||||
} while (update_iteration != m_update2.load(AK::MemoryOrder::memory_order_acquire));
|
||||
return Duration::from_timespec(ts);
|
||||
return time;
|
||||
}
|
||||
|
||||
u64 TimeManagement::uptime_ms() const
|
||||
|
@ -226,7 +227,7 @@ time_t TimeManagement::ticks_per_second() const
|
|||
return m_time_keeper_timer->ticks_per_second();
|
||||
}
|
||||
|
||||
Duration TimeManagement::boot_time()
|
||||
UnixDateTime TimeManagement::boot_time()
|
||||
{
|
||||
#if ARCH(X86_64)
|
||||
return RTC::boot_time();
|
||||
|
@ -252,14 +253,14 @@ UNMAP_AFTER_INIT TimeManagement::TimeManagement()
|
|||
if (ACPI::is_enabled()) {
|
||||
if (!ACPI::Parser::the()->x86_specific_flags().cmos_rtc_not_present) {
|
||||
RTC::initialize();
|
||||
m_epoch_time.tv_sec += boot_time().to_timespec().tv_sec;
|
||||
m_epoch_time += boot_time().offset_to_epoch();
|
||||
} else {
|
||||
dmesgln("ACPI: RTC CMOS Not present");
|
||||
}
|
||||
} else {
|
||||
// We just assume that we can access RTC CMOS, if ACPI isn't usable.
|
||||
RTC::initialize();
|
||||
m_epoch_time.tv_sec += boot_time().to_timespec().tv_sec;
|
||||
m_epoch_time += boot_time().offset_to_epoch();
|
||||
}
|
||||
if (probe_non_legacy_hardware_timers) {
|
||||
if (!probe_and_set_x86_non_legacy_hardware_timers())
|
||||
|
@ -275,7 +276,7 @@ UNMAP_AFTER_INIT TimeManagement::TimeManagement()
|
|||
#endif
|
||||
}
|
||||
|
||||
Duration TimeManagement::now()
|
||||
UnixDateTime TimeManagement::now()
|
||||
{
|
||||
return s_the.ptr()->epoch_time();
|
||||
}
|
||||
|
@ -437,7 +438,8 @@ void TimeManagement::increment_time_since_boot_hpet()
|
|||
m_seconds_since_boot = seconds_since_boot;
|
||||
m_ticks_this_second = ticks_this_second;
|
||||
// TODO: Apply m_remaining_epoch_time_adjustment
|
||||
timespec_add(m_epoch_time, { (time_t)(delta_ns / 1000000000), (long)(delta_ns % 1000000000) }, m_epoch_time);
|
||||
timespec time_adjustment = { (time_t)(delta_ns / 1000000000), (long)(delta_ns % 1000000000) };
|
||||
m_epoch_time += Duration::from_timespec(time_adjustment);
|
||||
|
||||
m_update1.store(update_iteration + 1, AK::MemoryOrder::memory_order_release);
|
||||
|
||||
|
@ -483,20 +485,16 @@ void TimeManagement::increment_time_since_boot()
|
|||
// Compute time adjustment for adjtime. Let the clock run up to 1% fast or slow.
|
||||
// That way, adjtime can adjust up to 36 seconds per hour, without time getting very jumpy.
|
||||
// Once we have a smarter NTP service that also adjusts the frequency instead of just slewing time, maybe we can lower this.
|
||||
long NanosPerTick = 1'000'000'000 / m_time_keeper_timer->frequency();
|
||||
time_t MaxSlewNanos = NanosPerTick / 100;
|
||||
long nanos_per_tick = 1'000'000'000 / m_time_keeper_timer->frequency();
|
||||
time_t max_slew_nanos = nanos_per_tick / 100;
|
||||
|
||||
u32 update_iteration = m_update2.fetch_add(1, AK::MemoryOrder::memory_order_acquire);
|
||||
|
||||
// Clamp twice, to make sure intermediate fits into a long.
|
||||
long slew_nanos = clamp(clamp(m_remaining_epoch_time_adjustment.tv_sec, (time_t)-1, (time_t)1) * 1'000'000'000 + m_remaining_epoch_time_adjustment.tv_nsec, -MaxSlewNanos, MaxSlewNanos);
|
||||
timespec slew_nanos_ts;
|
||||
timespec_sub({ 0, slew_nanos }, { 0, 0 }, slew_nanos_ts); // Normalize tv_nsec to be positive.
|
||||
timespec_sub(m_remaining_epoch_time_adjustment, slew_nanos_ts, m_remaining_epoch_time_adjustment);
|
||||
auto slew_nanos = Duration::from_nanoseconds(
|
||||
clamp(m_remaining_epoch_time_adjustment.to_nanoseconds(), -max_slew_nanos, max_slew_nanos));
|
||||
m_remaining_epoch_time_adjustment -= slew_nanos;
|
||||
|
||||
timespec epoch_tick = { .tv_sec = 0, .tv_nsec = NanosPerTick };
|
||||
epoch_tick.tv_nsec += slew_nanos; // No need for timespec_add(), guaranteed to be in range.
|
||||
timespec_add(m_epoch_time, epoch_tick, m_epoch_time);
|
||||
m_epoch_time += Duration::from_nanoseconds(nanos_per_tick + slew_nanos.to_nanoseconds());
|
||||
|
||||
if (++m_ticks_this_second >= m_time_keeper_timer->ticks_per_second()) {
|
||||
// FIXME: Synchronize with other clock somehow to prevent drifting apart.
|
||||
|
@ -540,7 +538,7 @@ void TimeManagement::update_time_page()
|
|||
{
|
||||
auto& page = time_page();
|
||||
u32 update_iteration = AK::atomic_fetch_add(&page.update2, 1u, AK::MemoryOrder::memory_order_acquire);
|
||||
page.clocks[CLOCK_REALTIME_COARSE] = m_epoch_time;
|
||||
page.clocks[CLOCK_REALTIME_COARSE] = m_epoch_time.to_timespec();
|
||||
page.clocks[CLOCK_MONOTONIC_COARSE] = monotonic_time(TimePrecision::Coarse).to_timespec();
|
||||
AK::atomic_store(&page.update1, update_iteration + 1u, AK::MemoryOrder::memory_order_release);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue