mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 04:37:44 +00:00
Kernel: Improve time keeping and dramatically reduce interrupt load
This implements a number of changes related to time: * If a HPET is present, it is now used only as a system timer, unless the Local APIC timer is used (in which case the HPET timer will not trigger any interrupts at all). * If a HPET is present, the current time can now be as accurate as the chip can be, independently from the system timer. We now query the HPET main counter for the current time in CPU #0's system timer interrupt, and use that as a base line. If a high precision time is queried, that base line is used in combination with quering the HPET timer directly, which should give a much more accurate time stamp at the expense of more overhead. For faster time stamps, the more coarse value based on the last interrupt will be returned. This also means that any missed interrupts should not cause the time to drift. * The default system interrupt rate is reduced to about 250 per second. * Fix calculation of Thread CPU usage by using the amount of ticks they used rather than the number of times a context switch happened. * Implement CLOCK_REALTIME_COARSE and CLOCK_MONOTONIC_COARSE and use it for most cases where precise timestamps are not needed.
This commit is contained in:
parent
a3fdf5148b
commit
5f51d85184
32 changed files with 318 additions and 190 deletions
|
@ -34,10 +34,15 @@
|
|||
|
||||
namespace Kernel {
|
||||
|
||||
#define OPTIMAL_TICKS_PER_SECOND_RATE 1000
|
||||
#define OPTIMAL_TICKS_PER_SECOND_RATE 250
|
||||
|
||||
class HardwareTimerBase;
|
||||
|
||||
enum class TimePrecision {
|
||||
Coarse = 0,
|
||||
Precise
|
||||
};
|
||||
|
||||
class TimeManagement {
|
||||
AK_MAKE_ETERNAL;
|
||||
|
||||
|
@ -47,12 +52,15 @@ public:
|
|||
static void initialize(u32 cpu);
|
||||
static TimeManagement& the();
|
||||
|
||||
static timespec ticks_to_time(u64 ticks, time_t ticks_per_second);
|
||||
static u64 time_to_ticks(const timespec& tspec, time_t ticks_per_second);
|
||||
|
||||
KResultOr<timespec> current_time(clockid_t clock_id) const;
|
||||
timespec monotonic_time() const;
|
||||
timespec epoch_time() const;
|
||||
static bool is_valid_clock_id(clockid_t);
|
||||
KResultOr<timespec> current_time(clockid_t) const;
|
||||
timespec monotonic_time(TimePrecision = TimePrecision::Coarse) const;
|
||||
timespec monotonic_time_raw() const
|
||||
{
|
||||
// TODO: implement
|
||||
return monotonic_time(TimePrecision::Precise);
|
||||
}
|
||||
timespec epoch_time(TimePrecision = TimePrecision::Precise) const;
|
||||
void set_epoch_time(timespec);
|
||||
time_t ticks_per_second() const;
|
||||
time_t boot_time() const;
|
||||
|
@ -60,12 +68,13 @@ public:
|
|||
bool is_system_timer(const HardwareTimerBase&) const;
|
||||
|
||||
static void update_time(const RegisterState&);
|
||||
void increment_time_since_boot(const RegisterState&);
|
||||
static void update_time_hpet(const RegisterState&);
|
||||
void increment_time_since_boot_hpet();
|
||||
void increment_time_since_boot();
|
||||
|
||||
static bool is_hpet_periodic_mode_allowed();
|
||||
|
||||
u64 uptime_ms() const;
|
||||
u64 monotonic_ticks() const;
|
||||
static timeval now_as_timeval();
|
||||
|
||||
timespec remaining_epoch_time_adjustment() const { return m_remaining_epoch_time_adjustment; }
|
||||
|
@ -78,16 +87,19 @@ private:
|
|||
Vector<HardwareTimerBase*> scan_for_non_periodic_timers();
|
||||
NonnullRefPtrVector<HardwareTimerBase> m_hardware_timers;
|
||||
void set_system_timer(HardwareTimerBase&);
|
||||
static void timer_tick(const RegisterState&);
|
||||
static void system_timer_tick(const RegisterState&);
|
||||
|
||||
// Variables between m_update1 and m_update2 are synchronized
|
||||
Atomic<u32> m_update1 { 0 };
|
||||
u32 m_ticks_this_second { 0 };
|
||||
u32 m_seconds_since_boot { 0 };
|
||||
u64 m_seconds_since_boot { 0 };
|
||||
timespec m_epoch_time { 0, 0 };
|
||||
timespec m_remaining_epoch_time_adjustment { 0, 0 };
|
||||
Atomic<u32> m_update2 { 0 };
|
||||
|
||||
u32 m_time_ticks_per_second { 0 }; // may be different from interrupts/second (e.g. hpet)
|
||||
bool m_can_query_precise_time { false };
|
||||
|
||||
RefPtr<HardwareTimerBase> m_system_timer;
|
||||
RefPtr<HardwareTimerBase> m_time_keeper_timer;
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue