From e7f5de73e8b3fe792a17c34a6c0bb85a84b0f50e Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Tue, 10 Aug 2010 21:04:39 +0200 Subject: Changed idt_waitIrq to support multiple waiting threads. --- src/kernel/task/idt.c | 19 ++++++++++++++----- src/kernel/task/timer.c | 5 +---- 2 files changed, 15 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/kernel/task/idt.c b/src/kernel/task/idt.c index 887ebf7..caf9fb0 100644 --- a/src/kernel/task/idt.c +++ b/src/kernel/task/idt.c @@ -65,7 +65,10 @@ struct idt_entry idt_entries[256]; struct idt_ptr idt_ptr; static int_callback irq_handlers[16] = {0}; -static struct thread* irq_wakeup[16] = {0}; +static struct irq_waiter { + struct thread *thread; + struct irq_waiter *next; +} *irq_wakeup[16] = {0}; /* Called in idt_.asm when an exception fires (interrupt 0 to 31). Tries to handle the exception, panics if fails. */ @@ -90,9 +93,11 @@ void idt_irqHandler(struct registers regs) { outb(0xA0, 0x20); } outb(0x20, 0x20); - if (irq_wakeup[regs.err_code] != 0) { - irq_wakeup[regs.err_code]->state = TS_RUNNING; - irq_wakeup[regs.err_code] = 0; + while (irq_wakeup[regs.err_code] != 0) { + struct irq_waiter *tmp = irq_wakeup[regs.err_code]; + thread_wakeUp(tmp->thread); + irq_wakeup[regs.err_code] = tmp->next; + kfree(tmp); doSwitch = 1; } if (irq_handlers[regs.err_code] != 0) { @@ -205,7 +210,11 @@ void idt_handleIrq(int number, int_callback func) { /* Tells the IRQ handler to wake up the current thread when specified IRQ fires. */ void idt_waitIrq(int number) { if (number < 16 && number >= 0 && proc_priv() <= PL_DRIVER) { - irq_wakeup[number] = current_thread; + struct irq_waiter *tmp = kmalloc(sizeof(struct irq_waiter)); + tmp->thread = current_thread; + tmp->next = irq_wakeup[number]; + irq_wakeup[number] = tmp; + thread_goInactive(); } } diff --git a/src/kernel/task/timer.c b/src/kernel/task/timer.c index 643ca54..65ad06a 100644 --- a/src/kernel/task/timer.c +++ b/src/kernel/task/timer.c @@ -61,10 +61,7 @@ void thread_sleep(uint32_t msecs) { sf->wakeup_time = timer_time() + msecs; sf->thread = current_thread; //Insert it at the right place - if (sleeping_threads == 0) { - sleeping_threads = sf; - sf->next = 0; - } else if (sleeping_threads->wakeup_time >= sf->wakeup_time) { + if (sleeping_threads == 0 || sleeping_threads->wakeup_time >= sf->wakeup_time) { sf->next = sleeping_threads; sleeping_threads = sf; } else { -- cgit v1.2.3