mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-01-04 09:14:21 +03:00
323e727a4c
Most systems (Linux, OpenBSD) adjust 0.5 ms per second, or 0.5 us per 1 ms tick. That is, the clock is sped up or slowed down by at most 0.05%. This means adjusting the clock by 1 s takes 2000 s, and the clock an be adjusted by at most 1.8 s per hour. FreeBSD adjusts 5 ms per second if the remaining time adjustment is >= 1 s (0.5%) , else it adjusts by 0.5 ms as well. This allows adjusting by (almost) 18 s per hour. Since Serenity OS can lose more than 22 s per hour (#3429), this picks an adjustment rate up to 1% for now. This allows us to adjust up to 36s per hour, which should be sufficient to adjust the clock fast enough to keep up with how much time the clock currently loses. Once we have a fancier NTP implementation that can adjust tick rate in addition to offset, we can think about reducing this. adjtime is a bit old-school and most current POSIX-y OSs instead implement adjtimex/ntp_adjtime, but a) we have to start somewhere b) ntp_adjtime() is a fairly gnarly API. OpenBSD's adjfreq looks like it might provide similar functionality with a nicer API. But before worrying about all this, it's probably a good idea to get to a place where the kernel APIs are (barely) good enough so that we can write an ntp service, and once we have that we should write a way to automatically evaluate how well it keeps the time adjusted, and only then should we add improvements ot the adjustment mechanism.
85 lines
3.0 KiB
C++
85 lines
3.0 KiB
C++
/*
|
|
* Copyright (c) 2020, Liav A. <liavalb@hotmail.co.il>
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
* list of conditions and the following disclaimer.
|
|
*
|
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
* and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <AK/NonnullRefPtrVector.h>
|
|
#include <AK/RefPtr.h>
|
|
#include <AK/Types.h>
|
|
#include <Kernel/UnixTypes.h>
|
|
|
|
namespace Kernel {
|
|
|
|
#define OPTIMAL_TICKS_PER_SECOND_RATE 1000
|
|
|
|
class HardwareTimerBase;
|
|
|
|
class TimeManagement {
|
|
AK_MAKE_ETERNAL;
|
|
|
|
public:
|
|
TimeManagement();
|
|
static bool initialized();
|
|
static void initialize(u32 cpu);
|
|
static TimeManagement& the();
|
|
|
|
timespec epoch_time() const;
|
|
void set_epoch_time(timespec);
|
|
time_t seconds_since_boot() const;
|
|
time_t ticks_per_second() const;
|
|
time_t ticks_this_second() const;
|
|
time_t boot_time() const;
|
|
|
|
bool is_system_timer(const HardwareTimerBase&) const;
|
|
|
|
static void update_time(const RegisterState&);
|
|
void increment_time_since_boot(const RegisterState&);
|
|
|
|
static bool is_hpet_periodic_mode_allowed();
|
|
|
|
static timeval now_as_timeval();
|
|
|
|
timespec remaining_epoch_time_adjustment() const { return m_remaining_epoch_time_adjustment; }
|
|
void set_remaining_epoch_time_adjustment(const timespec& adjustment) { m_remaining_epoch_time_adjustment = adjustment; }
|
|
|
|
private:
|
|
bool probe_and_set_legacy_hardware_timers();
|
|
bool probe_and_set_non_legacy_hardware_timers();
|
|
Vector<HardwareTimerBase*> scan_and_initialize_periodic_timers();
|
|
Vector<HardwareTimerBase*> scan_for_non_periodic_timers();
|
|
NonnullRefPtrVector<HardwareTimerBase> m_hardware_timers;
|
|
void set_system_timer(HardwareTimerBase&);
|
|
|
|
u32 m_ticks_this_second { 0 };
|
|
u32 m_seconds_since_boot { 0 };
|
|
timespec m_epoch_time { 0, 0 };
|
|
timespec m_remaining_epoch_time_adjustment { 0, 0 };
|
|
RefPtr<HardwareTimerBase> m_system_timer;
|
|
RefPtr<HardwareTimerBase> m_time_keeper_timer;
|
|
};
|
|
|
|
}
|