Hi All,
I have written a basic device manager which I am fairly happy with for starters and devices such as the PIT, RTC etc... are now to be controlled through that rather than directly from the kernel itself. Now I am getting a little more organised, I've been thinking about whether I am doing the "correct thing" with multitasking.
Up until now, the kernel has had control of the PIT, which increments a tick count and calls the task scheduler if the current task's time slot is up. When the PIT is controlled via the device manager, I see 3 options:
1. The kernel retains control of the PIT which is purely used for scheduling. A different timer value is set on each task switch depending on current priority. This is probably the fastest way (least code execution) of doing things, but is inflexible in that IRQ0 can *only* be used for the PIT. I need to find another time source for the tick counter (I believe the APIC and RTC(?) can be used as interrupt sources).
2. After scanning and adding hardware, the kernel scans for how many timers are available on the system and, if appropriate, "takes control" of one of them as in 1.
3. The PIT is entirely controlled by the device manager as with every other device. A number of interrupt handlers can service IRQ0 including the task switcher (when necessary) and tick counter which should be installed as with every other interrupt. This is the most flexible system, but requires the most code execution on each cycle of the timer.
At the moment, I quite favour option 1, but this completely ties up the PIT and IRQ0 with task switching. I know ultimately I need to make the design decision, but any ideas?
Cheers,
Adam
A Time Source for Multitasking
- mathematician
- Member
- Posts: 437
- Joined: Fri Dec 15, 2006 5:26 pm
- Location: Church Stretton Uk
Re: A Time Source for Multitasking
Hi,
BTW it is possible to do everything with a single timer. For e.g.:
Cheers,
Brendan
IMHO the scheduler should be responsible for all time related things (time slices, sleep(), udelay(), nanosleep(), etc), except for keeping track of "real time" perhaps. In this case, would it really matter if the scheduler completely ties up every timer in the entire computer (except for possibly one timer which is used for keeping track of "real time", e.g. the RTC)?AJ wrote:At the moment, I quite favour option 1, but this completely ties up the PIT and IRQ0 with task switching. I know ultimately I need to make the design decision, but any ideas?
BTW it is possible to do everything with a single timer. For e.g.:
Code: Select all
timerIRQhandler:
realTimeClock += timePeriod;
if(timePeriod != newTimePeriod) {
setNewTimerFrequency();
}
if(wakeUpTimeForFirstSleepingTask <= realTimeClock) {
wakeUpSleepingTasks();
}
if(firstAlarmTime <= realTimeClock) {
sendAlarmSignals();
}
if(timeSliceEnd <= realTimeClock) {
doTaskSwitch();
}
sendEOI();
iretd
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
The timer handler could check if any additional isrs are registered after it does its work, then pass control to the device manager only if needed.
Code: Select all
-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GCS/M/MU d- s:- a--- C++++ UL P L++ E--- W+++ N+ w++ M- V+ PS+ Y+ PE- PGP t-- 5- X R- tv b DI-- D+ G e h! r++ y+
------END GEEK CODE BLOCK------
Thanks for this, Brendan.
Certainly at the moment my scheduler takes care of all task and thread suspend conditions including sleep, wait for irq, wait for IO etc, etc...
I'm thinking have the kernel provide an ISR which takes care of the task switch - I guess it is more a case of whether to use a separate IRQ for scheduling (say, IRQ0, the PIT) and tick counting (say, IRQ8, the RTC) or whether to allow it all to happen in one interrupt.
If I do the former, each ISR needs only to contain the code for that function (one will do something along the lines of tickcount++ and the other will do task_switch()).
If I do the latter, I need to keep my time slices equal so as not to confuse the tick counter, and the ISR will need to check whether the process time has elapsed and call the task switch as appropriate.
Adam
Certainly at the moment my scheduler takes care of all task and thread suspend conditions including sleep, wait for irq, wait for IO etc, etc...
I'm thinking have the kernel provide an ISR which takes care of the task switch - I guess it is more a case of whether to use a separate IRQ for scheduling (say, IRQ0, the PIT) and tick counting (say, IRQ8, the RTC) or whether to allow it all to happen in one interrupt.
If I do the former, each ISR needs only to contain the code for that function (one will do something along the lines of tickcount++ and the other will do task_switch()).
If I do the latter, I need to keep my time slices equal so as not to confuse the tick counter, and the ISR will need to check whether the process time has elapsed and call the task switch as appropriate.
Adam