--- /dev/null
+/*
+ * ------------------------------------------------------------------------
+ * File Name: clock.h
+ * Author: Zhao Yanbai
+ * 2026-08-13 18:13:37 Thursday CST
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+
+#pragma once
+
+extern volatile uint64_t jiffies;
\ No newline at end of file
extern void load_cr3(task_t* tsk);
extern list_head_t all_tasks;
-extern list_head_t delay_tasks;
vm_area_t* vma_list;
- list_head_t list; // 所有进程串成一个链表
-
+ list_head_t list; // 所有进程串成一个链表
list_head_t ready_list; // 就绪队列
-
list_head_t waitq_list;
- list_head_t pend; // 某些条件串成一个链表
-
- // list_head_t wait;
-
uint32_t sched_cnt; // 被调度换上CPU的次数
uint32_t sched_keep_cnt; // 时间片到了,但是没有被换出,又重新执行的次数
- uint64_t delay_jiffies; // debug only
-
uint64_t magic; // 栈溢出标志
};
void task_set_ready(task_t* t);
void task_set_wait(task_t* t);
+void task_init_lists(task_t* t);
+
#endif // ASM
#endif //_TASK_H
--- /dev/null
+/*
+ * ------------------------------------------------------------------------
+ * File Name: timer.h
+ * Author: Zhao Yanbai
+ * 2026-08-13 16:02:25 Thursday CST
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+
+#pragma once
+
+#include <list.h>
+#include <types.h>
+
+typedef struct timer timer_t;
+
+typedef void (*timer_callback_t)(void* arg);
+
+struct timer {
+ list_head_t list;
+ uint64_t expires;
+
+ timer_callback_t callback;
+ void* callback_arg;
+};
+
+void timer_init(timer_t* timer, uint64_t expires, timer_callback_t callback, void* callback_arg);
+
+void timer_add(timer_t* timer);
+
+void timer_del(timer_t* timer);
+
+void timer_run_expired_timers();
\ No newline at end of file
#include <printk.h>
#include <sched.h>
#include <system.h>
+#include <timer.h>
volatile uint64_t jiffies = 0; // TODO uint64: undefined reference to `__umoddi3'
-unsigned int sys_clock() {
- return jiffies;
-}
-
void clk_bh_handler(void* arg);
extern volatile bool enable_clock_irq_delay;
// 开中断执行这个函数
// 后续放到一个内核任务中去做,需要先把禁止内核抢占做了
-const char* task_state(unsigned int state);
void clk_bh_handler(void* arg) {
- task_t* p = 0;
- list_head_t* t = 0;
- list_head_t* pos = 0;
- list_for_each_safe(pos, t, &delay_tasks) {
- p = list_entry(pos, task_t, pend);
- // printk("%s state: %s\n", p->name, task_state(p->state));
- assert(p->state == TASK_WAIT);
- assert(p->delay_jiffies != 0);
- if (p->delay_jiffies > 0 && jiffies > p->delay_jiffies) {
- list_del_init(&p->pend);
- p->delay_jiffies = 0;
- // p->state = TASK_READY;
- task_set_ready(p);
- p->reason = "clk_bh";
- }
- }
+ timer_run_expired_timers();
}
uint16_t read_i8254_counter(uint8_t counter_no) {
tsk->state = TASK_INITING;
- INIT_LIST_HEAD(&tsk->list);
- INIT_LIST_HEAD(&tsk->ready_list);
- INIT_LIST_HEAD(&tsk->waitq_list);
- INIT_LIST_HEAD(&tsk->pend);
+ task_init_lists(tsk);
+
unsigned long iflags;
irq_save(iflags);
list_add(&tsk->list, &all_tasks);
#include <irq.h>
#include <system.h>
#include <task.h>
+#include <clock.h>
irq_desc_t irq_desc[NR_IRQS];
irq_bh_action_t* irq_bh_actions = NULL;
#endif
}
-extern uint32_t jiffies;
-
volatile bool enable_clock_irq_delay = false;
void irq_bh_handler() {
- uint32_t end = jiffies + 1;
+ uint64_t end = jiffies + 1;
// ENABLE_CLOCK_IRQ_WAIT是用来调试的
// 是为了让时钟减缓进程的时间片更慢一点,以便于调试
LIST_HEAD(all_tasks);
LIST_HEAD(ready_tasks);
-LIST_HEAD(delay_tasks);
void init_root_task() {
int i;
root_task.magic = TASK_MAGIC;
strcpy(root_task.name, "root");
- INIT_LIST_HEAD(&root_task.list);
- INIT_LIST_HEAD(&root_task.ready_list);
- INIT_LIST_HEAD(&root_task.pend);
- // INIT_LIST_HEAD(&root_task.next);
+ task_init_lists(&root_task);
list_add(&root_task.list, &all_tasks);
void setup_tasks() {
INIT_LIST_HEAD(&all_tasks);
INIT_LIST_HEAD(&ready_tasks);
- INIT_LIST_HEAD(&delay_tasks);
init_root_task();
t->state = TASK_WAIT;
irq_restore(eflags);
+}
+
+void task_init_lists(task_t* t) {
+ assert(t != NULL);
+
+ INIT_LIST_HEAD(&t->list);
+ INIT_LIST_HEAD(&t->ready_list);
+ INIT_LIST_HEAD(&t->waitq_list);
}
\ No newline at end of file
#include "msr.h"
#include "sched.h"
#include "system.h"
+#include "timer.h"
+#include "clock.h"
extern void syscall_entry();
extern void init_sysc_handler_table();
return 0;
}
-extern uint64_t jiffies;
+static void timer_waitq_wakeup_one_cb(void* arg) {
+ waitq_t* waitq = (waitq_t*)arg;
+ waitq_wakeup_one(waitq);
+}
// 特别说明:如果想把这个函数的参数ticks改为int64_t
// 那么就需要在编写用户级的系统调用库函数的时候注意
} else {
unsigned long flags;
irq_save(flags);
- // current->state = TASK_WAIT;
assert(current->state != TASK_WAIT);
- assert(list_empty(¤t->pend));
- task_set_wait(current);
- current->reason = "sysc_wait";
- current->delay_jiffies = jiffies + ticks;
- list_add(¤t->pend, &delay_tasks);
+
+ waitq_t waitq;
+ waitq_init(&waitq);
+
+ timer_t timer;
+ timer_init(&timer, jiffies + ticks, timer_waitq_wakeup_one_cb, &waitq);
+ timer_add(&timer);
+
+ waitq_sleep(&waitq);
+
+ timer_del(&timer);
+
irq_restore(flags);
}
- schedule();
+
return 0;
}
--- /dev/null
+/*
+ * ------------------------------------------------------------------------
+ * File Name: timer.c
+ * Author: Zhao Yanbai
+ * 2026-08-13 16:11:37 Thursday CST
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+
+#include <timer.h>
+#include <irq.h>
+#include <assert.h>
+#include <clock.h>
+
+void timer_init(timer_t* timer, uint64_t expires, timer_callback_t callback, void* callback_arg) {
+ assert(timer != NULL);
+
+ list_init(&timer->list);
+ timer->expires = expires;
+ timer->callback = callback;
+ timer->callback_arg = callback_arg;
+}
+
+list_head_t g_timer_list = LIST_HEAD_INIT(g_timer_list);
+
+void timer_add(timer_t* timer) {
+ assert(timer != NULL);
+ assert(list_empty(&timer->list));
+
+ unsigned long eflags;
+ irq_save(eflags);
+
+ // 按expires升序添加到g_timer_list中
+ list_head_t* prev = &g_timer_list;
+ list_head_t* pos = NULL;
+ list_for_each(pos, &g_timer_list) {
+ timer_t* current_timer = list_entry(pos, timer_t, list);
+ if (timer->expires < current_timer->expires) {
+ break;
+ }
+
+ prev = pos;
+ }
+
+ assert(prev != NULL);
+ list_add(&timer->list, prev);
+
+ irq_restore(eflags);
+}
+
+void timer_del(timer_t* timer) {
+ assert(timer != NULL);
+
+ unsigned long eflags;
+ irq_save(eflags);
+
+ list_del_init(&timer->list);
+
+ irq_restore(eflags);
+}
+
+void timer_run_expired_timers() {
+ list_head_t expire_timers = LIST_HEAD_INIT(expire_timers);
+
+ // 关中断将到期的定时器添加到临时的expire_timers链表中
+ unsigned long eflags;
+ irq_save(eflags);
+
+ list_head_t* pos = NULL;
+ list_head_t* tmp = NULL;
+ list_for_each_safe(pos, tmp, &g_timer_list) {
+ timer_t* timer = list_entry(pos, timer_t, list);
+ if (timer->expires <= jiffies) {
+ list_del_init(pos);
+
+ list_add_tail(pos, &expire_timers);
+ } else {
+ break;
+ }
+ }
+
+ irq_restore(eflags);
+
+ // 执行到期的定时器回调函数
+ pos = NULL;
+ tmp = NULL;
+ list_for_each_safe(pos, tmp, &expire_timers) {
+ timer_t* timer = list_entry(pos, timer_t, list);
+ timer_callback_t callback = timer->callback;
+ void* callback_arg = timer->callback_arg;
+ assert(callback != NULL);
+
+ list_del_init(pos);
+
+ callback(callback_arg);
+ }
+}
\ No newline at end of file