From: acevest Date: Tue, 23 Jul 2024 12:44:33 +0000 (+0800) Subject: 恢复信号量操作up()里调用schedule() X-Git-Url: http://zhaoyanbai.com/repos/%22/xml/v3/status/static/gitweb.css?a=commitdiff_plain;h=af6f9ccffdc4304a5db9360fbb1285978c431aee;p=kernel.git 恢复信号量操作up()里调用schedule() --- 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); }