mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-23 09:51:57 -05:00
Kernel: Make CLOCK_MONOTONIC respect the system tick frequency
The time returned by sys$clock_gettime() was not aligned with the delay calculations in sys$clock_nanosleep(). This patch fixes that by taking the system's ticks_per_second value into account in both functions. This patch also removes the need for Thread::sleep_until() and uses Thread::sleep() for both absolute and relative sleeps. This was causing the nesalizer emulator port to sleep for a negative amount of time at the end of each frame, making it run way too fast.
This commit is contained in:
parent
e07d14f4d9
commit
94ff04b536
3 changed files with 18 additions and 27 deletions
|
@ -37,10 +37,13 @@ int Process::sys$clock_gettime(clockid_t clock_id, Userspace<timespec*> user_ts)
|
|||
timespec ts = {};
|
||||
|
||||
switch (clock_id) {
|
||||
case CLOCK_MONOTONIC:
|
||||
ts.tv_sec = TimeManagement::the().seconds_since_boot();
|
||||
ts.tv_nsec = TimeManagement::the().ticks_this_second() * 1000000;
|
||||
case CLOCK_MONOTONIC: {
|
||||
auto ticks_per_second = TimeManagement::the().ticks_per_second();
|
||||
auto uptime = g_uptime;
|
||||
ts.tv_sec = uptime / ticks_per_second;
|
||||
ts.tv_nsec = (1000000000 * (uptime % ticks_per_second)) / ticks_per_second;
|
||||
break;
|
||||
}
|
||||
case CLOCK_REALTIME:
|
||||
ts = TimeManagement::the().epoch_time();
|
||||
break;
|
||||
|
@ -88,26 +91,24 @@ int Process::sys$clock_nanosleep(Userspace<const Syscall::SC_clock_nanosleep_par
|
|||
|
||||
bool is_absolute = params.flags & TIMER_ABSTIME;
|
||||
|
||||
auto ticks_per_second = TimeManagement::the().ticks_per_second();
|
||||
|
||||
switch (params.clock_id) {
|
||||
case CLOCK_MONOTONIC: {
|
||||
u64 wakeup_time;
|
||||
if (is_absolute) {
|
||||
u64 time_to_wake = (requested_sleep.tv_sec * 1000 + requested_sleep.tv_nsec / 1000000);
|
||||
wakeup_time = Thread::current()->sleep_until(time_to_wake);
|
||||
} else {
|
||||
u64 ticks_to_sleep = requested_sleep.tv_sec * TimeManagement::the().ticks_per_second();
|
||||
ticks_to_sleep += requested_sleep.tv_nsec * TimeManagement::the().ticks_per_second() / 1000000000;
|
||||
if (!ticks_to_sleep)
|
||||
return 0;
|
||||
wakeup_time = Thread::current()->sleep(ticks_to_sleep);
|
||||
}
|
||||
u64 ticks_to_sleep = requested_sleep.tv_sec * ticks_per_second;
|
||||
ticks_to_sleep += (requested_sleep.tv_nsec * ticks_per_second) / 1000000000;
|
||||
if (is_absolute)
|
||||
ticks_to_sleep -= g_uptime;
|
||||
if (!ticks_to_sleep)
|
||||
return 0;
|
||||
u64 wakeup_time = Thread::current()->sleep(ticks_to_sleep);
|
||||
if (wakeup_time > g_uptime) {
|
||||
u64 ticks_left = wakeup_time - g_uptime;
|
||||
if (!is_absolute && params.remaining_sleep) {
|
||||
timespec remaining_sleep = {};
|
||||
remaining_sleep.tv_sec = ticks_left / TimeManagement::the().ticks_per_second();
|
||||
ticks_left -= remaining_sleep.tv_sec * TimeManagement::the().ticks_per_second();
|
||||
remaining_sleep.tv_nsec = ticks_left * 1000000000 / TimeManagement::the().ticks_per_second();
|
||||
remaining_sleep.tv_sec = ticks_left / ticks_per_second;
|
||||
ticks_left -= remaining_sleep.tv_sec * ticks_per_second;
|
||||
remaining_sleep.tv_nsec = (ticks_left * 1000000000) / ticks_per_second;
|
||||
if (!copy_to_user(params.remaining_sleep, &remaining_sleep))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
|
|
@ -258,15 +258,6 @@ u64 Thread::sleep(u64 ticks)
|
|||
return wakeup_time;
|
||||
}
|
||||
|
||||
u64 Thread::sleep_until(u64 wakeup_time)
|
||||
{
|
||||
ASSERT(state() == Thread::Running);
|
||||
auto ret = Thread::current()->block<Thread::SleepBlocker>(nullptr, wakeup_time);
|
||||
if (wakeup_time > g_uptime)
|
||||
ASSERT(ret.was_interrupted());
|
||||
return wakeup_time;
|
||||
}
|
||||
|
||||
const char* Thread::state_string() const
|
||||
{
|
||||
switch (state()) {
|
||||
|
|
|
@ -377,7 +377,6 @@ public:
|
|||
size_t thread_specific_region_size() const { return m_thread_specific_region_size; }
|
||||
|
||||
u64 sleep(u64 ticks);
|
||||
u64 sleep_until(u64 wakeup_time);
|
||||
|
||||
class BlockResult {
|
||||
public:
|
||||
|
|
Loading…
Add table
Reference in a new issue