]> Zhao Yanbai Git Server - kernel.git/commitdiff
简化down 和 up的逻辑
authoracevest <zhaoyanbai@126.com>
Tue, 17 Oct 2023 07:58:26 +0000 (15:58 +0800)
committeracevest <zhaoyanbai@126.com>
Tue, 17 Oct 2023 07:58:26 +0000 (15:58 +0800)
drivers/block.c
include/semaphore.h
include/task.h
kernel/semaphore.c

index 4ce1bded731415665d4aba989fb206b7e316a8c1..baacea91fe3a94a365d6dfc6e74138aba267c38f 100644 (file)
@@ -60,7 +60,10 @@ void ata_read_ext2_sb() {
            p->s_free_blocks_count, p->s_magic);
     printk("first ino %u inode size %u first data block %u\n", p->s_first_ino, p->s_inode_size, p->s_first_data_block);
     printk("log block size %u write time %u\n", p->s_log_block_size, p->s_wtime);
-    p->s_volume_name[63] = 0;
-    printk("volume %s\n", p->s_volume_name);
+    char volume_name[16 + 1];
+    strncpy(volume_name, p->s_volume_name, 16);
+    volume_name[16] = 0;
+    printk("volume %s\n", volume_name);
+    // printk("last mounted %s\n", p->s_last_mounted);
     kfree(bb->data);
 }
index f76b5d5e8135355e199f2a870e439d340290db28..7f29c1a98c9308988e1bd3888d09f5affa038e7c 100644 (file)
@@ -34,7 +34,10 @@ void up(semaphore_t *s);
 
 typedef semaphore_t mutex_t;
 
-#define DECLARE_MUTEX(name) semaphore_t name = SEMAPHORE_INITIALIZER(name, 1)
+#define MUTEX_INITIALIZER(name) \
+    { .cnt = (1), .wait_list = LIST_HEAD_INIT((name).wait_list) }
+
+#define DECLARE_MUTEX(name) mutex_t name = MUTEX_INITIALIZER(name)
 
 #define INIT_MUTEX(ptr)                      \
     do {                                     \
index 4c3f74e54cfeec48ef589b804df697e30ea744d1..18827237c264ae2b4f8edfc5b08f85d9e5597741 100644 (file)
@@ -72,7 +72,7 @@ typedef union task_union {
 
         list_head_t pend;  // 某些条件串成一个链表
 
-        wait_queue_head_t wait;
+        list_head_t wait;
 
         uint32_t sched_cnt;       // 被调度换上CPU的次数
         uint32_t sched_keep_cnt;  // 时间片到了,但是没有被换出,又重新执行的次数
index 199b17c9b811f24b58cbec80e2cc9b369b0ad2a1..9014f46d203f3484bb55938f7b1d9237f2e1d685 100644 (file)
 #include <sched.h>
 #include <semaphore.h>
 
+void semaphore_init(semaphore_t *s, unsigned int v) {
+    s->cnt = v;
+    INIT_LIST_HEAD(&(s->wait_list));
+}
+
+#if 1
+volatile void down(semaphore_t *s) {
+    unsigned long iflags;
+    irq_save(iflags);
+
+    if (likely(s->cnt > 0)) {
+        s->cnt--;
+    } else {
+        task_union *task = current;
+        list_add_tail(&task->wait, &s->wait_list);
+
+        task->state = TASK_WAIT;
+        task->reason = "down";
+
+        schedule();
+    }
+
+    irq_restore(iflags);
+}
+
+volatile void up(semaphore_t *s) {
+    unsigned long iflags;
+    irq_save(iflags);
+
+    if (list_empty(&s->wait_list)) {
+        s->cnt++;
+    } else {
+        task_union *task = list_first_entry(&s->wait_list, task_union, wait);
+        list_del(&task->wait);
+        task->state = TASK_READY;
+        task->reason = "up";
+
+        // 按理这里应该调用schedule再重新调度一次
+        // 原因是有可能多个任务都在一个循环里争抢一个锁
+        // 如果这里不让当前任务尝试放弃CPU重新调度,则在下一轮循环中它又可能抢到锁
+        // 这种情况如果一直发生,就可能导致其它任务一直抢不到
+        //
+        // 但这里为什么又没调用schedule呢?
+        // 这是因为在目前在ide_irq_bh_handler里调用了up来唤醒磁盘任务
+        // 而ide_irq_bh_handler又是中断的底半处理,不应该切换任务
+        // 否则会引起irq里的reenter问题,导致不能再进底半处理,也无法切换任务
+        // 这里暂时先保持这样,后续再来解决这里
+        // schedule();
+    }
+
+    irq_restore(iflags);
+}
+
+#else
+
 typedef struct semaphore_waiter {
     list_head_t list;
     task_union *task;
@@ -21,11 +76,6 @@ typedef struct semaphore_waiter {
 
 #define DECLARE_SEMAPHORE_WAITER(name, task) semaphore_waiter_t name = SEMAPHORE_WAITER_INITIALIZER(name, task)
 
-void semaphore_init(semaphore_t *s, unsigned int v) {
-    s->cnt = v;
-    INIT_LIST_HEAD(&(s->wait_list));
-}
-
 volatile void __down(semaphore_t *s) {
     task_union *task = current;
     DECLARE_SEMAPHORE_WAITER(waiter, task);
@@ -36,6 +86,7 @@ volatile void __down(semaphore_t *s) {
         task->reason = "down";
         schedule();
 
+        assert(waiter.up == 1);
         if (waiter.up) {
             break;
         }
@@ -62,6 +113,18 @@ volatile void __up(semaphore_t *s) {
 
     waiter->task->state = TASK_READY;
     waiter->task->reason = "up";
+
+    // 按理这里应该调用schedule再重新调度一次
+    // 原因是有可能多个任务都在一个循环里争抢一个锁
+    // 如果这里不让当前任务尝试放弃CPU重新调度,则在下一轮循环中它又可能抢到锁
+    // 这种情况如果一直发生,就可能导致其它任务一直抢不到
+    //
+    // 但这里为什么又没调用schedule呢?
+    // 这是因为在目前在ide_irq_bh_handler里调用了up来唤醒磁盘任务
+    // 而ide_irq_bh_handler又是中断的底半处理,不应该切换任务
+    // 否则会引起irq里的reenter问题,导致不能再进底半处理,也无法切换任务
+    // 这里暂时先保持这样,后续再来解决这里
+    // schedule();
 }
 
 volatile void up(semaphore_t *s) {
@@ -77,6 +140,7 @@ volatile void up(semaphore_t *s) {
 
     irq_restore(iflags);
 }
+#endif
 
 void mutex_lock(semaphore_t *s) { down(s); }
 void mutex_unlock(semaphore_t *s) { up(s); }