kernel: Change the timer subsystem to use timespecs natively
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
d2334a67dd
commit
8bcec00a9d
@ -35,7 +35,9 @@ static void log_serial(LogLevel level, const char* format, va_list origin)
|
||||
"\x1b[0m ",
|
||||
ansi_color_codes_per_log_level[(int)level], log_level_letters[(int)level]);
|
||||
|
||||
Serial::printf("%4zu.%.3zu ", Timer::ticks(), Timer::ticks_ms() - (Timer::ticks() * 1000));
|
||||
auto* time = Timer::monotonic_clock();
|
||||
|
||||
Serial::printf("%4zu.%.3zu ", time->tv_sec, time->tv_nsec / 1'000'000);
|
||||
|
||||
// NOTE: We do this manually because of a lack of vprintf() in both Serial and TextConsole.
|
||||
cstyle_format(
|
||||
|
@ -4,10 +4,8 @@
|
||||
#include "boot/bootboot.h"
|
||||
#include <luna/TypeTraits.h>
|
||||
|
||||
// NOTE: Storing these values as unsigned integers doesn't allow for pre-epoch times.
|
||||
// We are in 2023 anyway, not sure why anybody would want to set their computer's time to 1945.
|
||||
static u64 timer_ticks = 0;
|
||||
static u64 boot_timestamp;
|
||||
static struct timespec s_monotonic_clock = { 0, 0 };
|
||||
static struct timespec s_realtime_clock;
|
||||
|
||||
static inline constexpr bool isleap(u32 year)
|
||||
{
|
||||
@ -56,84 +54,33 @@ extern const BOOTBOOT bootboot;
|
||||
|
||||
namespace Timer
|
||||
{
|
||||
static struct timespec s_interval = { .tv_sec = 0, .tv_nsec = ARCH_TIMER_RESOLUTION * 1000 };
|
||||
|
||||
void tick()
|
||||
{
|
||||
timer_ticks += ARCH_TIMER_RESOLUTION;
|
||||
timespecadd(&s_monotonic_clock, &s_interval, &s_monotonic_clock);
|
||||
timespecadd(&s_realtime_clock, &s_interval, &s_realtime_clock);
|
||||
}
|
||||
|
||||
usize raw_ticks()
|
||||
struct timespec* monotonic_clock()
|
||||
{
|
||||
return timer_ticks;
|
||||
return &s_monotonic_clock;
|
||||
}
|
||||
|
||||
usize ticks()
|
||||
struct timespec* realtime_clock()
|
||||
{
|
||||
return ticks_us() / US_PER_SECOND;
|
||||
}
|
||||
|
||||
usize ticks_ms()
|
||||
{
|
||||
return timer_ticks / 1000;
|
||||
}
|
||||
|
||||
usize ticks_us()
|
||||
{
|
||||
return timer_ticks;
|
||||
}
|
||||
|
||||
usize ticks_ns()
|
||||
{
|
||||
return ticks_us() * 1000;
|
||||
}
|
||||
|
||||
usize boot()
|
||||
{
|
||||
return boot_timestamp / US_PER_SECOND;
|
||||
}
|
||||
|
||||
usize boot_ms()
|
||||
{
|
||||
return boot_timestamp / 1000;
|
||||
}
|
||||
|
||||
usize boot_us()
|
||||
{
|
||||
return boot_timestamp;
|
||||
}
|
||||
|
||||
usize boot_ns()
|
||||
{
|
||||
return boot_timestamp * 1000;
|
||||
}
|
||||
|
||||
usize clock()
|
||||
{
|
||||
return boot() + ticks();
|
||||
}
|
||||
|
||||
usize clock_ms()
|
||||
{
|
||||
return boot_ms() + ticks_ms();
|
||||
}
|
||||
|
||||
usize clock_us()
|
||||
{
|
||||
return boot_us() + ticks_us();
|
||||
}
|
||||
|
||||
usize clock_ns()
|
||||
{
|
||||
return boot_ns() + ticks_ns();
|
||||
return &s_realtime_clock;
|
||||
}
|
||||
|
||||
void init()
|
||||
{
|
||||
boot_timestamp = bootloader_time_to_unix(bootboot.datetime) * US_PER_SECOND;
|
||||
s_realtime_clock.tv_sec = bootloader_time_to_unix(bootboot.datetime);
|
||||
s_realtime_clock.tv_nsec = 0;
|
||||
arch_init();
|
||||
}
|
||||
}
|
||||
|
||||
bool should_invoke_scheduler()
|
||||
{
|
||||
return (timer_ticks % 1000) == 0;
|
||||
return (s_realtime_clock.tv_nsec % 1'000'000) == 0;
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#include <bits/timespec.h>
|
||||
#include <luna/Types.h>
|
||||
|
||||
#ifdef ARCH_X86_64
|
||||
@ -15,22 +16,9 @@ namespace Timer
|
||||
{
|
||||
void tick();
|
||||
|
||||
usize raw_ticks();
|
||||
struct timespec* monotonic_clock();
|
||||
|
||||
usize ticks();
|
||||
usize ticks_ms();
|
||||
usize ticks_us();
|
||||
usize ticks_ns();
|
||||
|
||||
usize boot();
|
||||
usize boot_ms();
|
||||
usize boot_us();
|
||||
usize boot_ns();
|
||||
|
||||
usize clock();
|
||||
usize clock_ms();
|
||||
usize clock_us();
|
||||
usize clock_ns();
|
||||
struct timespec* realtime_clock();
|
||||
|
||||
void arch_init();
|
||||
void init();
|
||||
|
@ -2,4 +2,5 @@
|
||||
#include <luna/Types.h>
|
||||
|
||||
// Every timer tick is equivalent to 250 microseconds.
|
||||
// FIXME: Change ARCH_TIMER_RESOLUTION to use nanoseconds.
|
||||
const usize ARCH_TIMER_RESOLUTION = 250;
|
||||
|
@ -12,19 +12,11 @@ Result<u64> sys_clock_gettime(Registers*, SyscallArgs args)
|
||||
switch (id)
|
||||
{
|
||||
case CLOCK_MONOTONIC: {
|
||||
usize ticks = Timer::ticks_ns();
|
||||
struct timespec kernel_ts;
|
||||
kernel_ts.tv_sec = (time_t)(ticks / NS_PER_SECOND);
|
||||
kernel_ts.tv_nsec = (long)(ticks % NS_PER_SECOND);
|
||||
if (!MemoryManager::copy_to_user_typed(ts, &kernel_ts)) return err(EFAULT);
|
||||
if (!MemoryManager::copy_to_user_typed(ts, Timer::monotonic_clock())) return err(EFAULT);
|
||||
break;
|
||||
}
|
||||
case CLOCK_REALTIME: {
|
||||
usize clock = Timer::clock_ns();
|
||||
struct timespec kernel_ts;
|
||||
kernel_ts.tv_sec = (time_t)(clock / NS_PER_SECOND);
|
||||
kernel_ts.tv_nsec = (long)(clock % NS_PER_SECOND);
|
||||
if (!MemoryManager::copy_to_user_typed(ts, &kernel_ts)) return err(EFAULT);
|
||||
if (!MemoryManager::copy_to_user_typed(ts, Timer::realtime_clock())) return err(EFAULT);
|
||||
break;
|
||||
}
|
||||
default: return err(EINVAL);
|
||||
|
@ -18,3 +18,19 @@ struct timeval
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(IN_MOON) || defined(_INCLUDE_TIMESPEC_MACROS)
|
||||
#ifndef _TIMESPEC_MACROS_INCLUDED
|
||||
#define _TIMESPEC_MACROS_INCLUDED
|
||||
#define timespecadd(a, b, res) \
|
||||
do { \
|
||||
(res)->tv_sec = (a)->tv_sec + (b)->tv_sec; \
|
||||
(res)->tv_nsec = (a)->tv_nsec + (b)->tv_nsec; \
|
||||
while ((res)->tv_nsec >= 1'000'000'000) \
|
||||
{ \
|
||||
(res)->tv_sec++; \
|
||||
(res)->tv_nsec -= 1'000'000'000; \
|
||||
} \
|
||||
} while (0);
|
||||
#endif
|
||||
#endif
|
||||
|
@ -3,6 +3,8 @@
|
||||
#ifndef _SYS_TIME_H
|
||||
#define _SYS_TIME_H
|
||||
|
||||
#define _INCLUDE_TIMESPEC_MACROS
|
||||
|
||||
#include <bits/attrs.h>
|
||||
#include <bits/timespec.h>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user