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.
On Sun, Jan 1, 2017 at 1:09 PM, Howard Hinnant <howard.hinn...@gmail.com> wrote: > On Jan 1, 2017, at 3:20 PM, Saleem Abdulrasool via cfe-commits < > cfe-commits@lists.llvm.org> wrote: > > > > Author: compnerd > > Date: Sun Jan 1 14:20:41 2017 > > New Revision: 290803 > > > > URL: http://llvm.org/viewvc/llvm-project?rev=290803&view=rev > > Log: > > chrono: implement a Windows version of system_clock::now > > > > system_clock::now is not entirely straight forward on Windows, which > > does not have a clock_gettime function. > > > > GetSystemTimeAsFileTime gives us the value relative to the NT epoch (Jan > > 1 1601) rather than the Unix epoch (Jan 1 1970). However, this function > > has a low resolution (~10ms). Newer versions of Windows provide > > GetSystemTimePreciseAsFileTime which gives us a much more accurate time > > (<1us). Unfortunately, the latter is only available on Windows 8+ when > > targeting desktop apps. > > > > Modified: > > libcxx/trunk/src/chrono.cpp > > > > Modified: libcxx/trunk/src/chrono.cpp > > URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/ > chrono.cpp?rev=290803&r1=290802&r2=290803&view=diff > > ============================================================ > ================== > > --- libcxx/trunk/src/chrono.cpp (original) > > +++ libcxx/trunk/src/chrono.cpp Sun Jan 1 14:20:41 2017 > > @@ -12,9 +12,18 @@ > > #include "system_error" // __throw_system_error > > #include <time.h> // clock_gettime, CLOCK_MONOTONIC and > CLOCK_REALTIME > > > > +#if defined(_WIN32) > > +#define WIN32_LEAN_AND_MEAN > > +#define VC_EXTRA_LEAN > > +#include <Windows.h> > > +#if _WIN32_WINNT >= _WIN32_WINNT_WIN8 > > +#include <winapifamily.h> > > +#endif > > +#else > > #if !defined(CLOCK_REALTIME) > > #include <sys/time.h> // for gettimeofday and timeval > > #endif > > +#endif > > > > #if !defined(_LIBCPP_HAS_NO_MONOTONIC_CLOCK) && > !defined(CLOCK_MONOTONIC) > > #if __APPLE__ > > @@ -36,6 +45,28 @@ const bool system_clock::is_steady; > > system_clock::time_point > > system_clock::now() _NOEXCEPT > > { > > +#if defined(_WIN32) > > + // The Windows epoch is Jan 1 1601, the Unix epoch Jan 1 1970. The > difference > > + // in nanoseconds is the windows epoch offset. > > + static const constexpr __int64 kWindowsEpochOffset = > 0x19db1ded53e8000; > > This is the correct difference, but the comment is wrong. It isn’t > nanoseconds. It is 100ns units. > > Maybe I got the math wrong, but this was supposed to be ns, which is why I bounced between 100ns and ns. > > + > > + FILETIME ftSystemTime; > > +#if _WIN32_WINNT >= _WIN32_WINNT_WIN8 > > +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) > > + GetSystemTimePreciseAsFileTime(&ftSystemTime); > > +#else > > + GetSystemTimeAsFileTime(&ftSystemTime); > > +#endif > > +#else > > + GetSystemTimeAsFileTime(&ftSystemTime); > > +#endif > > + __int64 llWinTimeNS = > > + ((static_cast<__int64>(ftSystemTime.dwHighDateTime) << 32) | > > + static_cast<__int64>(ftSystemTime.dwLowDateTime)) * > > + 100; > > 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. > > This is what I get for trying to be clever and not use durations. > > + return time_point(duration_cast<duration>( > > + (nanoseconds(llWinTimeNS - kWindowsEpochOffset)))); > > It really isn’t desirable to bounce this off of nanoseconds because of the > overflow. 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. > > +#else > > #ifdef CLOCK_REALTIME > > struct timespec tp; > > if (0 != clock_gettime(CLOCK_REALTIME, &tp)) > > @@ -46,6 +77,7 @@ system_clock::now() _NOEXCEPT > > gettimeofday(&tv, 0); > > return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec)); > > #endif // CLOCK_REALTIME > > +#endif > > } > > 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. > > Here is code written by Billy O’Neal (MS) doing the conversion you’re > looking for: > > https://github.com/HowardHinnant/date/wiki/Examples-and-Recipes#FILETIME > > It has no intermediate results with precision finer than 100ns. The range > of the 64bit 100ns unit goes out to +/- 29 thousand years. Thanks for the pointer! > > Howard > > -- Saleem Abdulrasool compnerd (at) compnerd (dot) org
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits