]> Zhao Yanbai Git Server - kernel.git/commitdiff
恢复信号量操作up()里调用schedule()
authoracevest <zhaoyanbai@126.com>
Tue, 23 Jul 2024 12:44:33 +0000 (20:44 +0800)
committeracevest <zhaoyanbai@126.com>
Wed, 21 Aug 2024 08:24:56 +0000 (16:24 +0800)
drivers/ide.c
kernel/semaphore.c

index 27616318280a3ae68e6fe31ee5c6659303a85496..fa65c10d2e3540e0f737b6dc55591129300834c8 100644 (file)
@@ -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);
 }
index 5ee78f3cea0472de7b156fc05a447b4d88dd839f..7207a3ec743a74766c021cc4831eb2ed598d517b 100644 (file)
@@ -57,6 +57,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);
@@ -66,13 +67,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_init(mutex_t *s) { INIT_MUTEX(s); }