From: acevest Date: Wed, 12 Aug 2026 11:17:25 +0000 (+0800) Subject: 添加READY队列 X-Git-Url: http://repos.zhaoyanbai.com/?a=commitdiff_plain;h=17f21268a9f4f93a467ff21f9a3bd55698deb617;p=kernel.git 添加READY队列 --- diff --git a/drivers/keyboard.c b/drivers/keyboard.c index 5b68d3a..b660fe6 100644 --- a/drivers/keyboard.c +++ b/drivers/keyboard.c @@ -27,7 +27,6 @@ void reboot(); void poweroff(); void ide_debug(); void ide_status(); -void debug_sched(); void kbd_debug(uint8_t scan_code); diff --git a/include/sched.h b/include/sched.h index 969482b..0205dbc 100644 --- a/include/sched.h +++ b/include/sched.h @@ -31,9 +31,3 @@ extern void load_cr3(task_t* tsk); extern list_head_t all_tasks; extern list_head_t delay_tasks; - -#define set_current_state(st) \ - do { \ - current->state = (st); \ - mb(); \ - } while (0) diff --git a/include/task.h b/include/task.h index 729bcbc..b46a8da 100644 --- a/include/task.h +++ b/include/task.h @@ -85,6 +85,8 @@ typedef union task_union { list_head_t list; // 所有进程串成一个链表 + list_head_t ready_list; // 就绪队列 + list_head_t pend; // 某些条件串成一个链表 // list_head_t wait; @@ -114,14 +116,17 @@ static inline pid_t sysc_getpid() { return current->pid; } -task_t* find_task(pid_t pid); - #define ROOT_TSK_PID (0) // #define TASK_INIT_WEIGHT 0 #define get_tsk_from_list(p) list_entry((p), Task, list) #define del_tsk_from_list(tsk) list_del((&tsk->list)) -#endif + +void task_set_run(task_t* t); +void task_set_ready(task_t* t); +void task_set_wait(task_t* t); + +#endif // ASM #endif //_TASK_H diff --git a/include/wait.h b/include/wait.h index 2833f35..80e8f07 100644 --- a/include/wait.h +++ b/include/wait.h @@ -56,26 +56,26 @@ void __wake_up(wait_queue_head_t* head, int nr); // 以下wait_event被定义成宏,而不是函数是因为condition // condition可能是一个表达式,如果定义成函数,往下传递就直接变成了一个值 // 如果在某一步这个值变了,并不会反应在这些逻辑判断上 -#define __wait_event(head, condition) \ - do { \ - DECLARE_WAIT_QUEUE_ENTRY(__wait, current); \ - unsigned long flags; \ - while (1) { \ - irq_save(flags); \ - prepare_to_wait(head, &__wait, TASK_WAIT); \ - if ((condition)) { \ - __end_wait(&__wait); \ - irq_restore(flags); \ - break; \ - } else { \ - irq_restore(flags); \ - void schedule(); \ - schedule(); \ - irq_save(flags); \ - __end_wait(&__wait); \ - irq_restore(flags); \ - } \ - } \ +#define __wait_event(head, condition) \ + do { \ + DECLARE_WAIT_QUEUE_ENTRY(__wait, current); \ + unsigned long flags; \ + while (1) { \ + irq_save(flags); \ + __prepare_to_wait(head, &__wait, TASK_WAIT); \ + if ((condition)) { \ + __end_wait(&__wait); \ + irq_restore(flags); \ + break; \ + } else { \ + irq_restore(flags); \ + void schedule(); \ + schedule(); \ + irq_save(flags); \ + __end_wait(&__wait); \ + irq_restore(flags); \ + } \ + } \ } while (0) #define wait_event(head, condition) \ diff --git a/kernel/clock.c b/kernel/clock.c index 9ed4e5f..c7127d9 100644 --- a/kernel/clock.c +++ b/kernel/clock.c @@ -58,9 +58,10 @@ void clk_bh_handler(void* arg) { assert(p->state == TASK_WAIT); assert(p->delay_jiffies != 0); if (p->delay_jiffies > 0 && jiffies > p->delay_jiffies) { - list_del(&p->pend); + list_del_init(&p->pend); p->delay_jiffies = 0; - p->state = TASK_READY; + // p->state = TASK_READY; + task_set_ready(p); p->reason = "clk_bh"; } } diff --git a/kernel/console.c b/kernel/console.c index b2d6ba7..2eefaa5 100644 --- a/kernel/console.c +++ b/kernel/console.c @@ -54,151 +54,4 @@ int console_write(const char* buf, size_t size) { console_list[i]->write(buf, size); } return 0; -} - -#if 0 - -cnsl_t cnsl; - -static bool empty(const cnsl_queue_t* q) { - return q->head == q->tail; -} - -static bool full(const cnsl_queue_t* q) { - return (q->head + 1) % CNSL_QUEUE_SIZE == q->tail; -} - -static void put(cnsl_queue_t* q, char c) { - if (!full(q)) { - q->data[q->head] = c; - q->head = (q->head + 1) % CNSL_QUEUE_SIZE; - } -} - -static bool get(cnsl_queue_t* q, char* c) { - if (!empty(q)) { - *c = q->data[q->tail]; - q->tail = (q->tail + 1) % CNSL_QUEUE_SIZE; - return true; - } - - return false; -} - -static void clear(cnsl_queue_t* q) { - q->head = q->tail = 0; -} - -static void erase(cnsl_queue_t* q) { - if (empty(q)) - return; - - if (q->head == 0) - q->head = CNSL_QUEUE_SIZE - 1; - else - q->head--; -} - -static void cnsl_queue_init(cnsl_queue_t* cq) { - memset((void*)cq, 0, sizeof(*cq)); - cq->head = 0; - cq->tail = 0; - init_wait_queue_head(&cq->wait); -} - -// wait_queue_head_t rdwq; -semaphore_t sem; -void cnsl_init() { - cnsl_queue_init(&cnsl.rd_q); - cnsl_queue_init(&cnsl.wr_q); - cnsl_queue_init(&cnsl.sc_q); - // init_wait_queue_head(&rdwq); - semaphore_init(&sem, 0); -} - -int cnsl_kbd_write(char ch) { - if (ch == 0) { - return 0; - } - extern tty_t* const default_tty; - if (ch == '\b') { - if (!empty(&cnsl.wr_q)) { - tty_color_putc(default_tty, '\b', TTY_FG_HIGHLIGHT | TTY_WHITE, TTY_BLACK); - } - // tty_color_putc(default_tty, '\b', TTY_WHITE, TTY_BLACK); - erase(&cnsl.wr_q); - erase(&cnsl.sc_q); - } else { - put(&cnsl.wr_q, ch); - put(&cnsl.sc_q, ch); - tty_color_putc(default_tty, ch, TTY_FG_HIGHLIGHT | TTY_WHITE, TTY_BLACK); - } - - if (ch == '\n') { - clear(&cnsl.wr_q); - return 0; // TODO FIX - while (get(&cnsl.sc_q, &ch)) - put(&cnsl.rd_q, ch); - // wake_up(&rdwq); - up(&sem); - } - - return 0; -} - -int cnsl_read(char* buf, size_t count) { - // unsigned long flags; - - assert(count > 0); - int cnt = 0; - for (cnt = 0; cnt < count;) { - char ch; -#if 1 - while (true) { - down(&sem); - - bool r = get(&cnsl.rd_q, &ch); - if (r) { - buf[cnt++] = ch; - if (ch == '\n') { - goto end; - } - } else { - break; - } - } -#else - task_union* task = current; - DECLARE_WAIT_QUEUE(wait, task); - add_wait_queue(&rdwq, &wait); - - while (true) { - task->state = TASK_WAIT; - irq_save(flags); - bool r = get(&cnsl.rd_q, &ch); - irq_restore(flags); - - if (r) { - buf[cnt++] = ch; - - task->state = TASK_READY; - del_wait_queue(&rdwq, &wait); - - if (ch == '\n') - goto end; - - break; - } - - schedule(); - } -#endif - } - -end: - buf[cnt] = 0; - return cnt; -} - -chrdev_t cnsl_chrdev = {.read = cnsl_read}; -#endif +} \ No newline at end of file diff --git a/kernel/fork.c b/kernel/fork.c index 437e51d..0a539b0 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -32,6 +32,8 @@ int do_fork(pt_regs_t* regs, unsigned long flags) { tsk->state = TASK_INITING; INIT_LIST_HEAD(&tsk->list); + INIT_LIST_HEAD(&tsk->ready_list); + INIT_LIST_HEAD(&tsk->pend); unsigned long iflags; irq_save(iflags); list_add(&tsk->list, &all_tasks); @@ -95,7 +97,7 @@ int do_fork(pt_regs_t* regs, unsigned long flags) { printd("task %08x child_regs esp %08x esp0 %08x\n", tsk, tsk->esp, tsk->esp0); - tsk->state = TASK_READY; + task_set_ready(tsk); void add_task_for_monitor(task_t * tsk); add_task_for_monitor(tsk); diff --git a/kernel/sched.c b/kernel/sched.c index 2bfb2e3..8f7dc5c 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -46,10 +46,8 @@ void load_cr3(task_t* tsk) { extern pde_t __initdata init_pgd[PDECNT_PER_PAGE] __attribute__((__aligned__(PAGE_SIZE))); -// list_head_t all_tasks; -// list_head_t delay_tasks; LIST_HEAD(all_tasks); - +LIST_HEAD(ready_tasks); LIST_HEAD(delay_tasks); void init_root_task() { @@ -57,7 +55,7 @@ void init_root_task() { root_task.pid = get_next_pid(); root_task.ppid = 0; - root_task.state = TASK_READY; + root_task.state = TASK_RUN; root_task.reason = "root"; root_task.priority = 7; root_task.ticks = root_task.priority; @@ -68,9 +66,13 @@ void init_root_task() { root_task.magic = TASK_MAGIC; strcpy(root_task.name, "root"); - list_add(&root_task.list, &all_tasks); + 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); + list_add(&root_task.list, &all_tasks); + // TODO // for(i=0; ipid == pid) { - break; - } - } - irq_restore(iflags); - - return p; -} - void schedule() { - // task_t* root = &root_task; - task_t* sel = 0; - task_t* p = 0; - list_head_t *pos = 0, *t = 0; - - assert(current->priority <= TASK_MAX_PRIORITY); + task_t* prev = current; + task_t* next = NULL; - unsigned long iflags; - irq_save(iflags); + unsigned long eflags; + irq_save(eflags); - if (current->state == TASK_RUN) { - current->state = TASK_READY; + if (prev->state == TASK_READY || prev->state == TASK_RUN) { + task_set_ready(prev); } - // task_t *head = current; - list_for_each_safe(pos, t, ¤t->list) { - p = list_entry(pos, task_t, list); - if (TASK_READY != p->state) { - continue; - } - if (&root_task == p) { - continue; - } - - sel = p; - break; + if (list_empty(&ready_tasks)) { + next = &root_task; + goto end; } - if (sel == 0) { - if (current->state != TASK_READY) { - sel = &root_task; - root_task.ticks = root_task.priority; - root_task.state = TASK_READY; - } else { - sel = current; - } - } + // 从ready_tasks中选择第一个 + next = list_entry(ready_tasks.next, task_t, ready_list); - task_t* prev = current; - task_t* next = sel; + assert(next->state == TASK_READY); + assert(next != &root_task); - next->state = TASK_RUN; - next->reason = ""; +end: + task_set_run(next); + + if (prev->ticks <= 0) { + prev->ticks = prev->priority; + } if (prev != next) { - if (prev->ticks <= 0) { - prev->ticks = prev->priority; - } next->sched_cnt++; context_switch(prev, next); } else { - // 这里可能是的情况是任务把时间片ticks用完了 - // 被设置成READY - // 重新高度,还是选中了该任务 next->sched_keep_cnt++; } - assert(current->state == TASK_RUN); - - irq_restore(iflags); -} - -void debug_sched() { - task_t* p = list_entry(current->list.next, task_t, list); - p->state = (p->state == TASK_READY) ? TASK_WAIT : TASK_READY; + irq_restore(eflags); } task_t* monitor_tasks[1024] = {&root_task, 0}; @@ -222,3 +179,53 @@ void add_task_for_monitor(task_t* tsk) { int id = tsk->pid; monitor_tasks[id] = tsk; } + +void task_set_run(task_t* t) { + assert(t != NULL); + + if (t == &root_task) { + t->state = TASK_RUN; + return; + } + + assert(t->state == TASK_READY); + + unsigned long eflags; + irq_save(eflags); + + list_del_init(&t->ready_list); + t->state = TASK_RUN; + + irq_restore(eflags); +} + +void task_set_ready(task_t* t) { + assert(t != NULL); + if (t == &root_task) { + t->state = TASK_READY; + return; + } + + unsigned long eflags; + irq_save(eflags); + if (!list_empty(&t->ready_list)) { + list_del_init(&t->ready_list); + } + list_add_tail(&t->ready_list, &ready_tasks); + t->state = TASK_READY; + irq_restore(eflags); +} + +void task_set_wait(task_t* t) { + assert(t != NULL); + // printk("task_set_wait %s %d\n", t->name, t->state); + assert(t != &root_task); + + unsigned long eflags; + irq_save(eflags); + + list_del_init(&t->ready_list); + t->state = TASK_WAIT; + + irq_restore(eflags); +} \ No newline at end of file diff --git a/kernel/semaphore.c b/kernel/semaphore.c index 0e5867f..096ac5f 100644 --- a/kernel/semaphore.c +++ b/kernel/semaphore.c @@ -42,7 +42,8 @@ volatile void down(semaphore_t* s) { INIT_LIST_HEAD(&waiter.list); list_add(&waiter.list, &s->wait_list); - task->state = TASK_WAIT; + // task->state = TASK_WAIT; + task_set_wait(task); task->reason = "down"; irq_restore(iflags); @@ -64,7 +65,8 @@ volatile void up(semaphore_t* s) { list_del(&waiter->list); task_t* task = waiter->task; - task->state = TASK_READY; + // task->state = TASK_READY; + task_set_ready(task); task->reason = "up"; irq_restore(iflags); diff --git a/kernel/syscall.c b/kernel/syscall.c index 218f5cc..fa0323a 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -51,7 +51,10 @@ int sysc_wait(int ticks) { } else { unsigned long flags; irq_save(flags); - current->state = TASK_WAIT; + // 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); diff --git a/kernel/tty.c b/kernel/tty.c index 875d1d5..31cc486 100644 --- a/kernel/tty.c +++ b/kernel/tty.c @@ -133,11 +133,11 @@ int tty_input(tty_t* tty, uint8_t c) { irq_restore(eflags); - // 目前先总是回显 - tty_write(tty, (const char*)&c, 1); - // 唤醒读进程 wake_up(&tty->ib_wait); + // 目前先总是回显 + tty_write(tty, (const char*)&c, 1); + return 1; } \ No newline at end of file diff --git a/kernel/wait.c b/kernel/wait.c index 27ecefd..f1d8e36 100644 --- a/kernel/wait.c +++ b/kernel/wait.c @@ -32,12 +32,14 @@ volatile void __prepare_to_wait(wait_queue_head_t* head, wait_queue_entry_t* wqe // list_add_tail(&wqe->entry, &head->task_list); list_add(&wqe->entry, &head->task_list); } - set_current_state(state); + + assert(state == TASK_WAIT); + task_set_wait(current); current->reason = "p_wait"; } volatile void __end_wait(wait_queue_entry_t* wqe) { - set_current_state(TASK_READY); + task_set_ready(current); current->reason = "e_wait"; // unsigned long flags; // irq_save(flags); @@ -66,7 +68,8 @@ volatile void __wake_up(wait_queue_head_t* head, int nr) { list_for_each_entry_safe(p, tmp, &head->task_list, entry) { assert(p->task != NULL); // printk("wakeup %s\n", p->task->name); - p->task->state = TASK_READY; + // p->task->state = TASK_READY; + task_set_ready(p->task); p->task->reason = "wake_up"; list_del_init(&p->entry);