aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2022-04-21 19:38:45 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2022-04-21 19:38:45 +0300
commit1a5248bb177242a34fd51efadb4af941853d5e35 (patch)
tree669565c49217876611565c42867dcf0126e08933
parent7967a9ab13214543041e4408086668b4db8d3e62 (diff)
downloadkmi-1a5248bb177242a34fd51efadb4af941853d5e35.tar.gz
kmi-1a5248bb177242a34fd51efadb4af941853d5e35.zip
use uint64_t for timer ticks
+ GCC seems to provide this even on 32bit platforms, though I should really check.
-rw-r--r--arch/riscv64/kernel/timer.c2
-rw-r--r--common/timer.c22
-rw-r--r--common/uapi/dispatch.c3
-rw-r--r--common/uapi/timers.c29
-rw-r--r--include/apos/syscalls.h3
-rw-r--r--include/apos/timer.h5
-rw-r--r--include/apos/uapi.h3
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 <arch/timer.h>
-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 <apos/timer.h>
#include <apos/uapi.h>
-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 <apos/types.h>
-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 */