Thank you in advance
If you have kernel support for clock_gettime, you could work around
missing glibc support by doing the syscalls directly, see syscall(2)/
_syscall(2). Otherwise, you will have to use gettimeofday.
If you don't have any kernel support, it will be difficult to get
monotonic clock... Especially gettimeofday() & co. are subject to time
change (e.g. NTP etc).
Cheers,
Loïc
--
My Blog: http://www.domaigne.com/blog
"Hardware: The parts of a computer system that can be kicked." --
Jeff Pesis
This is not usually anyhow difficult because it is the purpose of NTP
to provide a monotonic clock. The documentation accompanying the NTP
reference implementation calls this 'the clock correctness
principle'. This is also a requirement for most distributed
systems. The only real problem here is people who run ntpdate (or its
predecessors) from cron and thereby cause random clock jumps to happen
in unpredictable intervals. Insofar these cannot be 'fixed', they can
usually at least be replaced.
It depends on exactly what your requirements are. Your system's
equivalent of 'uptime' may be the best solution.
DS
I need a wall-time clock that 1) it's not dependant upon the system's
datetime for a server application -for calculating timeouts- and 2) has
at least 10 ms precision.
[...]
> I need a wall-time clock that 1) it's not dependant upon the system's
> datetime for a server application -for calculating timeouts- and 2)
> has at least 10 ms precision.
As I already wrote: You or the person administering the system you are
using needs to get a clue about the intended purpose of clocks,
namely, to measure time intervals and not to provide pseudo-random
numbers.
> As I already wrote: You or the person administering the system you are
> using needs to get a clue about the intended purpose of clocks,
> namely, to measure time intervals and not to provide pseudo-random
> numbers.
>
Yes, I read your other message. The fact is that I have to ensure that
the application works correctly even if the person administering the
system does something wrong to the machine's datetime.
> I need a wall-time clock that 1) it's not dependant upon the system's
> datetime for a server application -for calculating timeouts- and 2) has
> at least 10 ms precision.
Using a wall time clock for calculating timeouts is idiotic. Why would
you want to do that? You should be using an elapsed time clock (from
an arbitrary starting point) to do that.
Your requirements seem to be internally conflicting. For example, what
should happen if the system's best guess of actual wall time does in
fact go back ten seconds?
DS
> Yes, I read your other message. The fact is that I have to ensure that
> the application works correctly even if the person administering the
> system does something wrong to the machine's datetime.
What are the requirements for the application to work correctly? You
may need to construct your own clock to your specific requirements.
DS
Using your PRNG as clock would be idiotic. But that hasn't stopped
billions of people from successfully using their watches in order to
coordinate independent actions based on a common reference
time and the fact that 'a minute from now' will be 'a minute from now'
(within the accuracy limits of the oscillator) and not 'two minutes
in the past because the clock was off'.
[...]
> Your requirements seem to be internally conflicting. For example, what
> should happen if the system's best guess of actual wall time does in
> fact go back ten seconds?
That's extraordinary simple: I go to the superior of the person who
configured this, say something like 'sorry, but I need the walltime
clock to work' and this is going to solve the problem. Actually, going
to the person itself used to be sufficient up to now. After all, the
internet isn't exactly a new phenomenon.
> > Your requirements seem to be internally conflicting. For example, what
> > should happen if the system's best guess of actual wall time does in
> > fact go back ten seconds?
> That's extraordinary simple: I go to the superior of the person who
> configured this, say something like 'sorry, but I need the walltime
> clock to work' and this is going to solve the problem. Actually, going
> to the person itself used to be sufficient up to now. After all, the
> internet isn't exactly a new phenomenon.
"The car blew up because it ran out of gas."
"Simple fix, when the car is low on gas, fill the tank up. Don't let
it go empty."
Nope, sorry. Cars shouldn't blow up because they run out of gas, even
though it's possible to never run a car out of gas.
DS
Yes, my fault: english is not my mother language and I may not be
expressing correctly what are my requirements, sorry again.
Let's see if I can made myself clear with some source code. Actually, I
have a callback that's invoked "many times" per second, but I don't know
how much times. That's what I would like to do inside it:
void Object::callback() {
timespec now_ts;
clock_gettime( CLOCK_MONOTONIC, &now_ts );
if( now_ts - this->_last_stored_ts > TIMEOUT ) {
this->timeoutElapsed();
swap( now_ts, this->_last_stored_ts );
}
}
so, if the system datetime is changed, the timeout is still correctly
evaluated.
Now, the problem is that my target system doesn't support
CLOCK_MONOTONIC macro and clock(3) returns the processor time used by
the program.
Rainer is correct when he says that if NTP is working correctly, I could
-i.e.- change CLOCK_MONOTONIC with CLOCK_REALTIME, but -as for
requirements- I can't assume that NTP is working/configured correctly.
And no, I'm not writing the requirements :-)
> Your requirements seem to be internally conflicting. For example, what
> should happen if the system's best guess of actual wall time does in
> fact go back ten seconds?
>
Hope that the previous example clarifies this.
> Yes, my fault: english is not my mother language and I may not be
> expressing correctly what are my requirements, sorry again.
No problem. Often if we could figure out the right way to ask a
question, we wouldn't have a question at all.
> Let's see if I can made myself clear with some source code. Actually, I
> have a callback that's invoked "many times" per second, but I don't know
> how much times. That's what I would like to do inside it:
>
> void Object::callback() {
> timespec now_ts;
> clock_gettime( CLOCK_MONOTONIC, &now_ts );
> if( now_ts - this->_last_stored_ts > TIMEOUT ) {
> this->timeoutElapsed();
> swap( now_ts, this->_last_stored_ts );
> }
>
> }
>
> so, if the system datetime is changed, the timeout is still correctly
> evaluated.
>
> Now, the problem is that my target system doesn't support
> CLOCK_MONOTONIC macro and clock(3) returns the processor time used by
> the program.
>
> Rainer is correct when he says that if NTP is working correctly, I could
> -i.e.- change CLOCK_MONOTONIC with CLOCK_REALTIME, but -as for
> requirements- I can't assume that NTP is working/configured correctly.
> And no, I'm not writing the requirements :-)
Depending on how tight your requirements are and how often you expect
to be called, there are quite a few things you could do.
If you don't get called too often, and/or you know that checking the
system uptime is cheap on your system, and it has enough resolution,
you can use the system uptime to base your timeout.
If the problem is that checking the system uptime is too expensive and
you do it too often or it doesn't have enough resolution, you can
augment the system uptime check with a clock wall time check. You can
check wall time first, and if it appears valid, go with it. If it
appears to have jumped too much, fall back to the uptime and readjust
your "uptime walltime offset".
The same trick can be used if uptime does not have enough resolution.
Use wall time, keep the offset between wall time and uptime, and if
the wall time may have jumped (because you see a suspiciously large
jump in wall time), then check with uptime and reset the offset. Your
time will appear continuous because you act on the wall time adjusted
by the offset. (This may result in spurious checks of the uptime if
you don't get called for a few seconds, but since you must be under
low load when that happens, the extra cost is negligible. Your next
quick call won't result in that check.)
So you can use this flowchart to get the uptime without calling the
uptime function very much:
1) Get the system time.
2) Is the system time reasonably close to the last value I got, and
not less than it?
3) If yes, add the offset and return the offset time.
4) Otherwise, get the uptime.
5) Calculate the difference between system time and the uptime. If
it's significantly different from our calculated offset, save it as
the new offset. (Clock skew detected.) If monotonicity is an absolute
requirement, enforce it here if needed.
6) Return the system time plus the (possibly new) offset just as in
step 3.
There's no need to do this if your uptime function has the same
resolution as your system time or is about as expensive. But most
systems have a fast, accurate (in the sense of having high resolution)
system time but a slow, low-resolution uptime.
DS
,----
| Using your PRNG as clock would be idiotic. But that hasn't stopped
| billions of people from successfully using their watches in order to
| coordinate independent actions based on a common reference
| time and the fact that 'a minute from now' will be 'a minute from now'
| (within the accuracy limits of the oscillator) and not 'two minutes
| in the past because the clock was off'.
`----
Distributed systems (and as I wrote, these are by no means new) need
to coordinate their actions, based on a common reference time base and
a monotonic clock, in just the same way as people do. I'll happily
again quote parts of the NTP documentation on this:
4.1.3. Why should Time be synchronized?
Time usually just advances. If you have communicating programs
running on different computers, time still should even advance
if you switch from one computer to another. Obviously if one
system is ahead of the others, the others are behind that
particular one. From the perspective of an external observer,
switching between these systems would cause time to jump
forward and back, a non-desirable effect.
As a consequence, isolated networks may run their own wrong
time, but as soon as you connect to the Internet, effects will
be visible. Just imagine some EMail message arrived five
minutes before it was sent, and there even was a reply two
minutes before the message was sent.
Even on a single computer some applications have trouble when
the time jumps backwards. For example, database systems using
transactions and crash recovery like to know the time of the
last good state.[1]
Therefore, air traffic control was one of the first
applications for NTP.
http://www.ntp.org/ntpfaq/NTP-s-def.htm
That (according to some random source on the internet) NT cannot do
this just implies that it is a substandard platform unusable for a lot
of 'serious computing work' and not that UNIX(*) timekeeping needs to
be broken as well.
In case you haven't noticed this, computer networks in their present
form were invented something 35 years ago and distributed systems
using 'the internet' as communication medium are not new,
either. Paraphrasing an old Jefferson Airplane text: No computer is an
island. At least no 'interesting' computer.
First, let me say that I 100% agree with your point and literally
agree with 99% of what you wrote. Time keeping is frequently ignored,
seldom done correctly, and important in many cases that are
unrecognized. However, I feel obligated to point out:
> Distributed systems (and as I wrote, these are by no means new) need
> to coordinate their actions, based on a common reference time base and
> a monotonic clock, in just the same way as people do. I'll happily
> again quote parts of the NTP documentation on this:
Monotonicity is seldom a core requirement and only very few
implementations actually require it. There are many cases where
guaranteed monotonicity would require unacceptable trade-offs. (Even
NTP, by default, does not guarantee monotonicity, though it would have
to get into a severely broken state to behave non-monotonically.)
The problem is that most typical time uses just want the system's best
guess at wall time. Obviously, the better the system's wall clock is
synchronize and the more stably it flows, the better. But many uses
also want an even rate of flow. They want the clock to read 300ms
later in as close to 300ms as possible because they use the clock for
timeouts and the like.
The problem occurs when the system clock discovers that it is, say, an
hour behind wall clock time. Maybe it started up with no Internet
connectivity or synched to a bad clock. Ideally, this wouldn't happen,
but it can.
If you insist on monotonicity in this case, the system will have to
run the clock slower until it loses an hour. This will either mean a
severely off rate of flow for a short time or a somewhat off rate of
flow for a long time. In many cases, it's much more sensible to jump
the clock backwards.
Of course, the best solution is not to get into this case. But an
absolute insistence on monotonicity for the system's default wall
clock (even if we happen to get into these edge cases) is not usually
sensible.
The basic problem is that the same timebase is frequently used for
purposes with differing requirements. The best solution is to have
multiple timebases, which most modern systems do.
DS