diff options
-rw-r--r-- | src/cpu.c | 24 | ||||
-rw-r--r-- | src/cpu_asm.S | 17 |
2 files changed, 41 insertions, 0 deletions
@@ -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 */ |