From a27d8832510043e8a583f4a47df2b2a5d5f7bd56 Mon Sep 17 00:00:00 2001 From: acevest Date: Sun, 22 Jun 2014 22:56:54 +0800 Subject: [PATCH] fix bug in semaphore --- drivers/console.c | 34 ++++++++++++++++++++++++++++++ drivers/console.h | 26 +++++++++++++++++++++++ drivers/keyboard.c | 51 +++++++++++++-------------------------------- include/list.h | 7 +++++++ include/sched.h | 3 +-- include/semaphore.h | 4 ++-- include/wait.h | 9 ++++---- kernel/sched.c | 14 ++----------- kernel/semaphore.c | 6 ++++-- kernel/wait.c | 13 ++++++++++++ mm/kmalloc.c | 31 +-------------------------- setup/setup.c | 4 ++++ 12 files changed, 113 insertions(+), 89 deletions(-) create mode 100644 drivers/console.c create mode 100644 drivers/console.h diff --git a/drivers/console.c b/drivers/console.c new file mode 100644 index 0000000..c393b73 --- /dev/null +++ b/drivers/console.c @@ -0,0 +1,34 @@ +/* + * ------------------------------------------------------------------------ + * File Name: console.c + * Author: Zhao Yanbai + * Sun Jun 22 18:50:13 2014 + * Description: none + * ------------------------------------------------------------------------ + */ + +#include +#include + +cnsl_queue_t cnsl_rd_q; +cnsl_queue_t cnsl_wr_q; +cnsl_queue_t cnsl_sc_q; + +static void cnsl_queue_init(cnsl_queue_t *cq) +{ + memset((void *)cq, 0, sizeof(*cq)); + + cq->head = 0; + cq->tail = 0; + init_wait_queue(&cq->wait); + //cq->data = kmalloc(CNSL_QUEUE_SIZE, 0); + + printk("console queue data addr %08x\n", cq->data); +} + +void cnsl_init() +{ + cnsl_queue_init(&cnsl_rd_q); + cnsl_queue_init(&cnsl_wr_q); + cnsl_queue_init(&cnsl_sc_q); +} diff --git a/drivers/console.h b/drivers/console.h new file mode 100644 index 0000000..a18325d --- /dev/null +++ b/drivers/console.h @@ -0,0 +1,26 @@ +/* + * ------------------------------------------------------------------------ + * File Name: console.h + * Author: Zhao Yanbai + * Sun Jun 22 22:06:53 2014 + * Description: none + * ------------------------------------------------------------------------ + */ + +#pragma once + +#include + +#define CNSL_QUEUE_SIZE 1024 + +typedef struct cnsl_queue +{ + unsigned int head; + unsigned int tail; + wait_queue_head_t wait; + char data[CNSL_QUEUE_SIZE]; +} cnsl_queue_t; + +extern cnsl_queue_t cnsl_rd_q; +extern cnsl_queue_t cnsl_wr_q; +extern cnsl_queue_t cnsl_sc_q; diff --git a/drivers/keyboard.c b/drivers/keyboard.c index c75b181..2c0f9f8 100644 --- a/drivers/keyboard.c +++ b/drivers/keyboard.c @@ -18,27 +18,15 @@ #include #include #include - -#define KBD_BUF_SIZE 256 -static struct -{ - unsigned int count; - unsigned int head,tail; - unsigned char buf[KBD_BUF_SIZE]; -} kbd_buf; -#define count kbd_buf.count -#define head kbd_buf.head -#define tail kbd_buf.tail -#define buf kbd_buf.buf - - +#include void reboot(); void poweroff(); void ide_debug(); void ide_status(); void debug_sched(); -void kbd_handler(unsigned int irq, pt_regs_t * regs, void *dev_id) + +void kbd_handler(unsigned int irq, pt_regs_t * regs, void *dev_id) { unsigned char scan_code; scan_code = inb(0x60); @@ -57,32 +45,21 @@ void kbd_handler(unsigned int irq, pt_regs_t * regs, void *dev_id) if(scan_code == 0x14) // t debug_sched(); -// if(scan_code - - if(count < KBD_BUF_SIZE) - { - count++; - buf[tail++] = scan_code; - tail %= KBD_BUF_SIZE; - } -} + if((cnsl_rd_q.head+1) == cnsl_rd_q.tail) + goto end; -inline int getscan_code() -{ - unsigned int scan_code; - - //while(count <= 0); - if(count <= 0) return -1; + cnsl_rd_q.data[cnsl_rd_q.head++] = (char) scan_code; - scan_code = buf[head++]; - head %= KBD_BUF_SIZE; - count--; //很明显这是临界资源但现在只能这样了 +end: - return (0xFF & scan_code); + wake_up(&cnsl_rd_q.wait); } - -int sysc_read_kbd() +int sysc_read_kbd() { - return getscan_code(); + DECLARE_WAIT_QUEUE(wait, current); + add_wait_queue(&cnsl_rd_q.wait, &wait); + + + return 0; } diff --git a/include/list.h b/include/list.h index f57d998..ddd7d51 100644 --- a/include/list.h +++ b/include/list.h @@ -49,6 +49,13 @@ do{ \ pos != (head); \ pos = tmp, tmp = pos->next) +#define list_for_each_entry_safe(pos, tmp, head, member) \ + for(pos=list_entry((head)->next, typeof(*pos), member), \ + tmp=list_entry(pos->member.next, typeof(*pos), member); \ + &pos->member != (head); \ + pos=tmp, tmp=list_entry(tmp->member.next, typeof(*tmp), member)) + + static inline void _list_add(list_head_t *pnew, list_head_t *prev, list_head_t *next) { next->prev = pnew; diff --git a/include/sched.h b/include/sched.h index b6d104a..f5a87b1 100644 --- a/include/sched.h +++ b/include/sched.h @@ -24,7 +24,6 @@ unsigned long schedule(); -inline void wake_up(wait_queue_t * wq); -inline void sleep_on(wait_queue_t * wq); +void wake_up(wait_queue_head_t *wqh); extern task_union root_task; diff --git a/include/semaphore.h b/include/semaphore.h index 50d76be..8ea8d78 100644 --- a/include/semaphore.h +++ b/include/semaphore.h @@ -19,14 +19,14 @@ typedef struct semaphore list_head_t wait_list; } semaphore_t; -#define SEMAPHORE_INIT(name, n) \ +#define SEMAPHORE_INITIALIZER(name, n) \ { \ .cnt = (n), \ .wait_list = LIST_HEAD_INIT((name).wait_list) \ } #define DECLARE_MUTEX(name) \ - semaphore_t name = SEMAPHORE_INIT(name, 1) + semaphore_t name = SEMAPHORE_INITIALIZER(name, 1) void down(semaphore_t *s); void up(semaphore_t *s); diff --git a/include/wait.h b/include/wait.h index 199bd3c..fd74d45 100644 --- a/include/wait.h +++ b/include/wait.h @@ -35,15 +35,16 @@ typedef struct #define DECLARE_WAIT_QUEUE_HEAD(name) \ wait_queue_head_t name = WAIT_QUEUE_HEAD_INITIALIZER(name) -#define WAIT_QUEUE_INITIALIZER(name) \ +#define WAIT_QUEUE_INITIALIZER(name, tsk) \ { \ .task = tsk, \ .task_list = LIST_HEAD_INIT((name).task_list) \ } -#define DECLARE_WAIT_QUEUE(name) \ - wait_queue_t name = WAIT_QUEUE_INITIALIZER(name) +#define DECLARE_WAIT_QUEUE(name, tsk) \ + wait_queue_t name = WAIT_QUEUE_INITIALIZER(name, tsk) void init_wait_queue(wait_queue_head_t * wqh); - +void add_wait_queue(wait_queue_head_t *wqh, wait_queue_t *wq); +void del_wait_queue(wait_queue_head_t *wqh, wait_queue_t *wq); diff --git a/kernel/sched.c b/kernel/sched.c index 1e61176..59c4859 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -164,7 +164,8 @@ unsigned long schedule() task_union *prev = current; task_union *next = sel; - context_switch(prev, next); + if(prev != sel) + context_switch(prev, next); } void debug_sched() @@ -172,14 +173,3 @@ void debug_sched() task_union *p = list_entry(current->list.next, task_union, list); p->state = (p->state == TASK_RUNNING) ? TASK_WAIT: TASK_RUNNING; } - - -inline void wake_up(wait_queue_t * wq) -{ - -} - -inline void sleep_on(wait_queue_t * wq) -{ - -} diff --git a/kernel/semaphore.c b/kernel/semaphore.c index 8be4d05..8f80703 100644 --- a/kernel/semaphore.c +++ b/kernel/semaphore.c @@ -33,7 +33,7 @@ void __down(semaphore_t *s) DECLARE_SEMAPHORE_WAITER(waiter, task); list_add_tail(&waiter.list, &s->wait_list); - while(true) + //while(true) { task->state = TASK_WAIT; @@ -42,7 +42,7 @@ void __down(semaphore_t *s) disable_irq(); if(waiter.up) - break; + ;//break; } } @@ -69,6 +69,8 @@ void __up(semaphore_t *s) semaphore_waiter_t *waiter = list_first_entry(&s->wait_list, semaphore_waiter_t, list); list_del(&waiter->list); waiter->up = 1; + + waiter->task->state = TASK_RUNNING; } diff --git a/kernel/wait.c b/kernel/wait.c index 6f78576..b06b537 100644 --- a/kernel/wait.c +++ b/kernel/wait.c @@ -32,3 +32,16 @@ void del_wait_queue(wait_queue_head_t *wqh, wait_queue_t *wq) irq_restore(iflags); } +void wake_up(wait_queue_head_t *wqh) +{ + unsigned long flags; + wait_queue_t *p, *tmp; + irq_save(flags); + list_for_each_entry_safe(p, tmp, &wqh->task_list, task_list) + { + p->task->state = TASK_RUNNING; + } + irq_restore(flags); + + // no schedule() here. +} diff --git a/mm/kmalloc.c b/mm/kmalloc.c index 4de3411..b22ab1f 100644 --- a/mm/kmalloc.c +++ b/mm/kmalloc.c @@ -15,48 +15,19 @@ #include #include -static get_order(size_t size) +static int get_order(size_t size) { - //printk("size:%08x ", size); - size = ALIGN(size, PAGE_SIZE); - //printk(" %08x\n", size); int i; - int n = size>>PAGE_SHIFT; - for(i=0; imapNR, page->mapNR<mapNR<>PAGE_SHIFT); - //printk("%08x\n", page->mapNR); - //old_free_pages(page); } diff --git a/setup/setup.c b/setup/setup.c index 8c26766..9adf6df 100644 --- a/setup/setup.c +++ b/setup/setup.c @@ -33,6 +33,7 @@ extern void setup_fs(); extern void setup_ext2(); extern void reboot(); +extern void cnsl_init(); #define HZ 10 #define CLOCK_TICK_RATE 1193180 @@ -76,6 +77,9 @@ void setup_kernel() setup_sysc(); setup_pci(); + cnsl_init(); + + setup_tasks(); setup_irqs(); -- 2.44.0