diff options
author | Tom <tomut@yahoo.com> | 2020-12-03 22:12:50 -0700 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-12-21 18:26:12 +0100 |
commit | 5f51d851840d889520c21cc4359d6db59d83ff06 (patch) | |
tree | 2edf3477ba3500c770353461480500c8cda01efd /Kernel/Syscalls/clock.cpp | |
parent | a3fdf5148bb8f7760eea863eb13cb9264da054a6 (diff) | |
download | serenity-5f51d851840d889520c21cc4359d6db59d83ff06.zip |
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.
Diffstat (limited to 'Kernel/Syscalls/clock.cpp')
-rw-r--r-- | Kernel/Syscalls/clock.cpp | 30 |
1 files changed, 13 insertions, 17 deletions
diff --git a/Kernel/Syscalls/clock.cpp b/Kernel/Syscalls/clock.cpp index a48c2df98a..c28552953d 100644 --- a/Kernel/Syscalls/clock.cpp +++ b/Kernel/Syscalls/clock.cpp @@ -78,25 +78,21 @@ int Process::sys$clock_nanosleep(Userspace<const Syscall::SC_clock_nanosleep_par bool is_absolute = params.flags & TIMER_ABSTIME; - switch (params.clock_id) { - case CLOCK_MONOTONIC: - case CLOCK_REALTIME: { - bool was_interrupted; - if (is_absolute) { - was_interrupted = Thread::current()->sleep_until(params.clock_id, requested_sleep).was_interrupted(); - } else { - timespec remaining_sleep; - was_interrupted = Thread::current()->sleep(params.clock_id, requested_sleep, &remaining_sleep).was_interrupted(); - if (was_interrupted && params.remaining_sleep && !copy_to_user(params.remaining_sleep, &remaining_sleep)) - return -EFAULT; - } - if (was_interrupted) - return -EINTR; - return 0; - } - default: + if (!TimeManagement::is_valid_clock_id(params.clock_id)) return -EINVAL; + + bool was_interrupted; + if (is_absolute) { + was_interrupted = Thread::current()->sleep_until(params.clock_id, requested_sleep).was_interrupted(); + } else { + timespec remaining_sleep; + was_interrupted = Thread::current()->sleep(params.clock_id, requested_sleep, &remaining_sleep).was_interrupted(); + if (was_interrupted && params.remaining_sleep && !copy_to_user(params.remaining_sleep, &remaining_sleep)) + return -EFAULT; } + if (was_interrupted) + return -EINTR; + return 0; } int Process::sys$adjtime(Userspace<const timeval*> user_delta, Userspace<timeval*> user_old_delta) |