]> Zhao Yanbai Git Server - kernel.git/commitdiff
替换所有同步原语的实现逻辑
authoracevest <zhaoyanbai@126.com>
Thu, 13 Aug 2026 00:36:40 +0000 (08:36 +0800)
committeracevest <zhaoyanbai@126.com>
Thu, 13 Aug 2026 00:36:40 +0000 (08:36 +0800)
27 files changed:
drivers/ide.c
drivers/ide.h
drivers/sata.c
drivers/sata.h
fs/buffer.c
fs/dentry.c
fs/fssysc.c
fs/path.c
fs/vfs.h
fs/write.c
include/buffer.h
include/completion.h
include/disk.h
include/semaphore.h
include/sync.h [new file with mode: 0644]
include/task.h
include/tty.h
include/wait.h
include/waitq.h [new file with mode: 0644]
kernel/completion.c
kernel/fork.c
kernel/semaphore.c
kernel/sync.c [new file with mode: 0644]
kernel/task_disk.c
kernel/task_ide.c
kernel/tty.c
kernel/waitq.c [new file with mode: 0644]

index 72e6d439c53a131256f4f588fc2b03608087abd1..52bd0eb0326c5d076749a3c2d5cc69fa200bd43c 100644 (file)
@@ -9,9 +9,8 @@
 
 #include <ide.h>
 #include <irq.h>
-#include <semaphore.h>
+#include <sync.h>
 #include <task.h>
-#include <wait.h>
 
 /*
 高技术配置(英语:Advanced Technology Attachment,简称“ATA”)与由集成驱动电子设备(英语:Integrated Drive
@@ -127,7 +126,7 @@ void ide_irq_bh_handler(void* arg) {
     // 所以就移除了up()里的 schedule()
     // 后来就改用完成量来通知磁盘任务,就不存在这个问题了
     // complete会唤醒进程,但不会立即重新调度进程
-    complete(&ide_ctrl->intr_complete);
+    completion_complete(&ide_ctrl->intr_complete);
 }
 
 void ide_irq_handler(unsigned int irq, pt_regs_t* regs, void* devid) {
@@ -178,11 +177,12 @@ void ide_pci_init(pci_device_t* pci) {
     uint32_t iobase = pci->bars[4] & 0xFFFFFFFE;  // 最低为0是内存地址为1是端口地址
 
     for (int i = 0; i < NR_IDE_CONTROLLER; i++) {
-        INIT_MUTEX(&ide_pci_controller[i].request_mutex);
+        // INIT_MUTEX(&ide_pci_controller[i].request_mutex);
+        mutex_init(&ide_pci_controller[i].request_mutex);
         ide_pci_controller[i].request_queue.count = 0;
         INIT_LIST_HEAD(&ide_pci_controller[i].request_queue.list);
         semaphore_init(&ide_pci_controller[i].request_queue.sem, 0);
-        init_completion(&ide_pci_controller[i].intr_complete);
+        completion_init(&ide_pci_controller[i].intr_complete);
         ide_pci_controller[i].intr_complete.name = i == 0 ? "ide0_intr_complete" : "ide1_intr_complete";
 
         atomic_set(&ide_pci_controller[i].request_cnt, 0);
index 6076a087d5b83b2ea291c29bfccadee23b611a02..65ca5a607b86a4756b5896255e4663e9f35d52f5 100644 (file)
@@ -14,7 +14,6 @@
 #include <disk.h>
 #include <io.h>
 #include <pci.h>
-#include <semaphore.h>
 #include <system.h>
 #include <task.h>
 
index 5295e5b29cfc36a87ce2f43c1216a30d85307c0f..c8897f7535d44528c7d0bbacc5f9cedad9e5a769 100644 (file)
@@ -34,7 +34,7 @@ void init_sata_device(ahci_hba_t* hba, ahci_port_t* port, int port_index) {
     sata->index = index;
     sata->port_index = port_index;
 
-    init_completion(&sata->completion);
+    completion_init(&sata->completion);
 
     printk("ahci port clb %08x fb %08x sata_status 0x%08X signature %08X\n", port->cmd_list_base, port->fis_base,
            port->sata_status, port->signature);
@@ -127,7 +127,7 @@ void sata_irq_handler(unsigned int irq, pt_regs_t* regs, void* dev_id) {
             //
         }
 
-        complete(&sata->completion);
+        completion_complete(&sata->completion);
 
         port->interrupt_status = interrupt_status;
     }
index db9c1736f8e6fbe1b84f6f8795d81937043e2204..bef5349760076cf8ed156680b5917557500cd0f6 100644 (file)
@@ -11,7 +11,7 @@
 
 #include <ahci.h>
 #include <types.h>
-#include <completion.h>
+#include <sync.h>
 
 #define SATA_SIGNATURE_ATA 0x00000101
 #define SATA_SIGNATURE_ATAPI 0xEB140101
index 83bc864d43660aa004293a928fcf20e41207276f..dcd8c315f1084b4d4ee72abc6409c648887667f9 100644 (file)
@@ -26,7 +26,7 @@ typedef struct bbuffer_store {
     int blocksize;
     // list_head_t cache_list;
     list_head_t free_list;
-    wait_queue_head_t waitq;
+    waitq_t waitq;
 } bbuffer_store_t;
 
 // 1024, 2048, 4096
@@ -128,7 +128,7 @@ again:
         // wait on free list
         // TODO
         assert(0);
-        // wait_on(&s->waitq);
+        // waitq_sleep(&s->waitq);
         goto again;
     }
 
@@ -141,7 +141,7 @@ again:
     // 虽然此时该bbuffer_t上的ref_count为0但其可能还有I/O操作没有完成
     // 因为可能有的进程调用了write、read后再直接调用brelse
     // 所以需要在此等待其结束
-    wait_completion(&b->io_done);
+    completion_wait(&b->io_done);
 
     // 找到了
     b->block = block;
@@ -157,7 +157,7 @@ void brelse(bbuffer_t* b) {
     assert(b != NULL);
     assert(atomic_read(&(b->ref_count)) > 0);
 
-    wait_completion(&b->io_done);
+    completion_wait(&b->io_done);
 
     bbuffer_store_t* s = getstore(b->block_size);
     assert(s != NULL);
@@ -165,7 +165,7 @@ void brelse(bbuffer_t* b) {
 
     // TODO
     assert(0);
-    // wake_up(&s->waitq);
+    // waitq_wakeup_all(&s->waitq);
 }
 
 bbuffer_t* bread(dev_t dev, uint64_t block, uint32_t size) {
@@ -182,7 +182,7 @@ bbuffer_t* bread(dev_t dev, uint64_t block, uint32_t size) {
     block_read(b);
 
     // 等待I/O结束
-    wait_completion(&b->io_done);
+    completion_wait(&b->io_done);
     if (b->uptodate == 1) {
         return b;
     }
@@ -211,7 +211,7 @@ void init_buffer() {
         store[i].blocksize = blocksize;
         // list_init(&store[i].cache_list);
         list_init(&store[i].free_list);
-        init_wait_queue_head(&store[i].waitq);
+        waitq_init(&store[i].waitq);
 
         int page_left_space = 0;
         void* data = NULL;
@@ -237,8 +237,8 @@ void init_buffer() {
             b->dev = 0;
             b->page = page;
             b->uptodate = 0;
-            init_completion(&b->io_done);
-            complete(&b->io_done);
+            completion_init(&b->io_done);
+            completion_complete(&b->io_done);
             list_init(&b->node);
 
             assert(NULL != b->data);
index 6194613f1b058ddf08170615e83ce64f1f91c0f8..acd0c3885686e8ffc1815ce5effb120ad57d22ac 100644 (file)
@@ -9,7 +9,7 @@
 
 #include <errno.h>
 #include <mm.h>
-#include <semaphore.h>
+#include <sync.h>
 #include <string.h>
 #include <system.h>
 #include <vfs.h>
@@ -186,7 +186,7 @@ int dentry_real_lookup(dentry_t* parent, qstr_t* s, dentry_t** dentry) {
     assert(parent->d_inode != NULL);
     inode_t* dir = parent->d_inode;
 
-    down(&dir->i_sem);
+    semaphore_down(&dir->i_sem);
 
     // 在获得信号量后,需要再上cache中查找一遍
     // 因为这个过程中当前进程可能会睡眠,当被唤醒后,其它进程已经在内存准备好了
@@ -194,7 +194,7 @@ int dentry_real_lookup(dentry_t* parent, qstr_t* s, dentry_t** dentry) {
     assert(0 == ret);
 
     if (NULL != *dentry) {
-        up(&dir->i_sem);
+        semaphore_up(&dir->i_sem);
         return ret;
     }
 
@@ -220,7 +220,7 @@ int dentry_real_lookup(dentry_t* parent, qstr_t* s, dentry_t** dentry) {
         // }
     }
 
-    up(&dir->i_sem);
+    semaphore_up(&dir->i_sem);
 
     return ret;
 }
index cc8b46cb538cd2106512a415e8f3e583ae8cd4aa..521814cf56615a438070e0b0b4a9bec0eb2353c4 100644 (file)
@@ -36,7 +36,7 @@ __attribute__((regparm(0))) long sysc_mkdir(const char* path, int mode) {
         assert(dentry == NULL);
     }
 
-    up(&ni.path.dentry->d_inode->i_sem);
+    semaphore_up(&ni.path.dentry->d_inode->i_sem);
 
     return ret;
 }
index 7e1a491544069f33bcb5516ba3e7216a9e9ec3c8..bd0c8c0831662eebac4f3d458e5ba14fa68940b9 100644 (file)
--- a/fs/path.c
+++ b/fs/path.c
@@ -361,7 +361,7 @@ int path_lookup_create(namei_t* ni, dentry_t** dentry) {
     int err = 0;
 
     // 在调用完path_lookup_create后调用 up 操作
-    down(&ni->path.dentry->d_inode->i_sem);
+    semaphore_down(&ni->path.dentry->d_inode->i_sem);
 
     //
     if (ni->last_type != LAST_NORMAL) {
@@ -405,18 +405,18 @@ int path_open_namei(const char* path, int flags, int mode, namei_t* ni) {
 
     dir = ni->path.dentry;
     assert(NULL != dir);
-    down(&dir->d_inode->i_sem);
+    semaphore_down(&dir->d_inode->i_sem);
 
     ret = path_lookup_hash(dir, &ni->last, &dentry);
     if (0 != ret) {
-        up(&dir->d_inode->i_sem);
+        semaphore_up(&dir->d_inode->i_sem);
         goto end;
     }
 
     assert(dentry != NULL);
     if (NULL == dentry->d_inode) {
         ret = vfs_create(dir->d_inode, dentry, mode, ni);
-        up(&dir->d_inode->i_sem);
+        semaphore_up(&dir->d_inode->i_sem);
         dentry_put(ni->path.dentry);
         ni->path.dentry = dentry;
         if (0 != ret) {
@@ -427,7 +427,7 @@ int path_open_namei(const char* path, int flags, int mode, namei_t* ni) {
 
     // 上述是文件不存在的逻辑
     // 此处是文件存在的情况下的处理逻辑
-    up(&dir->d_inode->i_sem);
+    semaphore_up(&dir->d_inode->i_sem);
 
     if ((flags & O_EXCL) == 0) {
         panic("unsupport O_EXCL");
index 833ad06b68e8c671e59baaf31ab653ea72912d51..dc42c6e2b3806d5498119a2afb184879a9ba728e 100644 (file)
--- a/fs/vfs.h
+++ b/fs/vfs.h
@@ -12,7 +12,7 @@
 #include <atomic.h>
 #include <list.h>
 #include <page.h>
-#include <semaphore.h>
+#include <sync.h>
 #include <types.h>
 
 typedef struct qstr {
index 24347936006452fbfada530d17d5f7830b2f834c..5d999e4b9c590d863f0da38d53568ba1f16539ea 100644 (file)
@@ -45,7 +45,7 @@ ssize_t vfs_generic_file_write(file_t* file, const char* buf, size_t size, loff_
     // assert(mapping->a_ops->read_page != NULL);
     // assert(mapping->a_ops->write_page != NULL);
 
-    down(&inode->i_sem);
+    semaphore_down(&inode->i_sem);
 
     while (size > 0) {
         uint32_t index = pos >> PAGE_SHIFT;       // 所在页号索引
@@ -80,7 +80,7 @@ ssize_t vfs_generic_file_write(file_t* file, const char* buf, size_t size, loff_
     }
 
     // end:
-    up(&inode->i_sem);
+    semaphore_up(&inode->i_sem);
     *p_pos = pos;
 
     //
index b3bfcf09bb28063acb5ee6818efedc76bc927f44..7ce713bfaa38a04fc5b63fde0c8e5e4906acf095 100644 (file)
@@ -10,7 +10,7 @@
 #pragma once
 
 #include <atomic.h>
-#include <completion.h>
+#include <sync.h>
 #include <fs.h>
 #include <mm.h>
 #include <page.h>
index 63468838e6925ab56879cbbb40fe6361479bcbd1..dc264a2ce23eba273f9b6aae0bd35278f34f5fdd 100644 (file)
 
 #include <wait.h>
 
-typedef struct completion {
+typedef struct deprecated_completion {
     unsigned int done;
     wait_queue_head_t wait;
 
     // 仅用于调试
     char* name;
-} completion_t;
+} deprecated_completion_t;
 
-#define COMPLETION_INITIALIZER(x) {0, WAIT_QUEUE_HEAD_INITIALIZER(x.wait)}
+#define DEPRECATED_COMPLETION_INITIALIZER(x) {0, WAIT_QUEUE_HEAD_INITIALIZER(x.wait)}
 
-void init_completion(completion_t* x);
+void init_deprecated_completion(deprecated_completion_t* x);
 
-void wait_completion(completion_t* x);
+void wait_deprecated_completion(deprecated_completion_t* x);
 
 // 一次只唤醒一个进程
-void complete(completion_t* x);
+void complete(deprecated_completion_t* x);
index 63078d584d59969fd878fffbf388c934506526ea..7b5a63a29da14bcdaf9d5ef9785246e38673b7c8 100644 (file)
@@ -13,7 +13,7 @@
 #include <completion.h>
 #include <fs.h>
 #include <list.h>
-#include <semaphore.h>
+#include <sync.h>
 
 typedef enum {
     DISK_REQ_IDENTIFY,
index d811a3882d17c93cbb3f93ff08c13450570b81fd..0543928829858ddb56ae17745e8d3303d3ca86b2 100644 (file)
 
 #include <list.h>
 
-typedef struct semaphore {
+typedef struct deprecated_semaphore {
     volatile unsigned int cnt;
     list_head_t wait_list;
-} semaphore_t;
+} deprecated_semaphore_t;
 
 #define SEMAPHORE_INITIALIZER(name, n) {.cnt = (n), .wait_list = LIST_HEAD_INIT((name).wait_list)}
 
-void semaphore_init(semaphore_t* s, unsigned int v);
+void deprecated_semaphore_init(deprecated_semaphore_t* s, unsigned int v);
 
 // down
 // 如果s->cnt > 0不会立即重新调度进程
 // 如果s->cnt == 0 会重新调度进程
-volatile void down(semaphore_t* s);
+volatile void down(deprecated_semaphore_t* s);
 
 // up
 // 只会唤醒进程,但不会立即重新调度进程
-volatile void up(semaphore_t* s);
+volatile void up(deprecated_semaphore_t* s);
 
-typedef semaphore_t mutex_t;
+typedef deprecated_semaphore_t deprecated_mutex_t;
 
 #define MUTEX_INITIALIZER(name) {.cnt = (1), .wait_list = LIST_HEAD_INIT((name).wait_list)}
 
@@ -40,6 +40,6 @@ typedef semaphore_t mutex_t;
         (ptr)->cnt = 1;                      \
         INIT_LIST_HEAD(&((ptr)->wait_list)); \
     } while (0)
-void mutex_init(mutex_t*);
-void mutex_lock(mutex_t*);
-void mutex_unlock(mutex_t*);
+void deprecated_mutex_init(deprecated_mutex_t*);
+void deprecated_mutex_lock(deprecated_mutex_t*);
+void deprecated_mutex_unlock(deprecated_mutex_t*);
diff --git a/include/sync.h b/include/sync.h
new file mode 100644 (file)
index 0000000..3dcd85c
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * ------------------------------------------------------------------------
+ *   File Name: sync.h
+ *      Author: Zhao Yanbai
+ *              2026-08-13 06:39:47 Thursday CST
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+
+#pragma once
+
+#include <waitq.h>
+
+// WAIT EVENT
+
+#define wait_event(waitq, condition) \
+    do {                             \
+        assert(waitq != NULL);       \
+        unsigned long __we_eflags;   \
+        irq_save(__we_eflags);       \
+        while (!(condition)) {       \
+            waitq_sleep(waitq);      \
+        }                            \
+        irq_restore(__we_eflags);    \
+    } while (0)
+
+// SEMAPHORE
+typedef struct semaphore semaphore_t;
+
+struct semaphore {
+    volatile int cnt;
+    waitq_t waitq;
+};
+
+void semaphore_init(semaphore_t* semaphore, int cnt);
+
+void semaphore_down(semaphore_t* semaphore);
+
+void semaphore_up(semaphore_t* semaphore);
+
+// MUTEX
+typedef semaphore_t mutex_t;
+
+void mutex_init(mutex_t* mutex);
+
+void mutex_lock(mutex_t* mutex);
+
+void mutex_unlock(mutex_t* mutex);
+
+// COMPLETION
+typedef struct completion completion_t;
+
+struct completion {
+    volatile int done;
+    waitq_t waitq;
+
+    // 仅用于调试
+    char* name;
+};
+
+void completion_init(completion_t* completion);
+
+void completion_wait(completion_t* completion);
+
+void completion_complete(completion_t* completion);
index b46a8dacb02f7c583174617de4f35167add49d91..1232ffd727ca2e63452471fe833e9a1ef7ee5c22 100644 (file)
@@ -87,6 +87,8 @@ typedef union task_union {
 
         list_head_t ready_list;  // 就绪队列
 
+        list_head_t waitq_list;
+
         list_head_t pend;  // 某些条件串成一个链表
 
         // list_head_t wait;
index d8eb053bac47e45f70d486753ef9103aba90b17c..2891ade1c5f0b11f0b9ab285c99b3cad92e27c08 100644 (file)
@@ -10,7 +10,7 @@
 #pragma once
 
 #include <types.h>
-#include <wait.h>
+#include <sync.h>
 #include <semaphore.h>
 
 #define TTY_MAX_NAME_LEN 32
@@ -31,7 +31,7 @@ struct tty {
     int ib_head;
     int ib_tail;
     mutex_t ib_mutex;
-    wait_queue_head_t ib_wait;
+    waitq_t ib_wait;
 
     tty_ops_t* ops;
     void* private;
index 80e8f07d5360cd96b4afad616d2ec23f35c08f0c..a8893da53e93a43140298a751d23bb526a9ec41b 100644 (file)
@@ -78,10 +78,10 @@ void __wake_up(wait_queue_head_t* head, int nr);
         }                                                \
     } while (0)
 
-#define wait_event(head, condition)      \
-    do {                                 \
-        if ((condition)) {               \
-            break;                       \
-        }                                \
-        __wait_event(head, (condition)); \
+#define deprecated_wait_event(head, condition) \
+    do {                                       \
+        if ((condition)) {                     \
+            break;                             \
+        }                                      \
+        __wait_event(head, (condition));       \
     } while (0)
diff --git a/include/waitq.h b/include/waitq.h
new file mode 100644 (file)
index 0000000..b1c4fde
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * ------------------------------------------------------------------------
+ *   File Name: waitq.h
+ *      Author: Zhao Yanbai
+ *              2026-08-13 06:39:38 Thursday CST
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+
+#pragma once
+
+#include <list.h>
+
+typedef struct waitq waitq_t;
+
+struct waitq {
+    list_head_t list;
+};
+
+void waitq_init(waitq_t* waitq);
+
+// 以下接口
+// 在调用前需要保证已经关闭中断
+// 在返回时中断状态仍然处于关闭状态
+void waitq_sleep(waitq_t* waitq);
+
+void waitq_wakeup(waitq_t* waitq, int cnt);
+
+void waitq_wakeup_one(waitq_t* waitq);
+
+void waitq_wakeup_all(waitq_t* waitq);
\ No newline at end of file
index 26023cd978ba4cc8b618f20a52282061d73ba952..101dd3335563b917102ff229e1956e60325410d5 100644 (file)
@@ -10,7 +10,7 @@
 #include <completion.h>
 #include <sched.h>
 
-void wait_completion(completion_t* x) {
+void wait_deprecated_completion(deprecated_completion_t* x) {
     uint32_t eflags;
     DECLARE_WAIT_QUEUE_ENTRY(__wait, current);
 
@@ -33,7 +33,7 @@ void wait_completion(completion_t* x) {
     }
 }
 
-void complete(completion_t* x) {
+void complete(deprecated_completion_t* x) {
     uint32_t iflags;
     irq_save(iflags);
     x->done++;
@@ -41,7 +41,7 @@ void complete(completion_t* x) {
     irq_restore(iflags);
 }
 
-void init_completion(completion_t* x) {
+void init_deprecated_completion(deprecated_completion_t* x) {
     x->done = 0;
     init_wait_queue_head(&x->wait);
 
index 0a539b0c97be386adc14e1f2b69ba91e8a83fe0d..1d10cd1d7e01ad4da50f07519f7d537e9c024900 100644 (file)
@@ -33,6 +33,7 @@ int do_fork(pt_regs_t* regs, unsigned long flags) {
 
     INIT_LIST_HEAD(&tsk->list);
     INIT_LIST_HEAD(&tsk->ready_list);
+    INIT_LIST_HEAD(&tsk->waitq_list);
     INIT_LIST_HEAD(&tsk->pend);
     unsigned long iflags;
     irq_save(iflags);
index 096ac5f88f284e67a8a687e57f53ab71663aa77d..be999f6783ef1bcf9526cf2493279e38f884be08 100644 (file)
@@ -23,12 +23,12 @@ typedef struct semaphore_waiter {
 
 } semaphore_waiter_t;
 
-void semaphore_init(semaphore_t* s, unsigned int v) {
+void deprecated_semaphore_init(deprecated_semaphore_t* s, unsigned int v) {
     s->cnt = v;
     INIT_LIST_HEAD(&(s->wait_list));
 }
 
-volatile void down(semaphore_t* s) {
+volatile void down(deprecated_semaphore_t* s) {
     unsigned long iflags;
     irq_save(iflags);
 
@@ -52,7 +52,7 @@ volatile void down(semaphore_t* s) {
     }
 }
 
-volatile void up(semaphore_t* s) {
+volatile void up(deprecated_semaphore_t* s) {
     unsigned long iflags;
     irq_save(iflags);
 
@@ -80,12 +80,12 @@ volatile void up(semaphore_t* s) {
     }
 }
 
-void mutex_init(mutex_t* s) {
+void deprecated_mutex_init(deprecated_mutex_t* s) {
     INIT_MUTEX(s);
 }
-void mutex_lock(semaphore_t* s) {
+void deprecated_mutex_lock(deprecated_mutex_t* s) {
     down(s);
 }
-void mutex_unlock(semaphore_t* s) {
+void deprecated_mutex_unlock(deprecated_mutex_t* s) {
     up(s);
 }
diff --git a/kernel/sync.c b/kernel/sync.c
new file mode 100644 (file)
index 0000000..29aa347
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * ------------------------------------------------------------------------
+ *   File Name: sync.c
+ *      Author: Zhao Yanbai
+ *              2026-08-13 06:39:52 Thursday CST
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+
+#include <sync.h>
+#include <irq.h>
+#include <system.h>
+
+// SEMAPHORE
+void semaphore_init(semaphore_t* semaphore, int cnt) {
+    assert(semaphore != NULL);
+    semaphore->cnt = cnt;
+    waitq_init(&semaphore->waitq);
+}
+
+void semaphore_down(semaphore_t* semaphore) {
+    assert(semaphore != NULL);
+
+    unsigned long eflags;
+    irq_save(eflags);
+
+    // 此处semaphore->cnt其实是有可能为负数的,因为可能直接被初始化为负数
+    while (true) {
+        if (semaphore->cnt > 0) {
+            semaphore->cnt--;
+            break;
+        }
+
+        waitq_sleep(&semaphore->waitq);
+    }
+
+    irq_restore(eflags);
+}
+
+void semaphore_up(semaphore_t* semaphore) {
+    assert(semaphore != NULL);
+    unsigned long eflags;
+    irq_save(eflags);
+
+    semaphore->cnt++;
+
+    waitq_wakeup_one(&semaphore->waitq);
+
+    irq_restore(eflags);
+}
+
+// MUTEX
+
+void mutex_init(mutex_t* mutex) {
+    assert(mutex != NULL);
+    semaphore_init(mutex, 1);
+}
+
+void mutex_lock(mutex_t* mutex) {
+    assert(mutex != NULL);
+    semaphore_down(mutex);
+}
+
+void mutex_unlock(mutex_t* mutex) {
+    assert(mutex != NULL);
+    semaphore_up(mutex);
+}
+
+// COMPLETION
+
+void completion_init(completion_t* completion) {
+    assert(completion != NULL);
+    completion->done = 0;
+    waitq_init(&completion->waitq);
+    completion->name = NULL;
+}
+
+void completion_wait(completion_t* completion) {
+    assert(completion != NULL);
+
+    unsigned long eflags;
+    irq_save(eflags);
+
+    while (completion->done == 0) {
+        waitq_sleep(&completion->waitq);
+    }
+
+    assert(completion->done > 0);
+    completion->done--;
+
+    irq_restore(eflags);
+}
+
+void completion_complete(completion_t* completion) {
+    assert(completion != NULL);
+
+    unsigned long eflags;
+    irq_save(eflags);
+
+    completion->done++;
+    waitq_wakeup_all(&completion->waitq);
+
+    irq_restore(eflags);
+}
\ No newline at end of file
index f344f8c57ba781a1534d4c249914e138922db59e..6babad78ee7394550603ea36f949444e7cf77258 100644 (file)
@@ -8,7 +8,7 @@
  */
 
 #include <disk.h>
-#include <completion.h>
+#include <sync.h>
 #include <sata.h>
 // #include
 
@@ -31,7 +31,7 @@ int send_disk_request(disk_request_t* req) {
         assert(((((uint32_t)req->buf) & (_64K - 1)) + size) <= _64K);
     }
 
-    init_completion(&req->completion);
+    completion_init(&req->completion);
 
     //
     mutex_lock(&disk_request_queue.mutex);
@@ -41,10 +41,10 @@ int send_disk_request(disk_request_t* req) {
     mutex_unlock(&disk_request_queue.mutex);
 
     //
-    up(&disk_request_queue.sem);
+    semaphore_up(&disk_request_queue.sem);
 
     //
-    wait_completion(&req->completion);
+    completion_wait(&req->completion);
 
     return 0;
 }
@@ -58,16 +58,16 @@ void disk_request(disk_request_t* req) {
     sata_device_t* sata = &sata_devices[0];
 
     //
-    init_completion(&sata->completion);
+    completion_init(&sata->completion);
 
     sata_dma_read(sata, req->pos, req->count, (vaddr_t)req->buf);
 
-    wait_completion(&sata->completion);
+    completion_wait(&sata->completion);
 }
 
 void disk_task_entry() {
     while (1) {
-        down(&disk_request_queue.sem);
+        semaphore_down(&disk_request_queue.sem);
 
         for (int i = 0; i < 123; i++) {
             asm("hlt");
@@ -84,7 +84,7 @@ void disk_task_entry() {
         disk_request(req);
 
         //
-        complete(&req->completion);
+        completion_complete(&req->completion);
 
         disk_request_queue.completed_count++;  // 不需要保护
 
index 6b549fb7d879ea909a39428da34d024cdd9d5541..614d04ffeab0821933ed38ba4207070e24f56e2b 100644 (file)
@@ -7,7 +7,7 @@
  * ------------------------------------------------------------------------
  */
 
-#include <completion.h>
+#include <sync.h>
 #include <disk.h>
 #include <ide.h>
 #include <sched.h>
@@ -117,7 +117,7 @@ void disk_task_entry(void* arg) {
         }
 
         const bool pio_mode = false;
-        init_completion(&ide_ctrl->intr_complete);
+        completion_init(&ide_ctrl->intr_complete);
 
         switch (r->command) {
         case DISK_REQ_IDENTIFY:
@@ -152,7 +152,7 @@ void disk_task_entry(void* arg) {
         int ret = 0;
         if (!pio_mode) {
             // 等待硬盘中断
-            wait_completion(&ide_ctrl->intr_complete);
+            completion_wail(&ide_ctrl->intr_complete);
 
             if ((ide_ctrl->status & (ATA_STATUS_BSY | ATA_STATUS_BSY | ATA_STATUS_WF)) != 0) {
                 printk("IDE status %02X error for drv %u pos %lu count %u\n", ide_ctrl->status, drvid, pos, r->count);
@@ -167,7 +167,7 @@ void disk_task_entry(void* arg) {
 
         if (r->bb != 0) {
             r->bb->uptodate = 1;
-            complete(&r->bb->io_done);
+            completion_complete(&r->bb->io_done);
         }
 
         r->ret = ret;
index 31cc48640b423a916001dd29e72213551ce755b0..a6a9c7c37f1ebe1eeaa37fd1bd081d1fffc96a25 100644 (file)
@@ -30,7 +30,7 @@ void init_ttys() {
         tty->ib_head = 0;
         tty->ib_tail = 0;
         mutex_init(&tty->ib_mutex);
-        init_wait_queue_head(&tty->ib_wait);
+        waitq_init(&tty->ib_wait);
 
         tty->ops = &vt_tty_ops;
 
@@ -134,7 +134,7 @@ int tty_input(tty_t* tty, uint8_t c) {
     irq_restore(eflags);
 
     // 唤醒读进程
-    wake_up(&tty->ib_wait);
+    waitq_wakeup_all(&tty->ib_wait);
 
     // 目前先总是回显
     tty_write(tty, (const char*)&c, 1);
diff --git a/kernel/waitq.c b/kernel/waitq.c
new file mode 100644 (file)
index 0000000..ad8ea70
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * ------------------------------------------------------------------------
+ *   File Name: waitq.c
+ *      Author: Zhao Yanbai
+ *              2026-08-13 06:39:43 Thursday CST
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+
+#include <waitq.h>
+#include <sched.h>
+
+void waitq_init(waitq_t* waitq) {
+    assert(waitq != NULL);
+    list_init(&waitq->list);
+}
+
+void waitq_sleep(waitq_t* waitq) {
+    task_t* task = current;
+
+    assert(waitq != NULL);
+    assert(task != NULL);
+    assert(task->state != TASK_WAIT);
+
+    list_add_tail(&task->waitq_list, &waitq->list);
+    task_set_wait(task);
+
+    schedule();
+}
+
+void waitq_wakeup(waitq_t* waitq, int cnt) {
+    assert(waitq != NULL);
+    assert(cnt >= 0);
+
+    for (int i = 0; ((i < cnt) || (cnt == 0)); i++) {
+        if (list_empty(&waitq->list)) {
+            break;
+        }
+
+        task_t* task = list_first_entry(&waitq->list, task_t, waitq_list);
+        assert(task != NULL);
+        assert(task->state == TASK_WAIT);
+
+        list_del_init(&task->waitq_list);
+
+        task_set_ready(task);
+    }
+}
+
+void waitq_wakeup_one(waitq_t* waitq) {
+    assert(waitq != NULL);
+    waitq_wakeup(waitq, 1);
+}
+
+void waitq_wakeup_all(waitq_t* waitq) {
+    assert(waitq != NULL);
+    waitq_wakeup(waitq, 0);
+}
\ No newline at end of file