diff options
author | dzwdz | 2022-08-04 15:58:54 +0200 |
---|---|---|
committer | dzwdz | 2022-08-04 15:58:54 +0200 |
commit | 81a58004d51547d074b4218f906b0b95f2b2c5dc (patch) | |
tree | 4301047fc342e165bc5a043a04b5fed44b8e8084 /src/kernel/arch/amd64/time.c | |
parent | 4a844820866094ff7d57435a16b7c23a9126814d (diff) |
syscalls: add _syscall_sleep()
Diffstat (limited to 'src/kernel/arch/amd64/time.c')
-rw-r--r-- | src/kernel/arch/amd64/time.c | 50 |
1 files changed, 50 insertions, 0 deletions
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 <kernel/arch/amd64/time.h> +#include <kernel/panic.h> +#include <kernel/proc.h> + +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(); +} |