Lagor wrote:
Since I'd like to support both, is it correct to assume that depending on the type of thread selected to be switched-to next, I have to write different ways to switch task?
Nope! Task switching always happens in ring 0, so your scheduler doesn't need to know whether a task will stay in ring 0 or return to ring 3.
Ok, I can live with that.
Lagor wrote:
First question: does this seem resonable?
No. A lot of tasks will yield before any timer interrupts happen, so you need a way to switch tasks that doesn't depend on interrupts. Once you have that, your timer interrupt can use it too.
Yes, this I understand. For the moment i was just trying to get the timer interrupt logic right.
Lagor wrote:
Second: depending on the type of thread to be executed, whether i want it to run at ring0 or ring3, do i have to use RET/IRET accordingly?
What about the return from interrupt? I'm using IRET without touching the stuff pushed by the CPU. Do i need to take care of things differently there as well?
Task switching always happens in ring 0, so switch_to_task always uses RET. The task itself will use IRET (or SYSRET or SYSEXIT) if it needs to be in ring 3.
This added a lot of confusion to me.
If i switch to a task with a RET while i'm in the interrupt handler, the flow will be directed to the new task code and, in a way, the interrupt handler code won't return (yet). Is this right?
So let's say my task was interrupted before a printf instruction, when i resume it from interrupt code running at ring0, i need to setup the stack, the eip (printf instruction) and CS so that when the RET executes, we're running the task in ring3 with the appropriate stack and at the right instruction.
I absolutely don't understand what you mean by 'the task itself need to put itself into the correct privilege level'
Quote:
As far as switch_to_task is concerned, there is no such thing as a new task: every task it switches to is an existing task that will be resumed. If you want to start a new task, you create the appropriate context so the new task will run in the correct ring when it resumes.
The only special handling you need to do in the timer interrupt is making sure you finish acknowledging it before you call switch_to_task, since there's no guarantee the next task will resume inside the timer interrupt handler.
Yes, this i do but as the last instruction of the timer interrupt handler. If i switched task before that, does this mean that piece of code will not get called?
I have to say, i thought i was almost there, I have perfectly running ring0 tasks but as soon as i wanted to mix them up with some ring3 ones, things started not to work.