
Hi! An application I'm writing has the special requirement that it be able to handle time-skews gracefully (like e.g. the daylight saving time or a user changing the system time). Using Boost 1.32 (but I think the same applies to later versions) it fails when I do things like this here: xtime xt; xtime_get( &xt, TIME_UTC); xt.sec += 2; thread::sleep(xt); My approach now was to implement TIME_MONOTONIC as already sketched in xtime.hpp, which was pretty straightforward (using timeGetTime() on win32). However, I noticed that this won't work, because things like thread::sleep() implicitly assume that the given time is from TIME_UTC and also only uses that one to compare against - obviously won't work when one is the time since system start and the other the time since 1970-01-01. Two solutions came to mind: 1. Convert TIME_MONOTONIC to TIME_UTC. This is more or less impossible to do reliably because a) timeGetTime() overflows frequently (every 49 days) and b) it requires some kind of fixed point that can be used for conversion, but that point simply does not exist due to the limitations that drove me to implementing TIME_MONOTONIC in the first place. 2. Add the clock type to the xtime structure. This means that every place that a time is determined via xtime_get(), e.g. in thread::sleep(), it uses the same clock type as the supplied object. I think this version makes the most sense, right? Unfortunately this breaks compatibility... On a related note, why doesn't the threading lib offer any means to yield for a certain time? In more than nine out of ten cases, this is the way I do things, waiting for a certain point in time - like Boost.Thread does - is rather the exception than the rule. Uli

On 4/10/06, Ulrich Eckhardt <doomster@knuut.de> wrote:
Hi!
An application I'm writing has the special requirement that it be able to handle time-skews gracefully (like e.g. the daylight saving time or a user changing the system time). Using Boost 1.32 (but I think the same applies to
Doesn't UTC avoid the DST issue completely? I'm also wondering why OSs don't offer a never decreasing timer.

At 6:37 PM +0200 4/10/06, Ulrich Eckhardt wrote:
Hi!
An application I'm writing has the special requirement that it be able to handle time-skews gracefully (like e.g. the daylight saving time or a user changing the system time). [...]
However, I noticed that this won't work, because things like thread::sleep() implicitly assume that the given time is from TIME_UTC and also only uses that one to compare against [...]
Regrettably, good monotonic clock support seems to be weak at both the standards level and in actual implementations. Since boost.thread is largely a portable wrapper around the underlying OS-specific facilities, that probably makes it rather difficult for boost.thread to do better.
On a related note, why doesn't the threading lib offer any means to yield for a certain time? In more than nine out of ten cases, this is the way I do things, waiting for a certain point in time - like Boost.Thread does - is rather the exception than the rule.
Because a user can easily synthesize a relative time measuer on top of an interface that uses absolute times, but there is a race condition associated with a user attempting to specify an absolute timeout on top of an interface that uses relative timeouts. See, for example, the Rationale section for pthread_cond_timedwait() in the Single Unix Specification for more details.

On Tuesday 11 April 2006 03:31, Kim Barrett wrote:
Regrettably, good monotonic clock support seems to be weak at both the standards level and in actual implementations. Since boost.thread is largely a portable wrapper around the underlying OS-specific facilities, that probably makes it rather difficult for boost.thread to do better.
I think there is still way for this to improve though. Firstly, I would change xtime_get() to return either an xtime struct or void, and throw on failure. With that, one could still implement monotonic clocks on systems that support it. What I mean is that I would be better off with a half-way solution than no solution at all.
On a related note, why doesn't the threading lib offer any means to yield for a certain time? In more than nine out of ten cases, this is the way I do things, waiting for a certain point in time - like Boost.Thread does - is rather the exception than the rule.
Because a user can easily synthesize a relative time measuer on top of an interface that uses absolute times, but there is a race condition associated with a user attempting to specify an absolute timeout on top of an interface that uses relative timeouts. See, for example, the Rationale section for pthread_cond_timedwait() in the Single Unix Specification for more details.
I read that spec, and while it is itself consistent it won't help in my situation. It explicitly says that the implementation should handle the case that a user advances(!) the clock, i.e. when the clock skips a few ticks. My case is different though, because I need to handle gracefully when the system clock moves backward, too. In other words, the race condition exist also in the case of absolute times. In case you wonder, this is part of a maintainance reminder system and in order to test that it asks for maintainance when X weeks have elapsed and that it cancels operation when X+Y weeks have elapsed, people simply turn the clock ahead and then finally turn the clock back again. If this happens between getting the current time and waiting for current time plus X, this will effectively produce a wait that goes for several weeks instead of milliseconds. Another part of the system checks for certain conditions and if they persist for more than X milliseconds it performs some actions. This, too, won't work when the clock suddenly skips ahead or backward. All in all, I think I really need monotonic time or at least the best approximation thereof, whether it is supported on all systems or not. Uli
participants (3)
-
Kim Barrett
-
Olaf van der Spek
-
Ulrich Eckhardt