nexos wrote:
One thing to know is an interrupt is different from a context switch. What happens with the PIT is that the interrupt handler gets called, and then the register state gets saved. It then calls a function that checks if there is task that is running should be preempted. If so, it calls switch_to_task. Then, when the new task runs, it restores its interrupted context. This may seem slower then what you are doing right now, but, most context switches end up occuring because a task pauses itself, and in this case, this method is faster.
I have to say, I'm a little confused. I understood things just the way you explained them but I don't see how the code in the tutorials implements these concepts.
When a PIT interrupt gets triggered, CPU uses the IDT to locate the eip of my timer-handler and then uses the value contained in TSS.esp0 to setup the stack for my kernel code (which should be my responsibility to be kept uptaded every time I use the stack in an int-handler right?).
Now, correct me if I'm wrong, my timer-handler will never return to the code immediatly after. This is because i setup a stack with the eip of the next task and then
ret to it.
So in the example i have interrupt code ->
schedule() ->
switch_to_task() and if I understood correctly,
switch_to_task will not just return to schedule which will return to the interrupt code but will, instead, jump into the new task code.
Maybe I can't read assembly that well but in the prologue of the switch_to_task there's this code:
Code:
push ebx
push esi
push edi
push ebp
mov edi,[current_task_TCB] ;edi = address of the previous task's "thread control block"
mov [edi+TCB.ESP],esp
to me, that code saves the registers onto the kernel stack (I am in interrupt code) and then saves this value into the current_task state??? Why? Does it need to be restored later somehow?
Besides, since
switch_to_task gets called by
schedule(), wouldn't ebx, esi and so forth contain the values as set by the callee (
schedule())?
Shouldn't we save the values of the registers that we got as soon as the interrupt occurred (aka, values of regs from the previously, and now preempted, task) ?
Cheers,
F