usage of time() for timeout handling

First off, most of us use something that ticks faster than time(), let's say clock(). Then we make sure to use unsigned arithmetic and always subtract clock values such that an "earlier" clock value is subtracted from a "later" clock value. Something like:

if ((now - then) >= TIMEOUT_THRESHOLD) { signal_timeout(); }

--
Dan Henry
Reply to
Dan Henry
Loading thread data ...

Whithout more context this is difficult to give an answer. On some systems I increment a 32 bit counter at each interrupt of the real time clock say every 10ms. You can always compute the difference between the values of the counter at each call. You increment the counter in the realtime interrupt ISR. You can read the counter from a user task but you must take into account the possibility that your task will be interrupted by the ISR. If the size of the counter is an int, say 32 bits on a 32 bits processor the incrementation will be atomic and you will always read correct values. otherwise if you are using a 32 bit counter on a 8 bit processor, you should read the counter value twice from the user task and verify that you have the same value, otherwise you read again.

Even if the counter rolls over you can compute the difference if you use unsigned integers.

This method is independant of the actual time of the system. Even if the user changes the time the counter will not be modified.

HTH

Reply to
Lanarcam

Hi gurus, I'm having some modules, that use time() for determine if a given activity has timed out. As the operating system time will be updated periodically with the time or the RTC chip, it is possible that the result of two calls to time() would give a smaller value on the second call. This would cause the timeout calculation to fail and result in unexpected behaviour. This situation could specially occour if the user changed the time of the system! How are you handling this problem? On could use the system tick for timeout calculations. But somewhere I read that for acuracy reason you should not do this for longer timeouts. How do you handle this problem?

Thanks in adbance David

Reply to
David

If this is Linux, you can use uptime. There is no uptime system call, unfortunately, so I process /proc/uptime to get the information. Less than elegant, but I have had no problems doing this.

Uptime continuously counts up since bootup.

If this is Linux, please say so next time. The resolution of uptime is high, and the accuracy is good.

Reply to
Bryan Hackney

David wrote: ) Hi gurus, ) I'm having some modules, that use time() for determine if a given activity ) has timed out. As the operating system time will be updated periodically ) with the time or the RTC chip, it is possible that the result of two calls

A good operating system will not 'jump' the OS clock to the correct time, it will slow down or speed up the OS clock so that it will match the correct timeafter a while. (Unless the jump is too great, in which case it will do it at once, but with a warning in a log file of some sort.)

) to time() would give a smaller value on the second call. This would cause ) the timeout calculation to fail and result in unexpected behaviour. ) This situation could specially occour if the user changed the time of the ) system! How are you handling this problem? On could use the system tick for ) timeout calculations. But somewhere I read that for acuracy reason you ) should not do this for longer timeouts. How do you handle this problem?

There are usually system calls that return different clocks that do not suffer from this problem, because they aren't synchronized with world time.

SaSW, Willem

--
Disclaimer: I am in no way responsible for any of the statements
            made in the above text. For all I know I might be
 Click to see the full signature
Reply to
Willem

Willem wrote (in article ):

windows, linux and OS X must all be "not good" then. Which I won't dispute. :-)

--
Randy Howard (2reply remove FOOBAR)
Reply to
Randy Howard

Managing various timers even with no operating system may be accomplish the following way:

1) In main() every 10msec (tick or 10 ticks of 1msec, you are calling constantly the function which increments all timers in the system ( no matter timer is active or no). 2) You divide your activity as state machine program in which from the moment you want to count time you simply clear the appropriate variable. In SM=0 -> var_timer1=0; ( in Count10msec() -> var_timer1++; ) In SM=1 you check whether var_timer1>msec(1000) if the timeout is 1 sec.

If required more timing intervals of the same variable, more states may be added.I am using up to 20-30 timers that way,don't have any problem with this.Normally, only some of the timers are active at the given moment.

Of course the resolution is 10msec.I mean that maximum error may be 10 msec because there is no correlation between the aplication and the function which constantly increments all variables.

HTH

Reply to
yossi_sr

But only by user intervention --- the automatic timer update will step backwards only once, ever (sometime in 2038 typically).

That's one reason why you shouldn't use time() for this unless you have absolutely no other option. Even clock() will generally be better than time().

Only if you did wrongly.

For the embedded world: by not allowing the users to get his dirty hands on internal timer values.

--
Hans-Bernhard Broeker (broeker@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.
Reply to
Hans-Bernhard Broeker

if you are only looking for time intervals why are you calling the wall clock function?

Look into using the alarm() function. From the man page -

NAME alarm - set an alarm clock for delivery of a signal

SYNOPSIS #include

unsigned int alarm(unsigned int seconds);

DESCRIPTION alarm arranges for a SIGALRM signal to be delivered to the process in seconds seconds.

If seconds is zero, no new alarm is scheduled.

In any event any previously set alarm is cancelled.

RETURN VALUE alarm returns the number of seconds remaining until any previously scheduled alarm was due to be delivered, or zero if there was no previ- ously scheduled alarm.

So there is NO interference from changing clock time, no maintenance of internal counters. Just process the SIGALRM signal. This could be as easy as setting a flag to be checked in your main loop/thread.

I'm really surprised no one else mentioned this solution. And if you are working in a Microsoft OS, check for something similar.

Ed.

NOTE: Dan's comments probably refer to low level drivers or hard realtime applications which usually need to proceess on those shorter time intervals and have available those special functions. (Or access to actual hardware timers.)

Reply to
Ed Prochak

Ed wrote: ) if you are only looking for time intervals why are you calling the wall ) clock function? ) ) Look into using the alarm() function. From the man page -

) ) ) In any event any previously set alarm is cancelled.

This means that the *entire* process can only have one alarm running at a time. So it's unsuited as-is for more than one timeout at a time.

) I'm really surprised no one else mentioned this solution. And if you ) are working in a Microsoft OS, check for something similar.

alarm() just isn't used much for timeouts, I guess. Maybe for the abovementioned reasone. Or maybe because the way signal handlers work differs subtly across platforms, and is hairy at best.

SaSW, Willem

--
Disclaimer: I am in no way responsible for any of the statements
            made in the above text. For all I know I might be
 Click to see the full signature
Reply to
Willem

and worrying about changing clock settings isn't a problem? the other solutions all proposed some workaround to calling time(). They all suffer the reversed clock problem (except for Dan).

The OP asked about timeout and specifically mentioned resolutions on level of whole seconds. (he's currentlly calling the time() function.) He made no explicit mention of needing more than one timeout. But if he does, then he just needs some cooperation between the different timeouts. It would be easy to set up shared functions that allow him to: create a timeout cancel a timeout start a timeout for a given number of seconds with a SIGALARM handler function that uses the data created by those functions to provide multiple timeouts. IF he needs this he should be able to program it. This isn't a difficult thing. Not much more work than what you would do with start/stop values. He could put all these functions in another small module.

And yes it is possible to send a SIGALRM from something other than the alarm(). (And you better read all of the alarm() manpage for other side effects.) But the point is the system clock can be changed all they want, his code will not be effected. And I presented a function that doesn't have that problem.

So unless there is a special function in his OS/language for this, I think alarm() is the best choice.

Ed

Reply to
Ed Prochak

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.