From 1a5248bb177242a34fd51efadb4af941853d5e35 Mon Sep 17 00:00:00 2001 From: Kimplul Date: Thu, 21 Apr 2022 19:38:45 +0300 Subject: use uint64_t for timer ticks + GCC seems to provide this even on 32bit platforms, though I should really check. --- arch/riscv64/kernel/timer.c | 2 +- common/timer.c | 22 ++++++++++++++++------ common/uapi/dispatch.c | 3 ++- common/uapi/timers.c | 29 ++++++++++++++++++++++++----- include/apos/syscalls.h | 3 ++- include/apos/timer.h | 5 ++++- include/apos/uapi.h | 3 ++- 7 files changed, 51 insertions(+), 16 deletions(-) diff --git a/arch/riscv64/kernel/timer.c b/arch/riscv64/kernel/timer.c index cad811d..b6d828e 100644 --- a/arch/riscv64/kernel/timer.c +++ b/arch/riscv64/kernel/timer.c @@ -1,6 +1,6 @@ #include -ticks_t stat_timer() +ticks_t stat_timer(const void *fdt) { /* TODO: read from fdt */ return 0; diff --git a/common/timer.c b/common/timer.c index b48e455..f35c983 100644 --- a/common/timer.c +++ b/common/timer.c @@ -26,9 +26,9 @@ static struct sp_root *__cpu_timers() return &cpu_timers[cpu_id()]; } -void init_timer() +void init_timer(const void *fdt) { - ticks_per_sec = stat_timer(); + ticks_per_sec = stat_timer(fdt); init_nodes(&node_root, sizeof(struct timer_node)); } @@ -39,8 +39,17 @@ static id_t __insert_timer(struct timer_node *ti) enum sp_dir d; while (n) { struct timer_node *t = container_of(n, struct timer_node, sp_n); - if (ti->timer.cid == t->timer.cid) - ti->timer.cid--; + if (ti->timer.cid == t->timer.cid) { + /* if there's an identical ID, we'll just increment our + * ID until we get and ID that doesn't exist yet. There + * is a very small possibility that this will set a + * timer that's very slightly ahead of some other timer + * to be handled after the one that's very close, but + * the timescales that we're dealing with are probably + * tiny enough that this won't matter, even if it + * occurs. */ + ti->timer.cid++; + } p = n; @@ -66,6 +75,7 @@ static id_t __new_timer(id_t tid, ticks_t ticks) { struct timer_node *ti = (struct timer_node *)get_node(&node_root); ti->timer.ticks = ticks; + /* preliminary ID, may change after actual insertion */ ti->timer.cid = ticks; ti->timer.tid = tid; return __insert_timer(ti); @@ -117,8 +127,8 @@ void remove_timer(struct timer *t) sp_remove(&sp_root(__cpu_timers()), n); } -/* TODO: does this overflow too early? */ ticks_t nsecs_to_ticks(tunit_t nsecs) { - return (nsecs * ticks_per_sec) / 1000000000; + ticks_t t = (nsecs * ticks_per_sec) / 1000000000; + return t == 0 ? 1 : t; } diff --git a/common/uapi/dispatch.c b/common/uapi/dispatch.c index 3b03c43..e6c334a 100644 --- a/common/uapi/dispatch.c +++ b/common/uapi/dispatch.c @@ -8,7 +8,8 @@ static const sys_t syscall_table[] = { [SYS_FREE_MEM] = sys_free_mem, /* timers */ - [SYS_REQ_TIMER] = sys_req_timer, + [SYS_REQ_REL_TIMER] = sys_req_rel_timer, + [SYS_REQ_ABS_TIMER] = sys_req_abs_timer, [SYS_FREE_TIMER] = sys_free_timer, /* ipc */ diff --git a/common/uapi/timers.c b/common/uapi/timers.c index 1dfc8bf..66f6533 100644 --- a/common/uapi/timers.c +++ b/common/uapi/timers.c @@ -1,13 +1,32 @@ +#include #include -SYSCALL_DEFINE1(req_timer)(vm_t ticks) +static ticks_t scaled_ticks(vm_t ticks, vm_t repeat) { - /* TODO */ - return 0; +#if __WORDSIZE == 64 + UNUSED(repeat); + return ticks; +#else + return ((ticks_t)ticks << 32) + repeat; +#endif +} + +SYSCALL_DEFINE2(req_rel_timer)(vm_t ticks, vm_t repeat) +{ + return new_rel_timer(cur_tcb()->tid, scaled_ticks(ticks, repeat)); +} + +SYSCALL_DEFINE2(req_abs_timer)(vm_t ticks, vm_t repeat) +{ + return new_abs_timer(cur_tcb()->tid, scaled_ticks(ticks, repeat)); } SYSCALL_DEFINE1(free_timer)(vm_t cid) { - /* TODO */ - return 0; + struct timer *timer = find_timer(cid); + if (!timer) + return ERR_NF; + + remove_timer(timer); + return OK; } diff --git a/include/apos/syscalls.h b/include/apos/syscalls.h index d9df89b..ed18872 100644 --- a/include/apos/syscalls.h +++ b/include/apos/syscalls.h @@ -11,7 +11,8 @@ enum { SYS_FREE_MEM, /* free memory */ /* timers */ - SYS_REQ_TIMER, + SYS_REQ_REL_TIMER, + SYS_REQ_ABS_TIMER, SYS_FREE_TIMER, /* IPC */ diff --git a/include/apos/timer.h b/include/apos/timer.h index ea5bd03..e68009a 100644 --- a/include/apos/timer.h +++ b/include/apos/timer.h @@ -3,7 +3,10 @@ #include -typedef size_t ticks_t; +/* GCC will compile uint64_t even on 32bit platforms, just with some runtime + * overhead, should be fine. This will allow us to have a reasonable time range + * even with nanosecond clocks. (138 years with ~4.2 Hz clock) */ +typedef uint64_t ticks_t; /* whichever time unit we're dealing with */ typedef size_t tunit_t; diff --git a/include/apos/uapi.h b/include/apos/uapi.h index fb7dff7..18f086c 100644 --- a/include/apos/uapi.h +++ b/include/apos/uapi.h @@ -64,7 +64,8 @@ SYSCALL_DECLARE(req_sharedmem); SYSCALL_DECLARE(free_mem); /* timers */ -SYSCALL_DECLARE(req_timer); +SYSCALL_DECLARE(req_rel_timer); +SYSCALL_DECLARE(req_abs_timer); SYSCALL_DECLARE(free_timer); /* ipc */ -- cgit v1.3