From af6f9ccffdc4304a5db9360fbb1285978c431aee Mon Sep 17 00:00:00 2001 From: acevest Date: Tue, 23 Jul 2024 20:44:33 +0800 Subject: [PATCH] =?utf8?q?=E6=81=A2=E5=A4=8D=E4=BF=A1=E5=8F=B7=E9=87=8F?= =?utf8?q?=E6=93=8D=E4=BD=9Cup()=E9=87=8C=E8=B0=83=E7=94=A8schedule()?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- drivers/ide.c | 5 +++++ kernel/semaphore.c | 15 +++++++++------ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/ide.c b/drivers/ide.c index 2761631..fa65c10 100644 --- a/drivers/ide.c +++ b/drivers/ide.c @@ -143,6 +143,11 @@ void ide_irq_bh_handler(void *arg) { printlxy(MPL_IDE0 + channel, MPO_IDE, "IDE%d req %u irq %u consumed %u", channel, atomic_read(&(ide_ctrl->request_cnt)), ide_ctrl->irq_cnt, ide_ctrl->consumed_cnt); + // 之前这里是用up()来唤醒磁盘任务 + // 但在中断的底半处理,不应该切换任务,因为会引起irq里的reenter问题,导致不能再进底半处理,也无法切换任务 + // 所以就移除了up()里的 schedule() + // 后来就改用完成量来通知磁盘任务,就不存在这个问题了 + // complete会唤醒进程,但不会立即重新调度进程 complete(&ide_ctrl->intr_complete); } diff --git a/kernel/semaphore.c b/kernel/semaphore.c index a38696c..23763a5 100644 --- a/kernel/semaphore.c +++ b/kernel/semaphore.c @@ -56,6 +56,7 @@ volatile void up(semaphore_t *s) { if (list_empty(&s->wait_list)) { s->cnt++; + irq_restore(iflags); } else { semaphore_waiter_t *waiter = list_first_entry(&s->wait_list, semaphore_waiter_t, list); assert(waiter != 0); @@ -65,13 +66,15 @@ volatile void up(semaphore_t *s) { task->state = TASK_READY; task->reason = "up"; - // 这里不应该调用schedule()再重新调度一次 - // 例如,目前在ide_irq_bh_handler里调用了up来唤醒磁盘任务 - // 而ide_irq_bh_handler又是中断的底半处理,不应该切换任务 - // 否则会引起irq里的reenter问题,导致不能再进底半处理,也无法切换任务 - } + irq_restore(iflags); - irq_restore(iflags); + // 之前把这里的schedule()删除了,是因为up()被用到了 ide_irq_bh_handler 里去唤醒磁盘任务 + // 但在中断的底半处理,不应该切换任务,因为会引起irq里的reenter问题,导致不能再进底半处理,也无法切换任务 + // 但这种方法是不对的 + // 后来就改用完成量来通知磁盘任务 + // 因此信号量这里就可以加回schedule()了 + schedule(); + } } void mutex_lock(semaphore_t *s) { down(s); } -- 2.44.0