timer function

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
slacker

timer function

Post by slacker »

how would i i create a timer function like:

void pause(int numsec)
Thunder

Re:timer function

Post by Thunder »

firs you need IRQ0 enabled - this is timer, and add some counter: in function write: do...until...
Thats all... ;)
slacker

Re:timer function

Post by slacker »

i thought the PIT was involved in creating this timer function?
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:timer function

Post by Pype.Clicker »

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

Code: Select all

volatile int sleeptime=0;
void timerISR() {
   if (sleeptime) sleeptime--;
}

void sleepfor(int time) {
  sleeptime=time*freq;
  while (sleeptime);
}
slacker

Re:timer function

Post by slacker »

is this true?: the frequency set by the PIT determines how many times IRQ0 fires in a second.
slacker

Re:timer function

Post by slacker »

also is there a website somewhere that has data for the PIT? like ports, etc?
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:timer function

Post by Pype.Clicker »

Yes. Check out the "miscellaneous device" section on Operating System Resource Center (available from the .:Quicklinkz:. thread)
Whatever5k

Re:timer function

Post by Whatever5k »

Pype, your global variable approach won't work with multiple processes, will it?
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:timer function

Post by distantvoices »

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
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:timer function

Post by Pype.Clicker »

abless wrote: Pype, your global variable approach won't work with multiple processes, will it?
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:
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...
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:timer function

Post by Pype.Clicker »

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?
I think it would be too much time-consuming to crawl the process list at every time tick.

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 time server has a static pointer to the list of time_events, each time_event corresponding to a process that needs an alarm (regardless of whether it is alseep or running).

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]
We can check that the deadline for pid1 is 5+deadline(2) = 5+5 = 10 as requested.
Similarily, deadline(3)=10+deadline(1)=15+deadline(2)=20.

You can find the implementation of this algorithm in clicker's sourcecode
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:timer function

Post by distantvoices »

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.
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
Whatever5k

Re:timer function

Post by Whatever5k »

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?
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:timer function

Post by Pype.Clicker »

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

Code: Select all

q-->[PID=1 | delay=10]
and that you add PID=2, delay = 2, the resulting list is

Code: Select all

q --> [PID=2 | delay= +2] --> [PID=1 | delay = +8]
Well seen from you ;)
Post Reply