From eb1d273218e5df582c7f550aaaea291fcbd0aec3 Mon Sep 17 00:00:00 2001 From: Mohamed Hamza Date: Sat, 26 Oct 2019 11:08:29 +0200 Subject: [PATCH] add time tracking interface --- kernel/arch/i386/include/core/platform.h | 2 +- kernel/arch/i386/platform/misc/pit.c | 4 --- kernel/arch/i386/platform/pc/init.c | 3 -- kernel/arch/i386/sys/sched.c | 55 ++++++++++++++++++++++++++------ kernel/fs/procfs/procfs.c | 4 +-- kernel/include/core/arch.h | 6 ++-- kernel/include/core/system.h | 1 + 7 files changed, 54 insertions(+), 21 deletions(-) diff --git a/kernel/arch/i386/include/core/platform.h b/kernel/arch/i386/include/core/platform.h index 902b19e..874c351 100644 --- a/kernel/arch/i386/include/core/platform.h +++ b/kernel/arch/i386/include/core/platform.h @@ -2,6 +2,6 @@ #define _X86_CORE_PLATFORM_H int platform_init(void); -void platform_timer_setup(size_t period_ns, void (*handler)()); +uint32_t platform_timer_setup(size_t period_ns, void (*handler)()); #endif /* ! _X86_CORE_PLATFORM_H */ diff --git a/kernel/arch/i386/platform/misc/pit.c b/kernel/arch/i386/platform/misc/pit.c index 269247a..58532ae 100644 --- a/kernel/arch/i386/platform/misc/pit.c +++ b/kernel/arch/i386/platform/misc/pit.c @@ -56,10 +56,6 @@ uint32_t x86_pit_period_set(uint32_t period_ns) if (!kargs_get("i8254.div", &arg_div)) { div = atou32(arg_div); } else { - //uint32_t period_ms = period_ns / 1000UL; - //uint32_t freq = 1000000000UL/period_ms; - //printk("freq = %d Hz\n", freq); - //div = FBASE/freq; div = period_ns/838UL; } diff --git a/kernel/arch/i386/platform/pc/init.c b/kernel/arch/i386/platform/pc/init.c index 244ffca..28e6d79 100644 --- a/kernel/arch/i386/platform/pc/init.c +++ b/kernel/arch/i386/platform/pc/init.c @@ -78,10 +78,7 @@ static int x86_pc_cmos_init(void) uint32_t platform_timer_setup(size_t period_ns, void (*handler)()) { uint32_t period = x86_pit_period_set(period_ns); - //hpet_timer_setup(1, handler); - x86_irq_handler_install(PIT_IRQ, handler); - return period; } diff --git a/kernel/arch/i386/sys/sched.c b/kernel/arch/i386/sys/sched.c index 5988432..5bd4df5 100644 --- a/kernel/arch/i386/sys/sched.c +++ b/kernel/arch/i386/sys/sched.c @@ -1,23 +1,61 @@ #include #include +#include #include #include #include #include "sys.h" -uint32_t timer_freq = 62; -uint32_t timer_ticks = 0; -uint32_t timer_sub_ticks = 0; +static uint32_t timer_period = 0; +static uint64_t timer_ticks = 0; + +uint64_t arch_rtime_ns(void) +{ + return timer_ticks * timer_period; +} + +uint64_t arch_rtime_us(void) +{ + return timer_ticks * timer_period / 1000ULL; +} + +uint64_t arch_rtime_ms(void) +{ + return timer_ticks * timer_period / 1000000ULL; +} + +static uint64_t first_measured_time = 0; static void x86_sched_handler(struct x86_regs *r) { - ++timer_sub_ticks; - if (timer_sub_ticks == timer_freq) { - timer_ticks++; - timer_sub_ticks = 0; + /* we check time every 2^16 ticks */ + if (!(timer_ticks & 0xFFFF)) { + if (!timer_ticks) { + struct timespec ts = {0}; + gettime(&ts); + first_measured_time = ts.tv_sec; + } else { + struct timespec ts = {0}; + gettime(&ts); + + uint64_t measured_time = ts.tv_sec - first_measured_time; + uint64_t calculated_time = arch_rtime_ms() / 1000; + + int32_t delta = calculated_time - measured_time; + + if (ABS(delta) > 1) { + printk("warning: calculated time differs from measured time by %c%d seconds\n", delta < 0? '-' : '+', ABS(delta)); + printk("calculated time: %d seconds\n", calculated_time); + printk("measured time: %d seconds\n", measured_time); + + /* TODO: attempt to correct time */ + } + } } + ++timer_ticks; + if (!kidle) { struct x86_thread *arch = (struct x86_thread *) curthread->arch; @@ -53,7 +91,7 @@ static void x86_sched_handler(struct x86_regs *r) void arch_sched_init(void) { - platform_timer_setup(20000, x86_sched_handler); + timer_period = platform_timer_setup(2000000, x86_sched_handler); } static void __arch_idle(void) @@ -97,4 +135,3 @@ void arch_sleep(void) extern void x86_sleep(void); x86_sleep(); } - diff --git a/kernel/fs/procfs/procfs.c b/kernel/fs/procfs/procfs.c index b275efc..6f30931 100644 --- a/kernel/fs/procfs/procfs.c +++ b/kernel/fs/procfs/procfs.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -109,8 +110,7 @@ static ssize_t procfs_uptime(off_t off, size_t size, char *buf) { char uptime_buf[64]; - extern uint32_t timer_ticks; - int sz = snprintf(uptime_buf, 64, "%d\n", timer_ticks); + int sz = snprintf(uptime_buf, 64, "%ld\n", arch_rtime_ms() / 1000); if (off < sz) { ssize_t ret = MIN(size, (size_t)(sz - off)); diff --git a/kernel/include/core/arch.h b/kernel/include/core/arch.h index 6190995..65398a9 100644 --- a/kernel/include/core/arch.h +++ b/kernel/include/core/arch.h @@ -6,8 +6,6 @@ /* arch/ARCH/sys/proc.c */ void arch_proc_init(struct proc *proc); -void arch_proc_spawn(struct proc *init); -void arch_proc_switch(struct proc *proc) __attribute__((noreturn)); void arch_proc_kill(struct proc *proc); void arch_init_execve(struct proc *proc, int argc, char * const _argp[], int envc, char * const _envp[]); void arch_sleep(void); @@ -45,6 +43,10 @@ void arch_disable_interrupts(void); void arch_reboot(void); +uint64_t arch_rtime_ns(void); +uint64_t arch_rtime_us(void); +uint64_t arch_rtime_ms(void); + int arch_time_get(struct timespec *ts); void arch_stack_trace(void); diff --git a/kernel/include/core/system.h b/kernel/include/core/system.h index 72f3efd..3841f5b 100644 --- a/kernel/include/core/system.h +++ b/kernel/include/core/system.h @@ -4,6 +4,7 @@ #define _BV(b) (1 << (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define ABS(a) ((a) < 0? -(a) : (a)) #define MEMBER_SIZE(type, member) (sizeof(((type *)0)->member)) -- 2.11.4.GIT