summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cpu.c24
-rw-r--r--src/cpu_asm.S17
2 files changed, 41 insertions, 0 deletions
diff --git a/src/cpu.c b/src/cpu.c
index 3e00d61..1971e77 100644
--- a/src/cpu.c
+++ b/src/cpu.c
@@ -463,6 +463,30 @@ cpu_intr_main(const struct cpu_intr_frame *frame)
* because the interrupt handler has awaken a higher priority thread,
* in which case a context switch is triggerred. Such context switches
* are called involuntary.
+ *
+ * Here is what the stack looks like when such a context switch occurs :
+ *
+ * | | Stack grows down.
+ * | |
+ * | stack of the interrupted thread |
+ * | |
+ * +---------------------------------+ <- interrupt occurs
+ * | |
+ * | struct cpu_intr_frame |
+ * | |
+ * +---------------------------------+
+ * | |
+ * | cpu_intr_main stack frame |
+ * | |
+ * +---------------------------------+
+ * | |
+ * | thread function stack frames |
+ * | |
+ * +---------------------------------+
+ * | |
+ * | thread context on switch | See thread_switch_context in
+ * | | thread_asm.S.
+ * +---------------------------------+
*/
thread_preempt_enable();
}
diff --git a/src/cpu_asm.S b/src/cpu_asm.S
index 321f5b2..e14fb1f 100644
--- a/src/cpu_asm.S
+++ b/src/cpu_asm.S
@@ -128,6 +128,23 @@ name: \
pushl $(vector); \
jmp cpu_intr_common
+/*
+ * This is the first common low level entry point for all exceptions and
+ * interrupts. When reached, the stack contains the registers automatically
+ * pushed by the processor, an error code and the vector. It's important
+ * to note that the stack pointer still points to the stack of the thread
+ * running when the interrupt occurs. Actually, in this implementation,
+ * the entire interrupt handler borrows the stack of the interrupted thread.
+ *
+ * This is dangerous because the stack must then be large enough for both
+ * the largest call chain of the interrupted thread as well as the largest
+ * call chain of any interrupt handler. On some implementations, especially
+ * those with very demanding real-time constraints, interrupt handling may
+ * nest to avoid waiting for the current interrupt to be serviced before
+ * starting handling a higher priority one, leading to even larger stack
+ * needs. This is why many operating systems dedicate a separate stack for
+ * interrupt handling.
+ */
cpu_intr_common:
CPU_INTR_STORE_REGISTERS
push %esp /* push the address of the interrupt frame */