Colonel Kernel wrote:It's not clear to me why you're avoiding having a dedicated idle thread. The system will be just as fast to respond to interrupts as with the way you've done it.
The previous approach I used was that the init-thread, after it has finished work (start shells etc.), goes into an endless-loop which calls wait() all the time. wait() causes the kernel to block the thread. Everytime the scheduler finds no runnable thread it chooses the init-thread (no matter if it is blocked). So the init-thread does just run if there is nothing else to do because if there are runnable threads, they will be chosen first.
This way is easy and works but wastes some time because it makes syscalls all the time and they have to be finished before we can switch to another thread (interrupts are disabled in my kernel and I don't support SMP).
Of course it is possible to prevent the syscalls by e.g. telling the kernel when the init-thread is finished with starting shells so that the kernel will just choose init from that point on if there is no other runnable thread. But the problem is that the hlt-instruction is a privileged one so that the init-thread would have to run in kernel-mode, right? My OS doesn't support kernel-mode threads yet and I wanted to prevent the need of them, if possible.
Or is there another way halting the cpu when idling in user-mode?
Colonel Kernel wrote:Also, I see big re-entrancy concerns with how you've done it. What if the interrupt that occurs during idle needs to switch tasks? Is your scheduler able to handle that case?
This problem shouldn't occurr with no SMP-support and interrupts disabled in kernel, right?
On the other hand, this case is exactly the problem. Perhaps I wasn't clear enough in the last post. If I have to switch tasks when I've got an interrupt during idle something wents wrong. I am not sure if we're talking about the same thing
Artlav wrote:-The fields for different-level stacks should be valid in TSS's.
It is valid for CPL 0. Since I'm just using ring3 and ring0 this should be ok, AFAIK.
Artlav wrote:-popa does not update ESP.
I'm saving and restoring all required registers manually. The stack-pointer (for user-mode) is updated automatically if switching back to a (numerically) higher PL, right?
Artlav wrote:-Interrupt does not push SS and ESP if called from the same CPL, but does if from different.
That's one of the possible problems I had in mind. But if I have understood it correctly it should work. Because the CPL is determined by the segment-registers. They are stored on the kernel-stack at interrupt-begin (cs by the CPU, the other manually). That means if I switch the kernel-stack and stack- and base-pointer (from nested-interrupt to not-nested-interrupt) everything should be as if the idle-task has never existed and the CPU should restore SS and ESP because we're changing the CPL when leaving interrupt-handling.
Or is this not correct?