#include <ide.h>
#include <irq.h>
-#include <semaphore.h>
+#include <sync.h>
#include <task.h>
-#include <wait.h>
/*
高技术配置(英语:Advanced Technology Attachment,简称“ATA”)与由集成驱动电子设备(英语:Integrated Drive
// 所以就移除了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) {
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);
#include <disk.h>
#include <io.h>
#include <pci.h>
-#include <semaphore.h>
#include <system.h>
#include <task.h>
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);
//
}
- complete(&sata->completion);
+ completion_complete(&sata->completion);
port->interrupt_status = interrupt_status;
}
#include <ahci.h>
#include <types.h>
-#include <completion.h>
+#include <sync.h>
#define SATA_SIGNATURE_ATA 0x00000101
#define SATA_SIGNATURE_ATAPI 0xEB140101
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
// wait on free list
// TODO
assert(0);
- // wait_on(&s->waitq);
+ // waitq_sleep(&s->waitq);
goto again;
}
// 虽然此时该bbuffer_t上的ref_count为0但其可能还有I/O操作没有完成
// 因为可能有的进程调用了write、read后再直接调用brelse
// 所以需要在此等待其结束
- wait_completion(&b->io_done);
+ completion_wait(&b->io_done);
// 找到了
b->block = block;
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);
// TODO
assert(0);
- // wake_up(&s->waitq);
+ // waitq_wakeup_all(&s->waitq);
}
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;
}
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;
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);
#include <errno.h>
#include <mm.h>
-#include <semaphore.h>
+#include <sync.h>
#include <string.h>
#include <system.h>
#include <vfs.h>
assert(parent->d_inode != NULL);
inode_t* dir = parent->d_inode;
- down(&dir->i_sem);
+ semaphore_down(&dir->i_sem);
// 在获得信号量后,需要再上cache中查找一遍
// 因为这个过程中当前进程可能会睡眠,当被唤醒后,其它进程已经在内存准备好了
assert(0 == ret);
if (NULL != *dentry) {
- up(&dir->i_sem);
+ semaphore_up(&dir->i_sem);
return ret;
}
// }
}
- up(&dir->i_sem);
+ semaphore_up(&dir->i_sem);
return ret;
}
assert(dentry == NULL);
}
- up(&ni.path.dentry->d_inode->i_sem);
+ semaphore_up(&ni.path.dentry->d_inode->i_sem);
return ret;
}
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) {
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) {
// 上述是文件不存在的逻辑
// 此处是文件存在的情况下的处理逻辑
- up(&dir->d_inode->i_sem);
+ semaphore_up(&dir->d_inode->i_sem);
if ((flags & O_EXCL) == 0) {
panic("unsupport O_EXCL");
#include <atomic.h>
#include <list.h>
#include <page.h>
-#include <semaphore.h>
+#include <sync.h>
#include <types.h>
typedef struct qstr {
// 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; // 所在页号索引
}
// end:
- up(&inode->i_sem);
+ semaphore_up(&inode->i_sem);
*p_pos = pos;
//
#pragma once
#include <atomic.h>
-#include <completion.h>
+#include <sync.h>
#include <fs.h>
#include <mm.h>
#include <page.h>
#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);
#include <completion.h>
#include <fs.h>
#include <list.h>
-#include <semaphore.h>
+#include <sync.h>
typedef enum {
DISK_REQ_IDENTIFY,
#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)}
(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*);
--- /dev/null
+/*
+ * ------------------------------------------------------------------------
+ * 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);
list_head_t ready_list; // 就绪队列
+ list_head_t waitq_list;
+
list_head_t pend; // 某些条件串成一个链表
// list_head_t wait;
#pragma once
#include <types.h>
-#include <wait.h>
+#include <sync.h>
#include <semaphore.h>
#define TTY_MAX_NAME_LEN 32
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;
} \
} 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)
--- /dev/null
+/*
+ * ------------------------------------------------------------------------
+ * 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
#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);
}
}
-void complete(completion_t* x) {
+void complete(deprecated_completion_t* x) {
uint32_t iflags;
irq_save(iflags);
x->done++;
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);
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);
} 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);
}
}
-volatile void up(semaphore_t* s) {
+volatile void up(deprecated_semaphore_t* s) {
unsigned long iflags;
irq_save(iflags);
}
}
-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);
}
--- /dev/null
+/*
+ * ------------------------------------------------------------------------
+ * 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
*/
#include <disk.h>
-#include <completion.h>
+#include <sync.h>
#include <sata.h>
// #include
assert(((((uint32_t)req->buf) & (_64K - 1)) + size) <= _64K);
}
- init_completion(&req->completion);
+ completion_init(&req->completion);
//
mutex_lock(&disk_request_queue.mutex);
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;
}
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");
disk_request(req);
//
- complete(&req->completion);
+ completion_complete(&req->completion);
disk_request_queue.completed_count++; // 不需要保护
* ------------------------------------------------------------------------
*/
-#include <completion.h>
+#include <sync.h>
#include <disk.h>
#include <ide.h>
#include <sched.h>
}
const bool pio_mode = false;
- init_completion(&ide_ctrl->intr_complete);
+ completion_init(&ide_ctrl->intr_complete);
switch (r->command) {
case DISK_REQ_IDENTIFY:
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);
if (r->bb != 0) {
r->bb->uptodate = 1;
- complete(&r->bb->io_done);
+ completion_complete(&r->bb->io_done);
}
r->ret = ret;
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;
irq_restore(eflags);
// 唤醒读进程
- wake_up(&tty->ib_wait);
+ waitq_wakeup_all(&tty->ib_wait);
// 目前先总是回显
tty_write(tty, (const char*)&c, 1);
--- /dev/null
+/*
+ * ------------------------------------------------------------------------
+ * 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