In any case, thank you all for the help!!!
Ring 0 multithreading
-
protegee6155
- Posts: 24
- Joined: Tue Dec 16, 2025 4:17 am
Re: Ring 0 multithreading
Well, never mind — I think I should research this topic a bit more so I don’t end up asking overly general questions for nothing. After learning more, I’ll probably create a new post with a more meaningful and focused question.
In any case, thank you all for the help!!!
In any case, thank you all for the help!!!
- bellezzasolo
- Member

- Posts: 163
- Joined: Sun Feb 20, 2011 2:01 pm
Re: Ring 0 multithreading
It's an interesting one to tackle design-wise. You almost certainly want the ability to context-switch in a device interrupt - for the purpose of timer preemption. And context-switching in a syscall is key to blocking.protegee6155 wrote: ↑Tue Jan 13, 2026 1:09 pm Hmm, okay, that somewhat makes sense.
So in that case, should my interrupt-handling code—the part that executes iret at the end—also serve as my context-switch function?
Thing is, you also want to send the EOI in the device interrupt case. So you need to make sure the EOI is sent before doing the context switch.
Since you also want to restore flags, at the point of switching, IRET isn't actually a bad way of doing it. With a bit of pseudo-assembly:
Code: Select all
context_switch(current_context, next_context):
pop rax ;return address
;Build iret frame
pushfq
push cs
push rax
mov [current_context.stack_ptr], rsp
mov rsp, [next_context.stack_ptr]
iretq
Whoever said you can't do OS development on Windows?
https://github.com/ChaiSoft/ChaiOS
https://github.com/ChaiSoft/ChaiOS
-
Octocontrabass
- Member

- Posts: 6245
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Ring 0 multithreading
No. That makes context switching more complicated for no reason, and that extra complexity will come back and bite you later. Stick to something like the switch_to_task example.protegee6155 wrote: ↑Tue Jan 13, 2026 1:09 pmSo in that case, should my interrupt-handling code—the part that executes iret at the end—also serve as my context-switch function?
Do you? Tasks that will return to ring 3 will restore their flags when they return to ring 3. What other flags would you want to restore?
- bellezzasolo
- Member

- Posts: 163
- Joined: Sun Feb 20, 2011 2:01 pm
Re: Ring 0 multithreading
The interrupt flag. While you might get away with mov rsp, [x] being atomic, you're still in a context switch procedure, quite possibly triggered from a hardware interrupt. To avoid stack overflow, you've probably done something like:Octocontrabass wrote: ↑Wed Jan 14, 2026 8:56 pmNo. That makes context switching more complicated for no reason, and that extra complexity will come back and bite you later. Stick to something like the switch_to_task example.protegee6155 wrote: ↑Tue Jan 13, 2026 1:09 pmSo in that case, should my interrupt-handling code—the part that executes iret at the end—also serve as my context-switch function?
Do you? Tasks that will return to ring 3 will restore their flags when they return to ring 3. What other flags would you want to restore?
Code: Select all
cli
EOI()
next_context = schedule()
if(next_context) context_switch(next_context)
iret
And just generally being interrupted during a context switch seems messy to reason about as you now hav reentrancy into the scheduler.
But, if you go into it with IF off, you now resume on a syscall / sysret, which doesn't necessariy touch flags (and you may well want the kernel to be preemptible while servicing a system call).
Neater I think to just save/restore flags as part of the context switch.
Whoever said you can't do OS development on Windows?
https://github.com/ChaiSoft/ChaiOS
https://github.com/ChaiSoft/ChaiOS
Re: Ring 0 multithreading
So long as stack overflow is avoided (and if you are implementing a pre-emptible kernel, you typically still don't re-enable the interrupt flag if only a small amount of stack remains), it is not harder to reason about an interrupt in the scheduler than an interrupt in any other place. All shared state must be spinlock-protected anyway (unless you have the kind of space brain necessary to implement lockless algorithms) and spinlocks shared with interrupt handlers must disable the interrupt flag when taken.bellezzasolo wrote: ↑Thu Jan 15, 2026 2:40 am And just generally being interrupted during a context switch seems messy to reason about as you now hav reentrancy into the scheduler.
Yes, if the interrupt flag can be different between contexts, then it should also be preserved by the task switcher. That is one more pushfd before and one more popfd after the stack switch.bellezzasolo wrote: ↑Thu Jan 15, 2026 2:40 am Neater I think to just save/restore flags as part of the context switch.
Indeed I left a lot out of there. For example, switching CR3, possibly handling the debug registers, the FPU/SSE and other state. But all of this can be added later, once the principle is out of the way.
Carpe diem!