I spent some time thinking about exactly how to implement my task switcher, and I have come up with a couple of key points and possible solutions.
1.) Pre-emptive Timer granularity. Current its default, meaning what something like 18 times a second. However, I have seem people using something as low as 1000 times per second. I am not looking for a real-time system, but I want to me able to multi-task quiet well.
2.) Queue Seperation. I am fairly unsure on this point, but I think it would be in the best interest to seperate the queues. This means, I would have 1 queue for all running processes, 1 queue for all sleeping process, and 1 queue for blocked process. Also as a footnote, by queue I mean double-linked-list.
3.) Sleeping Threads. When a Thread calls Sleep(mili-seconds) BigSleep(Seconds) or Pause(ticks) the functions will all wrap around a Yield thread function. What will happen is the function call will convert what ever value passed into timer ticks always going over instead of under (Meaning if a thread wants to sleep for 40 miliseconds, and I can only give it 35 or 45, it will sleep for 45). Further more, it will attach the ticks_to_sleep to the thread control structure and change the state to sleeping. Now comes the tricky part, decrementing the sleeping values. Who should do this? At first I thought the Scheduler should iterate through the sleeping queue and decrement the ticks_to_sleep, and also check to see if it is zero in which case it will move it to the ready queue. Then I thought that it would be to much logic in the scheduler and that would slow it down, this I came up with the idea of running a high priority task who's job would just be to decrement the sleeping tasks, and move to ready, and then yield back to the scheduler. Let me add this (just thought of it) Still using the granularity of 1000 / per. The smallest sleep increment is 10 ticks, so every ten times into the scheduler, we add the check sleepers task to the head of the queue. And then it will yield back.
4.) Scheduling Priority. I am looking for something simpler, this is a hobby os, and not a next gen platform, so a simple priority scheme should be fine. What I came up with is something simple like so. If my timer frequency was 1000 / second. Then a threads time to run would be determined as such. If a thread_priority was 5 It would be given 50 ticks to run. Simple formula: 100 - (priority * 10). I can then also hardcode a priority 0 (real-time) to run untill complete (Bad Idea and should never happen).
So basically my scheduler would look something as such.
Code: Select all
void Scheduler(OldEsp0)
{
SchedulerTicks++;
CurrentTask->TicksSlice--;
Possibly loop through sleepers and tick_to_sleep-- (also check for 0 and move to ready)
if (CurrentTask->TicksSlice == 0)
Switch to the next process
setup a new CurrentTask and set CurrentTask->TicksSlice = CurrentTask->TicksSliceSize
}
What do you think?
What am I missing?
Thanks,
Rich