confusion about task switch

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
raywill

confusion about task switch

Post by raywill »

I got confusion when I got to implement mutitasking.
This is my understanding( simplified )of task switch process:
1.An Idle Process is running
2.An time interrupt occur
3.Timer ISR saves current state(regs) to the stack.
4.Call timer handler
5.Timer handler call schedule();
6.schedule() choose another task (TASK_A )to run.
<Suppose TASK_A is doing a infinite loop.It does not stop until another timer interrupt occur.>
7.Goto step 2.

Here is my question:
Since TASK_A never returns , who is responsible to pop the registers pushed to stack in step 3?
If we don't pop those registers ,the stack will overflow very soon.

Where did I misunderstand ?

P.S: The timer ISR->

Code: Select all

isr:
   push byte 0         ; ( 0) fake error code
   PUSHB %1         ; ( 2) exception number
   push gs            ; ( 4) push segment registers
   push fs            ; ( 6)
   push es            ; ( 8)
   push ds            ; ( 9)
   pusha            ; (10) push GP registers
      mov ax,gdt_data_addr   ; (11) put known-good values...
      mov ds,eax      ; (15) ...in segment registers
      mov es,eax      ; (17)
      mov fs,eax      ; (19)
      mov gs,eax      ; (21)
      mov eax,esp      ; (23)
      push eax      ; (25) push pointer to regs_t
.1:

         mov eax,_timer_interrupt; (26)
         call eax   ; (31)
;**************************************************
;When the following code been executed?
;**************************************************
      pop eax
      popa            ; pop GP registers
      pop ds            ; pop segment registers
      pop es
      pop fs
      pop gs
      
      nop
      nop      
   add esp,8         ; drop exception number and error code
iret
xenos

Re:confusion about task switch

Post by xenos »

The registers will be popped from the stack by the ISR as soon as TASK_A is scheduled for execution again. So the task switch takes the following steps:

1. A process is running (not necessarily idle)
2. A timer interrupt occurs
3. The Timer ISR pushes the registers onto the stack
4. The timer handler is called
5. The scheduler is called
6. The scheduler chooses another task (TASK_A)

This means that the state of the curent task has to be saved and the state of TASK_A in which it was interrupted has to be restored. The state of the current task (i.e. registers and instruction pointer) can be found on the stack, so the stack image has to be saved and replaced by a stack image from TASK_A that has been saved when TASK_A was interrupted for the last time. When TASK_A is executed for the first time, this stack image needs to be created first. (For example, with all registers containing 0 and the instruction pointer, i.e. the interrupt return address, pointing to the first instruction.)

7. The scheduler returns
8. The timer handler returns
9. The ISR pops the registers for the new task from the stack
10. The ISR returns to the new task.
raywill

Re:confusion about task switch

Post by raywill »

XenOS wrote: The registers will be popped from the stack by the ISR

3. The Timer ISR pushes the registers onto the stack

The state of the current task (i.e. registers and instruction pointer) can be found on the stack, so the stack image has to be saved and replaced by a stack image from TASK_A that has been saved when TASK_A was interrupted for the last time. When TASK_A is executed for the first time, this stack image needs to be created first. (For example, with all registers containing 0 and the instruction pointer, i.e. the interrupt return address, pointing to the first instruction.)
Where is the stack? and Whose stack?
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:confusion about task switch

Post by Pype.Clicker »

well.

1. give each thread its own stack
2. the scheduler never calls another thread. Instead, it modifies the stack pointer so that it's now running in the next thread's stack.
3. the code of the scheduler (after doing the stack switch) will pop off whatever was pushed in the last call to the scheduler.
4. when no switch is needed by the scheduler (e.g. when going on with the current thread is the proper decision), the "stack switch" is skipped and the scheduler just returns as expected.

HTH.
Post Reply