From: acevest Date: Tue, 17 Oct 2023 07:58:26 +0000 (+0800) Subject: 简化down 和 up的逻辑 X-Git-Url: http://zhaoyanbai.com/repos/?a=commitdiff_plain;h=52986f7644394a734cb0c8acd3026fceaa8191e6;p=kernel.git 简化down 和 up的逻辑 --- diff --git a/drivers/block.c b/drivers/block.c index 4ce1bde..baacea9 100644 --- a/drivers/block.c +++ b/drivers/block.c @@ -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); } diff --git a/include/semaphore.h b/include/semaphore.h index f76b5d5..7f29c1a 100644 --- a/include/semaphore.h +++ b/include/semaphore.h @@ -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 { \ diff --git a/include/task.h b/include/task.h index 4c3f74e..1882723 100644 --- a/include/task.h +++ b/include/task.h @@ -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; // 时间片到了,但是没有被换出,又重新执行的次数 diff --git a/kernel/semaphore.c b/kernel/semaphore.c index 199b17c..9014f46 100644 --- a/kernel/semaphore.c +++ b/kernel/semaphore.c @@ -10,6 +10,61 @@ #include #include +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); }