From 02025985a1ac6b460f417e21d0ddc53a65baa0fe Mon Sep 17 00:00:00 2001 From: hinus Date: Tue, 6 Jul 2021 21:30:20 +0800 Subject: [PATCH] Title: Support timer in kernel. Issue: https://gitee.com/hinus/linux_kernel_011/issues/I3Z826 Description: Support timer in kernel. --- kernel/blk_drv/hd.c | 3 +++ kernel/main.c | 1 - kernel/sched.c | 57 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/kernel/blk_drv/hd.c b/kernel/blk_drv/hd.c index edfdb08..23b40ae 100644 --- a/kernel/blk_drv/hd.c +++ b/kernel/blk_drv/hd.c @@ -93,6 +93,7 @@ void hd_identity() { printf("HD size: %dMB\n", sectors * 512 / 1024 / 1024); } +extern void add_timer(long jiffies, void (*fn)()); int sys_setup(void * BIOS) { static int callable = 1; @@ -171,6 +172,8 @@ int sys_setup(void * BIOS) { } } + add_timer(300, test_b); + return 0; } diff --git a/kernel/main.c b/kernel/main.c index 4f6bb0e..21564b6 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -80,7 +80,6 @@ void main(void) move_to_user_mode(); if (!fork()) { - test_b(); init(); } diff --git a/kernel/sched.c b/kernel/sched.c index 9ad225a..4541b9f 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -107,7 +107,64 @@ void wake_up(struct task_struct **p) { } } +#define TIME_REQUESTS 64 + +static struct timer_list { + long jiffies; + void (*fn)(); + struct timer_list * next; +} timer_list[TIME_REQUESTS], * next_timer = NULL; + +void add_timer(long jiffies, void (*fn)()) { + struct timer_list * p; + if (!fn) + return; + cli(); + + if (jiffies <= 0) + (fn)(); + else { + for (p = timer_list ; p < timer_list + TIME_REQUESTS ; p++) + if (!p->fn) + break; + if (p >= timer_list + TIME_REQUESTS) + printk("No more time requests free"); + + p->fn = fn; + p->jiffies = jiffies; + p->next = next_timer; + next_timer = p; + + if (p->next && p->jiffies < p->next->jiffies) { + p->next->jiffies -= p->jiffies; + } + + while (p->next && p->next->jiffies < p->jiffies) { + p->jiffies -= p->next->jiffies; + fn = p->fn; + p->fn = p->next->fn; + p->next->fn = fn; + jiffies = p->jiffies; + p->jiffies = p->next->jiffies; + p->next->jiffies = jiffies; + p = p->next; + } + } + sti(); +} + void do_timer(long cpl) { + if (next_timer) { + next_timer->jiffies--; + while (next_timer && next_timer->jiffies <= 0) { + void (*fn)(void); + fn = next_timer->fn; + next_timer->fn = NULL; + next_timer = next_timer->next; + (fn)(); + } + } + if ((--current->counter)>0) return; current->counter=0; if (!cpl) return; -- Gitee