Page 1 of 1

Software task switch without interrupts

Posted: Mon Jan 14, 2008 5:27 pm
by mfa81
Hi you... this is my first post, I had looked around the forum for an answer and couldn't find.

So my question is: I am implementing a software based task switching assembly function which push all registers, updates SP for the new stack, and pop all registers from task_to_run stack then IRET. All segment registers are always the same for all tasks, including SS due to OS characteristics, just esp changes for each task, my scheduling algorithm is based on cooperative task switching, each task preempts itself calling the scheduler which finds the next task to run and call task_switch assembly code. Once my task_switch assembly is not called by an interrupt I don't get EFLAGS and CS saved on stack, which is needed by IRET instruction, I was wondering which is the best solution to get EFLAGS, CS, EIP on stack just after pop all register and before call IRET. The best solution I could find is call task_switch with 2 dummy 32 bit parameters, so the call instructions would push 32 bit parameter, 32 bit parameter and EIP on stack, after that I could use ebp to overwrite EFLAGS and CS into the dummy parameters stack places and push all registers leaving the stack as I'd like to load the context on the next time the task is schedule to run. Any opinion, hint or a best solution to have EFLAGS, CS and EIP into stack without using interrupts would be valuable.

Posted: Mon Jan 14, 2008 5:57 pm
by Combuster
how about something like:

Code: Select all

pushfd
push    dword seg_kernel_code
push    .return
jmp     task_switch

.return:

Posted: Mon Jan 14, 2008 6:06 pm
by mfa81
I forgot to mention that my task_switch assembly macro is called from a C scheduler code, in this case eip is the return point into scheduler, and then into task just after the self preempt call.

Posted: Tue Jan 15, 2008 2:55 am
by AJ
Hi,

Although your code is all ring 0 and sounds like it is in the same memory space, there is no reason why you can't use an interrupt mechanism for task switching.

You task therefore calls 'sleep(0)' or whatever, and that just does something like 'int 0x80'. You then get EFLAGS, CS and EIP pushed for free.

Cheers,
Adam

Posted: Tue Jan 15, 2008 7:26 am
by mfa81
Actually I realized that I don't need to save EFLAGS because once each task peempts itself calling the scheduler (C function), the EFLAGS doesn't need to be saved, so I can easily push all register, save esp into old task structure, update esp from new task structure, pop all registers and ret.