timer function
Re:timer function
firs you need IRQ0 enabled - this is timer, and add some counter: in function write: do...until...
Thats all...
Thats all...
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:timer function
yes, of course. You will hardly know how to wait for a given time without the help of the Programmable Interval Timer chip.
Basically,
1. set up or know the IRQ0 (PIT-raised interrupt) frequency
2. when a pause(n_sec) is made, compute how much IRQ0 this will make ...
3. use a software counter to know how long you still have to wait. When that counter reach 0 (decreasing is always easier for this kind of use), wake the sleeper. This could be done with some IPC mechanism of yours or through a global variable like in
Basically,
1. set up or know the IRQ0 (PIT-raised interrupt) frequency
2. when a pause(n_sec) is made, compute how much IRQ0 this will make ...
3. use a software counter to know how long you still have to wait. When that counter reach 0 (decreasing is always easier for this kind of use), wake the sleeper. This could be done with some IPC mechanism of yours or through a global variable like in
Code: Select all
volatile int sleeptime=0;
void timerISR() {
if (sleeptime) sleeptime--;
}
void sleepfor(int time) {
sleeptime=time*freq;
while (sleeptime);
}
Re:timer function
is this true?: the frequency set by the PIT determines how many times IRQ0 fires in a second.
Re:timer function
also is there a website somewhere that has data for the PIT? like ports, etc?
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:timer function
Yes. Check out the "miscellaneous device" section on Operating System Resource Center (available from the .:Quicklinkz:. thread)
Re:timer function
Pype, your global variable approach won't work with multiple processes, will it?
-
- Member
- Posts: 1600
- Joined: Wed Oct 18, 2006 11:59 am
- Location: Vienna/Austria
- Contact:
Re:timer function
How about keeping the amount to sleepin the process structure and have the timer task crawl though it to decrement it and wake processes which have slept enough up -- move them to the ready queue?
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
BlueillusionOS iso image
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:timer function
It depends on how you will use multiple processors ... if you have this handler used only on CPUx (iirc, on multiprocessor systems, each CPU can have its own instance of the IRQ0 by the mean of the local APIC. Correct me if i'm wrong), then nothing prevent you from using a static global variable:abless wrote: Pype, your global variable approach won't work with multiple processes, will it?
only the "timer-server" processor will be able to count the ticks that have gone since the process is asleep and only this processor will have the ability to wake the process up .
In other words, i don't see why every processor should be in charge of looking up the "sleep" queue, so i think it is clean to use the global variable as long as you make sure that only one processor will call the handler that does it...
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:timer function
I think it would be too much time-consuming to crawl the process list at every time tick.beyond infinity wrote: How about keeping the amount to sleepin the process structure and have the timer task crawl though it to decrement it and wake processes which have slept enough up -- move them to the ready queue?
What is usually done is to have the following structure:
Code: Select all
struct time_event {
int delay; //!< how much ticks remaining ?
int pid; //!< the process to be awaken.
struct time_event *next;
};
The list is organized so that the deadlines are in growing order, and when a new time event request is added, we compute its "deadline" value by the time we look for its place it in the queue. so that
"if X must be added just after Y, then deadline(X)=deadline(Y) + X.delay"
This way, only the head of the queue is decremented at every time tick. When it reaches zero, the queue's head is removed and its process is notified. The new head's delay is how long we still have to wait before notifying the next process.
example:
process 1 requests a wakeup after 10 ticks, process 2 after 5 ticks and process 3 after 20 ticks. All the requests are issued in the same time tick interval.
The queue will look like
Code: Select all
q-->[PID=2 | delay=5] --> [PID=1 | delay=5] --> [PID=3 | delay=10]
Similarily, deadline(3)=10+deadline(1)=15+deadline(2)=20.
You can find the implementation of this algorithm in clicker's sourcecode
-
- Member
- Posts: 1600
- Joined: Wed Oct 18, 2006 11:59 am
- Location: Vienna/Austria
- Contact:
Re:timer function
i have implemented this as a queue in which i put the sleeping processes. the timer isr collects ticks anf upon reaching an arbitrary amount of ticks, it wakes up the timer task, which takes the collected ticks and crawls through the list of sleeping processes.
slacker, to do this list building, you'll of course need a running memory manager. With this, it's just a thing of handling pointers round the course.
Take also care of Reentry of scheduler and so. whilst a Driver task or the timer task is running i recommend locking the scheduler till the task is ready with it's work and suspends - a call that moves the actual process to some other queue then the running queue and decrements some reentry counter ... and eventually causes an other driver task to run.
stay safe and listen to pype. that guy knows what he says.
slacker, to do this list building, you'll of course need a running memory manager. With this, it's just a thing of handling pointers round the course.
Take also care of Reentry of scheduler and so. whilst a Driver task or the timer task is running i recommend locking the scheduler till the task is ready with it's work and suspends - a call that moves the actual process to some other queue then the running queue and decrements some reentry counter ... and eventually causes an other driver task to run.
stay safe and listen to pype. that guy knows what he says.
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
BlueillusionOS iso image
Re:timer function
Pype, I am not sure if you got me right. I didn't mean multiple processors, but multiple **processes**. Look at this example:
Process A is calling sleep() function to request 10s of sleep.
sleeptime is set to 10 * freq. Everything ok.
Now process B calls sleep() itself. It requests 2s of sleep. Now sleeptime is set to 2 * freq. The problem is that both, process A and process B will be awaked after 2 seconds - although process A wants 8s more of sleep.
See what I mean?
Process A is calling sleep() function to request 10s of sleep.
sleeptime is set to 10 * freq. Everything ok.
Now process B calls sleep() itself. It requests 2s of sleep. Now sleeptime is set to 2 * freq. The problem is that both, process A and process B will be awaked after 2 seconds - although process A wants 8s more of sleep.
See what I mean?
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:timer function
oow.. okay. sorry for the confusion. Indeed, the static global variable approach isn't valid as soon as you want to use the same handler for several process sleeping. If this is the case, go for a 'time event' list approach where that static counter is actually shared by every process through the list.
so if you had
and that you add PID=2, delay = 2, the resulting list is
Well seen from you
so if you had
Code: Select all
q-->[PID=1 | delay=10]
Code: Select all
q --> [PID=2 | delay= +2] --> [PID=1 | delay = +8]