aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlex Auvolat <alex.auvolat@ens.fr>2015-02-28 11:25:12 +0100
committerAlex Auvolat <alex.auvolat@ens.fr>2015-02-28 11:25:12 +0100
commitf610cb7baa26b2803fce8b6e4604e8639c71d1d3 (patch)
treeb61a0bbed25be833625a4ca44b5decc7896e205f /src
parentb5552cc9c7dd2d333106b1c69e6ff23aab19df47 (diff)
downloadkogata-f610cb7baa26b2803fce8b6e4604e8639c71d1d3.tar.gz
kogata-f610cb7baa26b2803fce8b6e4604e8639c71d1d3.zip
IRQ handlers must be written with caution!
Diffstat (limited to 'src')
-rw-r--r--src/kernel/dev/pciide.c9
-rw-r--r--src/kernel/include/idt.h10
2 files changed, 16 insertions, 3 deletions
diff --git a/src/kernel/dev/pciide.c b/src/kernel/dev/pciide.c
index f4474ba..429432f 100644
--- a/src/kernel/dev/pciide.c
+++ b/src/kernel/dev/pciide.c
@@ -165,22 +165,25 @@ static thread_t *wait_irq14 = 0, *wait_irq15 = 0, *wait_pciirq = 0;
void irq14_handler(registers_t *regs) {
if (wait_irq14) {
- resume_thread(wait_irq14, true);
+ thread_t *t = wait_irq14;
wait_irq14 = 0;
+ resume_thread(t, true); // may not return depending on conditions
}
}
void irq15_handler(registers_t *regs) {
if (wait_irq15) {
- resume_thread(wait_irq15, true);
+ thread_t *t = wait_irq15;
wait_irq15 = 0;
+ resume_thread(t, true);
}
}
void pciirq_handler(int pci_id) {
if (wait_pciirq) {
- resume_thread(wait_pciirq, true);
+ thread_t *t = wait_pciirq;
wait_pciirq = 0;
+ resume_thread(t, true);
}
}
diff --git a/src/kernel/include/idt.h b/src/kernel/include/idt.h
index d9dd927..2cccfa5 100644
--- a/src/kernel/include/idt.h
+++ b/src/kernel/include/idt.h
@@ -74,6 +74,16 @@ void idt_init();
void idt_set_ex_handler(int number, isr_handler_t func); //Set exception handler
void idt_set_irq_handler(int number, isr_handler_t func); //Set IRQ handler
+// Warning about IRQ handlers :
+// IRQ handlers must not call yield(), because that may not return ! Therefore they cannot
+// use mutexes, memory allocation and most usefull things. Basically the only thing they
+// can do is wake up another thread, so it is a good idea to have a thread that waits for
+// the IRQ and does something when it happens, and the IRQ handler only wakes up that thread
+// when the IRQ happens.
+// Remark on resume_thread : if the second argument is set to true, yield() is called in the
+// function, so it may never return in some circumstances
+// IRQ handlers are never preemptible
+
void dbg_dump_registers(registers_t*);
/* vim: set ts=4 sw=4 tw=0 noet :*/