From 81a58004d51547d074b4218f906b0b95f2b2c5dc Mon Sep 17 00:00:00 2001 From: dzwdz Date: Thu, 4 Aug 2022 15:58:54 +0200 Subject: syscalls: add _syscall_sleep() --- src/kernel/arch/amd64/time.c | 50 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 src/kernel/arch/amd64/time.c (limited to 'src/kernel/arch/amd64/time.c') diff --git a/src/kernel/arch/amd64/time.c b/src/kernel/arch/amd64/time.c new file mode 100644 index 0000000..d6e53dd --- /dev/null +++ b/src/kernel/arch/amd64/time.c @@ -0,0 +1,50 @@ +#include +#include +#include + +static uint64_t uptime = 0, goal = ~0; +static struct process *scheduled = NULL; + +uint64_t uptime_ms(void) { return uptime; } + +static void update_goal(void) { + goal = scheduled ? scheduled->waits4timer.goal : ~(uint64_t)0; +} + +void pit_irq(void) { + // TODO inefficient - getting here executes a lot of code which could just be a few lines of asm + uptime++; + if (uptime < goal) return; + + struct process *p = scheduled; + assert(p); + scheduled = p->waits4timer.next; + process_transition(p, PS_RUNNING); + update_goal(); +} + +void timer_schedule(struct process *p, uint64_t time) { + process_transition(p, PS_WAITS4TIMER); + p->waits4timer.goal = time; + + struct process **slot = &scheduled; + while (*slot && (*slot)->waits4timer.goal <= time) { + assert((*slot)->state == PS_WAITS4TIMER); + slot = &(*slot)->waits4timer.next; + } + p->waits4timer.next = *slot; + *slot = p; + update_goal(); +} + +void timer_deschedule(struct process *p) { + assert(p->state == PS_WAITS4TIMER); + + struct process **slot = &scheduled; + while (*slot && *slot != p) + slot = &(*slot)->waits4timer.next; + assert(*slot); + *slot = p->waits4timer.next; + + update_goal(); +} -- cgit v1.2.3