From 83bf1481eece451f5eeaefa3ebf30c13db713e7a Mon Sep 17 00:00:00 2001 From: acevest Date: Sat, 20 May 2023 16:06:06 +0800 Subject: [PATCH] =?utf8?q?disk=20request=E8=88=8D=E5=BC=83completion?= =?utf8?q?=E6=96=B9=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- drivers/ata.c | 5 ++- drivers/ide.c | 11 +++++- include/disk.h | 17 +++++---- include/semaphore.h | 6 ++- kernel/semaphore.c | 8 ++++ kernel/task_disk.c | 89 ++++++++++++++++++++++----------------------- 6 files changed, 78 insertions(+), 58 deletions(-) diff --git a/drivers/ata.c b/drivers/ata.c index bef4eef..b9f167d 100644 --- a/drivers/ata.c +++ b/drivers/ata.c @@ -105,6 +105,8 @@ void ide_ata_init() { } void ata_init() { + // 初始化hard_disk与中断函数之间的信号量 + disk_request_t r; r.dev = 0; r.buf = (void *)identify; @@ -144,6 +146,7 @@ void ata_init() { } } +#if 0 void ata_read_identify_old(int dev) { // 这里所用的dev是逻辑编号 ATA0、ATA1下的Master、Salve的dev分别为0,1,2,3 // void send_disk_request(); // send_disk_request(); @@ -196,7 +199,7 @@ void ata_read_identify_old(int dev) { // 这里所用的dev是逻辑编号 ATA0 printk("%04x ", p[i]); } } - +#endif // ATA_CMD_READ_DMA_EXT void ata_dma_read_ext(int dev, uint64_t pos, uint16_t count, void *dest) { // Intel® diff --git a/drivers/ide.c b/drivers/ide.c index f66e055..ed188e7 100644 --- a/drivers/ide.c +++ b/drivers/ide.c @@ -13,8 +13,8 @@ #include // #include +#include #include -// #include // #include // #include #include @@ -538,12 +538,16 @@ void ide_irq() { ide_intr_func(); } // void ata_read_identify(int dev); +#if 1 +extern semaphore_t disk_intr_sem; +#else DECLARE_WAIT_QUEUE_HEAD(ide_wait_queue_head); void sleep_on_ide() { sleep_on(&ide_wait_queue_head); } void prepare_to_wait_on_ide() { ide_pci_controller.done = 0; } void wait_on_ide() { wait_event(&ide_wait_queue_head, ide_pci_controller.done); } +#endif extern void *mbr_buf; uint8_t ata_pci_bus_status(); @@ -554,9 +558,12 @@ void ide_irq_handler(unsigned int irq, pt_regs_t *regs, void *devid) { printk("ide irq %d handler pci status after interrupt: %x\n", irq, ata_pci_bus_status()); +#if 1 + up(&disk_intr_sem); +#else ide_pci_controller.done = 1; - wake_up(&ide_wait_queue_head); +#endif } void ide_init() { diff --git a/include/disk.h b/include/disk.h index 15f4338..6e56080 100644 --- a/include/disk.h +++ b/include/disk.h @@ -26,14 +26,15 @@ typedef struct disk_request { void *buf; // 到的缓冲区 disk_request_cmd_t command; // 命令 list_head_t list; - // wait_queue_head_t wait; // 等待队列 - // 驱动器完全有可能在进程在进程睡眠到等待队列前返回数据并执行唤醒操作 - // 这时等待队列上无进程,就相当于不执行任何操作 - // 然后进程再睡眠到等待队列上,就会造成永远无法唤醒该进程 - // 因此要添加一个字段,标志驱动器已经对该请求做过唤醒操作 - // 进程在睡眠前需要检查该字段 - // int done; - completion_t completion; + // // wait_queue_head_t wait; // 等待队列 + // // 驱动器完全有可能在进程在进程睡眠到等待队列前返回数据并执行唤醒操作 + // // 这时等待队列上无进程,就相当于不执行任何操作 + // // 然后进程再睡眠到等待队列上,就会造成永远无法唤醒该进程 + // // 因此要添加一个字段,标志驱动器已经对该请求做过唤醒操作 + // // 进程在睡眠前需要检查该字段 + // // int done; + // completion_t completion; + semaphore_t sem; } disk_request_t; typedef struct { diff --git a/include/semaphore.h b/include/semaphore.h index 565a3f4..7d0c139 100644 --- a/include/semaphore.h +++ b/include/semaphore.h @@ -21,7 +21,11 @@ typedef struct semaphore { #define SEMAPHORE_INITIALIZER(name, n) \ { .cnt = (n), .wait_list = LIST_HEAD_INIT((name).wait_list) } -#define DECLARE_MUTEX(name) semaphore_t name = SEMAPHORE_INITIALIZER(name, 1) +void semaphore_init(semaphore_t *s, unsigned int v); void down(semaphore_t *s); void up(semaphore_t *s); + +#define DECLARE_MUTEX(name) semaphore_t name = SEMAPHORE_INITIALIZER(name, 1) +void mutex_lock(semaphore_t *); +void mutex_unlock(semaphore_t *); \ No newline at end of file diff --git a/kernel/semaphore.c b/kernel/semaphore.c index 55360e8..36c8484 100644 --- a/kernel/semaphore.c +++ b/kernel/semaphore.c @@ -21,6 +21,11 @@ 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); @@ -71,3 +76,6 @@ volatile void up(semaphore_t *s) { irq_restore(iflags); } + +void mutex_lock(semaphore_t *s) { down(s); } +void mutex_unlock(semaphore_t *s) { up(s); } \ No newline at end of file diff --git a/kernel/task_disk.c b/kernel/task_disk.c index e6960df..fc85b5c 100644 --- a/kernel/task_disk.c +++ b/kernel/task_disk.c @@ -11,15 +11,21 @@ #include #include -disk_request_queue_t disk_request_queue; // = {.count = 0, - // .sem = SEMAPHORE_INITIALIZER(disk_request_queue.sem, 0), - // .list = LIST_HEAD_INIT(disk_request_queue.list)}; +disk_request_queue_t disk_request_queue; + +// task disk与中断函数之间的信号量 +semaphore_t disk_intr_sem; + +DECLARE_MUTEX(disk_request_mutex); void disk_init() { disk_request_queue.count = 0; - disk_request_queue.sem.cnt = 0; - INIT_LIST_HEAD(&disk_request_queue.sem.wait_list); INIT_LIST_HEAD(&disk_request_queue.list); + // disk_request_queue.sem.cnt = 0; + // INIT_LIST_HEAD(&disk_request_queue.sem.wait_list); + semaphore_init(&disk_request_queue.sem, 0); + + semaphore_init(&disk_intr_sem, 0); } void send_disk_request(disk_request_t *r) { @@ -27,6 +33,9 @@ void send_disk_request(disk_request_t *r) { panic("null disk request"); } + // 这个用来让task_disk唤醒自己 + semaphore_init(&r->sem, 0); + // 校验pos,和pos+count是否大于硬盘返回的最大LBA48 // ... @@ -36,70 +45,61 @@ void send_disk_request(disk_request_t *r) { panic("disk DMA read cross 64K"); } - // INIT_LIST_HEAD(&r->wait.task_list); - // r->done = 0; - - init_completion(&r->completion); - - // r.pos = pos; - // r.count = count; - // r.buf = kmalloc(512, 0); - // r.command = DISK_REQ_IDENTIFY; - // INIT_LIST_HEAD(&r.wait.task_list); - // r.done = 0; - - // printk("do send disk request: %d %x %x %x\n", list_empty(&disk_request_queue.sem.wait_list), - // &disk_request_queue.sem.wait_list, disk_request_queue.sem.wait_list.next, - // disk_request_queue.sem.wait_list.prev); - +#if 1 + mutex_lock(&disk_request_mutex); + list_add_tail(&r->list, &disk_request_queue.list); + mutex_unlock(&disk_request_mutex); +#else // 发送命令 unsigned long flags; irq_save(flags); list_add_tail(&r->list, &disk_request_queue.list); irq_restore(flags); +#endif // 唤醒task_disk - // printk("up sem\n"); up(&disk_request_queue.sem); - // 等待task_dist结束 - // printk("wait event\n"); - // wait_event(&r->wait, r->done != 0); - wait_completion(&r->completion); - - // printk("wait finished\n"); + // 等待被task_disk唤醒 + down(&r->sem); } void disk_task_entry() { int r_cnt = 0; while (1) { - void prepare_to_wait_on_ide(); - prepare_to_wait_on_ide(); - // printk("wait for new hard disk request\n"); down(&disk_request_queue.sem); // printk("hard disk request: %d\n", disk_request_queue.count++); +#if 1 + mutex_lock(&disk_request_mutex); + disk_request_t *r; + r = list_first_entry(&disk_request_queue.list, disk_request_t, list); + if (NULL == r) { + panic("no disk request"); + } + + list_del(&r->list); + mutex_unlock(&disk_request_mutex); +#else unsigned long flags; irq_save(flags); disk_request_t *r; if (list_empty(&disk_request_queue.list)) { - } else { - r = list_first_entry(&disk_request_queue.list, disk_request_t, list); - if (NULL == r) { - panic("no disk request"); - } - - printk("disk request[%d]: dev %d pos %ld count %d cmd %d\n", r_cnt++, r->dev, r->pos, r->count, r->command); + panic("disk request should not empty"); } - irq_restore(flags); - + r = list_first_entry(&disk_request_queue.list, disk_request_t, list); if (NULL == r) { - continue; + panic("no disk request"); } + printk("disk request[%d]: dev %d pos %ld count %d cmd %d\n", r_cnt++, r->dev, r->pos, r->count, r->command); + list_del(&r->list); + irq_restore(flags); +#endif + switch (r->command) { case DISK_REQ_IDENTIFY: assert(r->count == 1); @@ -117,8 +117,7 @@ void disk_task_entry() { } // 等待硬盘中断 - void wait_on_ide(); - wait_on_ide(); + down(&disk_intr_sem); // 读数据 if (DISK_REQ_IDENTIFY == r->command) { @@ -127,8 +126,6 @@ void disk_task_entry() { } // 唤醒等待该请求的进程 - // r->done = 1; - // wake_up(&r->wait); - complete(&r->completion); + up(&(r->sem)); } } -- 2.44.0