<div dir="ltr">Thanks for the review on this! I hope you wont mind taking a look at SVN r290806 as well which tries to address the comments.<br><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Jan 1, 2017 at 1:09 PM, Howard Hinnant <span dir="ltr"><<a href="mailto:howard.hinnant@gmail.com" target="_blank">howard.hinnant@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On Jan 1, 2017, at 3:20 PM, Saleem Abdulrasool via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a>> wrote:<br>
><br>
> Author: compnerd<br>
> Date: Sun Jan 1 14:20:41 2017<br>
> New Revision: 290803<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=290803&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=290803&view=rev</a><br>
> Log:<br>
> chrono: implement a Windows version of system_clock::now<br>
><br>
> system_clock::now is not entirely straight forward on Windows, which<br>
> does not have a clock_gettime function.<br>
><br>
> GetSystemTimeAsFileTime gives us the value relative to the NT epoch (Jan<br>
> 1 1601) rather than the Unix epoch (Jan 1 1970). However, this function<br>
> has a low resolution (~10ms). Newer versions of Windows provide<br>
> GetSystemTimePreciseAsFileTime which gives us a much more accurate time<br>
> (<1us). Unfortunately, the latter is only available on Windows 8+ when<br>
> targeting desktop apps.<br>
><br>
> Modified:<br>
> libcxx/trunk/src/chrono.cpp<br>
><br>
> Modified: libcxx/trunk/src/chrono.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/chrono.cpp?rev=290803&r1=290802&r2=290803&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/libcxx/trunk/src/<wbr>chrono.cpp?rev=290803&r1=<wbr>290802&r2=290803&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- libcxx/trunk/src/chrono.cpp (original)<br>
> +++ libcxx/trunk/src/chrono.cpp Sun Jan 1 14:20:41 2017<br>
> @@ -12,9 +12,18 @@<br>
> #include "system_error" // __throw_system_error<br>
> #include <time.h> // clock_gettime, CLOCK_MONOTONIC and CLOCK_REALTIME<br>
><br>
> +#if defined(_WIN32)<br>
> +#define WIN32_LEAN_AND_MEAN<br>
> +#define VC_EXTRA_LEAN<br>
> +#include <Windows.h><br>
> +#if _WIN32_WINNT >= _WIN32_WINNT_WIN8<br>
> +#include <winapifamily.h><br>
> +#endif<br>
> +#else<br>
> #if !defined(CLOCK_REALTIME)<br>
> #include <sys/time.h> // for gettimeofday and timeval<br>
> #endif<br>
> +#endif<br>
><br>
> #if !defined(_LIBCPP_HAS_NO_<wbr>MONOTONIC_CLOCK) && !defined(CLOCK_MONOTONIC)<br>
> #if __APPLE__<br>
> @@ -36,6 +45,28 @@ const bool system_clock::is_steady;<br>
> system_clock::time_point<br>
> system_clock::now() _NOEXCEPT<br>
> {<br>
> +#if defined(_WIN32)<br>
> + // The Windows epoch is Jan 1 1601, the Unix epoch Jan 1 1970. The difference<br>
> + // in nanoseconds is the windows epoch offset.<br>
> + static const constexpr __int64 kWindowsEpochOffset = 0x19db1ded53e8000;<br>
<br>
</div></div>This is the correct difference, but the comment is wrong. It isn’t nanoseconds. It is 100ns units.<br>
<span class=""><br></span></blockquote><div>Maybe I got the math wrong, but this was supposed to be ns, which is why I bounced between 100ns and ns.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">
> +<br>
> + FILETIME ftSystemTime;<br>
> +#if _WIN32_WINNT >= _WIN32_WINNT_WIN8<br>
> +#if WINAPI_FAMILY_PARTITION(<wbr>WINAPI_PARTITION_DESKTOP)<br>
> + GetSystemTimePreciseAsFileTime<wbr>(&ftSystemTime);<br>
> +#else<br>
> + GetSystemTimeAsFileTime(&<wbr>ftSystemTime);<br>
> +#endif<br>
> +#else<br>
> + GetSystemTimeAsFileTime(&<wbr>ftSystemTime);<br>
> +#endif<br>
> + __int64 llWinTimeNS =<br>
> + ((static_cast<__int64>(<wbr>ftSystemTime.dwHighDateTime) << 32) |<br>
> + static_cast<__int64>(<wbr>ftSystemTime.dwLowDateTime)) *<br>
> + 100;<br>
<br>
</span>The * 100 will overflow. The * 100 converts 100ns to ns. ns has a signed 64bit range of +/- 292 years, which is greater than the difference between the two epochs.<br>
<span class=""><br></span></blockquote><div><br></div><div>This is what I get for trying to be clever and not use durations.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">
> + return time_point(duration_cast<<wbr>duration>(<br>
> + (nanoseconds(llWinTimeNS - kWindowsEpochOffset))));<br>
<br>
</span>It really isn’t desirable to bounce this off of nanoseconds because of the overflow.</blockquote><div> </div><div>Yeap; This now becomes a duration_cast<duration>(filetime_duration) ... letting durations figure out how to do the conversion from 100ns (filetime_duration) to us (sytem_clock::duration) units.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">
> +#else<br>
> #ifdef CLOCK_REALTIME<br>
> struct timespec tp;<br>
> if (0 != clock_gettime(CLOCK_REALTIME, &tp))<br>
> @@ -46,6 +77,7 @@ system_clock::now() _NOEXCEPT<br>
> gettimeofday(&tv, 0);<br>
> return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec));<br>
> #endif // CLOCK_REALTIME<br>
> +#endif<br>
> }<br>
<br>
</span>Thank you for preserving the 1970 epoch. Though not currently specified by the standard, it is very important. And hopefully will be specified by a future standard.<br>
<br>
Here is code written by Billy O’Neal (MS) doing the conversion you’re looking for:<br>
<br>
<a href="https://github.com/HowardHinnant/date/wiki/Examples-and-Recipes#FILETIME" rel="noreferrer" target="_blank">https://github.com/<wbr>HowardHinnant/date/wiki/<wbr>Examples-and-Recipes#FILETIME</a><br>
<br>
It has no intermediate results with precision finer than 100ns. The range of the 64bit 100ns unit goes out to +/- 29 thousand years.</blockquote><div><br></div><div>Thanks for the pointer!</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="HOEnZb"><font color="#888888"><br>
Howard<br>
<br>
</font></span></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature">Saleem Abdulrasool<br>compnerd (at) compnerd (dot) org</div>
</div></div>