bluemoon wrote:
Please correct me if I'm wrong, my concern are implement kernel threads and handle IRQ and preemption:
I don't have any "kernel threads" except for some "idle thread" running an "sti; hlt;" loop (which is not even a real thread, it's just a wait loop that runs when there is no thread ready for execution), so please take my comments on this with a bit of caution.
Quote:
For kernel thread I can:
1. (enter kernel) syscall or interrupt trigger, control transfer from application to kernel, CR3 unchanged yet.
2. kernel does the handling (syscall or IRQ)
3. (leave kernel) scheduler pick a thread from { kernel threads, return to same user thread, diff thread of same user process, thread from other process }
4. if kernel thread -> transfer to it
5. if same process, same thread -> return to it
6. if same process, diff thread -> switch TCB
7. if diff process -> switch process
The idea is to add control flow to "leave kernel"
In principle this looks fine to me. If you replace "kernel thread" by "wait loop", it's more or less what my kernel is doing.
Quote:
To handle IRQ
I plan to have a high priority kernel thread that is blocking on a message queue, when IRQ happen, the handler post a message to the queue and wake that thread (by marking such thread "the next one"? see below for preemption). the thread then fetch the message and dispatch to registered handler/drivers.
I guess it would be more efficient to have a separate message queue for each IRQ, and to completely remove this "high priority kernel thread". Instead, the interrupt handler would push a message to the IRQ's message queue and wake some handler / driver thread that is waiting on that queue. There is no need for an intermediate kernel step which simple dispatches the message from the queue to another thread.
Quote:
Preemption
I still have not design it well. Since for one kstack per CPU, the kernel usually do not switch process until it return to user. If a thread/preempt all we can do is mark that thread "next" or raise it's probability to be picked by the scheduler; so if another process preempted before the kernel return, there is chance that the previously preempted process may not run next, but later. Can it be an issue?
I'm not quite sure whether I get the point. The case that two threads get preempted at nearly the same time can happen only on systems with multiple CPUs (otherwise you wouldn't have more than one thread running at the same time). You need to make sure that both CPUs can enter the kernel safely without causing problems. One possibility would be to have separate thread queues for each CPU, so that scheduling one thread on one CPU doesn't affect the other CPUs.