#7719 closed Bugs (invalid)
C++11 steady_clock is not monotonic on Win32 & OSX
| Reported by: | Owned by: | viboes | |
|---|---|---|---|
| Milestone: | Component: | chrono | |
| Version: | Boost 1.52.0 | Severity: | Problem |
| Keywords: | Cc: |
Description
Boost 1.52 defers to different OS specific calls for implementation of the std::chrono::steady_clock monotonic interface. There are supposed to be two characteristics: 1) monotonic, 2) independent of wall time. The current Boost implementation only achieves the latter.
Issue raised from Stackoverflow: stackoverflow.com/q/13478093/175849
Per platform discussion:
POSIX: defers to clock_gettime (CLOCK_MONOTONIC). Generally sufficient excepting peculiarities of hyper-threading.
OSX: defers to mach_absolute_time() which is implemented by RDTSC which is only monotonic on the same core.
Apple recommend per their documentation to use clock_get_time(SYSTEM_CLOCK) as a monotonic source. References:
www.opensource.apple.com/source/xnu/xnu-1486.2.11/osfmk/man/clock_get_time.html
stackoverflow.com/q/11680461/175849
An important caveat is that the clock is not monotonic if clock_set_time() is called.
Win32: defers to QueryPerformanceCounter() which on many platforms is not monotonic due to dependency on RDTSC as a direct source or interpolation of times from more reliable sources such as HPET, RTC, or PC AT.
Microsoft in MSVC2012 implement std::chrono using _Xtime_get_ticks() which defers to GetSystemTimeAsFileTime() as discussed here (in Japanese):
gist.github.com/3763854
This however is wall time and subject to clock changes, a more suitable source would be GetTick64Count() which requires Vista+, the alternative GetTickCount() wraps after 49.7 days.
Change History (7)
follow-up: 3 comment:2 by , 10 years ago
Of reference the Boost documentation defines is_steady() with the C++11 definition of is_monotonic(), MSDN provides the following:
A clock is monotonic if the value that is returned by a first call to
now()is always less than or equal to the value that is returned by a subsequent call tonow().
A clock is steady if it is monotonic and if the time between clock ticks is constant.
msdn.microsoft.com/en-us/library/hh874790.aspx
follow-up: 4 comment:3 by , 10 years ago
Replying to fnjordy@…:
Of reference the Boost documentation defines
is_steady()with the C++11 definition ofis_monotonic(), MSDN provides the following:
Please could you point me where in the Boost.Chrono documentation appears is_monotonic?
comment:4 by , 10 years ago
Replying to viboes:
Replying to fnjordy@…:
Of reference the Boost documentation defines
is_steady()with the C++11 definition ofis_monotonic(), MSDN provides the following:Please could you point me where in the Boost.Chrono documentation appears is_monotonic?
Oh, I got it. The doc don't use is_monotonic but the definition corresponds.
comment:5 by , 10 years ago
Your proposal are not steady (following the C++11 standard definition), except maybe GetTickCount(). The problem with GetTickCount() is that it is not enough long. Do you have a suggestion?
Please, could you give me the link to the stack overflow discussion?
comment:6 by , 10 years ago
| Resolution: | → invalid |
|---|---|
| Status: | assigned → closed |
comment:7 by , 10 years ago
| Milestone: | To Be Determined |
|---|

A steady clock is not necessarily a monotonic clock. N3128 (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3128.html) is the proposal that removed monotonic clocks and added steady clocks and includes the rationale:
The implementation of the timeout definition necessarily depends on a steady clock, one that cannot be adjusted. A monotonic clock is not sufficient. While one could be implicit in the standard, below we make one explicit. Given a steady clock, the monotonic clock seems to be of marginal utility, and we replace the monotonic clock with the steady clock.Please, let me know if there is something in the documentation that say something that doesn't conforms to the C++11 standard.