From: acevest Date: Fri, 10 May 2024 11:39:20 +0000 (+0800) Subject: 优化等待队列的代码 X-Git-Url: http://zhaoyanbai.com/repos/dnssec-dsfromkey.html?a=commitdiff_plain;h=0141e8ea6e56888f9cc986e131a3de2c8508fb31;p=kernel.git 优化等待队列的代码 --- diff --git a/include/wait.h b/include/wait.h index a3fd1c3..f94a0a7 100644 --- a/include/wait.h +++ b/include/wait.h @@ -22,40 +22,44 @@ typedef struct wait_queue_head { typedef struct { task_t *task; - list_head_t task_list; -} wait_queue_t; + list_head_t entry; +} wait_queue_entry_t; #define WAIT_QUEUE_HEAD_INITIALIZER(name) \ { .task_list = LIST_HEAD_INIT((name).task_list) } #define DECLARE_WAIT_QUEUE_HEAD(name) wait_queue_head_t name = WAIT_QUEUE_HEAD_INITIALIZER(name) -#define WAIT_QUEUE_INITIALIZER(name, tsk) \ - { .task = tsk, .task_list = LIST_HEAD_INIT((name).task_list) } +#define WAIT_QUEUE_ENTRY_INITIALIZER(name, tsk) \ + { .task = tsk, .entry = LIST_HEAD_INIT((name).entry) } -#define DECLARE_WAIT_QUEUE(name, tsk) wait_queue_t name = WAIT_QUEUE_INITIALIZER(name, tsk) +#define DECLARE_WAIT_QUEUE_ENTRY(name, tsk) wait_queue_entry_t name = WAIT_QUEUE_ENTRY_INITIALIZER(name, tsk) void init_wait_queue_head(wait_queue_head_t *wqh); -void add_wait_queue(wait_queue_head_t *head, wait_queue_t *wq); -void del_wait_queue(wait_queue_head_t *head, wait_queue_t *wq); +void add_wait_queue(wait_queue_head_t *head, wait_queue_entry_t *wq); +void del_wait_queue(wait_queue_head_t *head, wait_queue_entry_t *wq); // prepare_to_wait 不会调用schedule -void prepare_to_wait(wait_queue_head_t *head, wait_queue_t *wq, unsigned int state); +void prepare_to_wait(wait_queue_head_t *head, wait_queue_entry_t *wq, unsigned int state); -void __end_wait(wait_queue_t *wq); +void __end_wait(wait_queue_entry_t *wq); // 使用这个函数的时候需要注意 // 设置condition为真的语句和wake_up原子地执行 void wake_up(wait_queue_head_t *head); void __wake_up(wait_queue_head_t *head, int nr); +// 以下wait_event被定义成宏,而不是函数是因为condition +// condition可能是一个表达式,如果定义成函数,往下传递就直接变成了一个值 +// 如果在某一步这个值变了,并不会反应在这些逻辑判断上 + // 只要保证condition设置为真时,它是和wake_up一起原子执行的 // 那就能保证condition为真是如下__wait_event和wait_event里的if不出问题 // 也就是不会出现if-break后进程又再次因为其它原因阻塞后,又被wake_up的逻辑 // 设置为READY状态 #define __wait_event(head, condition) \ do { \ - DECLARE_WAIT_QUEUE(__wait, current); \ + DECLARE_WAIT_QUEUE_ENTRY(__wait, current); \ while (1) { \ prepare_to_wait(head, &__wait, TASK_WAIT); \ if ((condition)) { \ diff --git a/kernel/wait.c b/kernel/wait.c index 0ee1d13..6ddb303 100644 --- a/kernel/wait.c +++ b/kernel/wait.c @@ -14,43 +14,43 @@ volatile void init_wait_queue_head(wait_queue_head_t *wqh) { INIT_LIST_HEAD(&wqh->task_list); } -volatile void prepare_to_wait(wait_queue_head_t *head, wait_queue_t *wq, unsigned int state) { +volatile void prepare_to_wait(wait_queue_head_t *head, wait_queue_entry_t *wqe, unsigned int state) { unsigned long flags; irq_save(flags); - if (list_empty(&wq->task_list)) { - list_add_tail(&wq->task_list, &head->task_list); + if (list_empty(&wqe->entry)) { + list_add_tail(&wqe->entry, &head->task_list); } set_current_state(state); irq_restore(flags); } -volatile void __end_wait(wait_queue_t *wq) { +volatile void __end_wait(wait_queue_entry_t *wqe) { set_current_state(TASK_READY); unsigned long flags; irq_save(flags); - list_del_init(&wq->task_list); + list_del_init(&wqe->entry); irq_restore(flags); } -volatile void add_wait_queue(wait_queue_head_t *head, wait_queue_t *wq) { +volatile void add_wait_queue(wait_queue_head_t *head, wait_queue_entry_t *wqe) { unsigned long flags; irq_save(flags); - list_add_tail(&wq->task_list, &head->task_list); + list_add_tail(&wqe->entry, &head->task_list); irq_restore(flags); } -volatile void del_wait_queue(wait_queue_head_t *head, wait_queue_t *wq) { +volatile void del_wait_queue(wait_queue_head_t *head, wait_queue_entry_t *wqe) { unsigned long flags; irq_save(flags); - list_del(&wq->task_list); + list_del(&wqe->entry); irq_restore(flags); } volatile void __wake_up(wait_queue_head_t *head, int nr) { unsigned long flags; - wait_queue_t *p, *tmp; + wait_queue_entry_t *p, *tmp; irq_save(flags); - list_for_each_entry_safe(p, tmp, &head->task_list, task_list) { + list_for_each_entry_safe(p, tmp, &head->task_list, entry) { p->task->state = TASK_READY; current->reason = "wake_up"; @@ -66,11 +66,11 @@ volatile void __wake_up(wait_queue_head_t *head, int nr) { volatile void wake_up(wait_queue_head_t *head) { // - __wake_up(head, 1); + __wake_up(head, 0); // wake up all } volatile void wait_on(wait_queue_head_t *head) { - DECLARE_WAIT_QUEUE(wait, current); + DECLARE_WAIT_QUEUE_ENTRY(wait, current); unsigned long flags; irq_save(flags); @@ -78,7 +78,7 @@ volatile void wait_on(wait_queue_head_t *head) { current->state = TASK_WAIT; current->reason = "sleep_on"; - list_add_tail(&wait.task_list, &head->task_list); + list_add_tail(&wait.entry, &head->task_list); irq_restore(flags);