chrono.cpp revision ec3773c2dadbeadfc5def927116c2ee9d9c53066
1bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//===------------------------- chrono.cpp ---------------------------------===// 2bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// 3f5256e16dfc425c1d466f6308d4026d529ce9e0bHoward Hinnant// The LLVM Compiler Infrastructure 4bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// 5b64f8b07c104c6cc986570ac8ee0ed16a9f23976Howard Hinnant// This file is dual licensed under the MIT and the University of Illinois Open 6b64f8b07c104c6cc986570ac8ee0ed16a9f23976Howard Hinnant// Source Licenses. See LICENSE.TXT for details. 7bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// 8bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant//===----------------------------------------------------------------------===// 9bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 10bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include "chrono" 11bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include <sys/time.h> //for gettimeofday and timeval 12adff4895b2746f30b271bc219713e7ded5ae9677Howard Hinnant#if __APPLE__ 13bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include <mach/mach_time.h> // mach_absolute_time, mach_timebase_info_data_t 14adff4895b2746f30b271bc219713e7ded5ae9677Howard Hinnant#else /* !__APPLE__ */ 15adff4895b2746f30b271bc219713e7ded5ae9677Howard Hinnant#include <cerrno> // errno 16adff4895b2746f30b271bc219713e7ded5ae9677Howard Hinnant#include <system_error> // __throw_system_error 17adff4895b2746f30b271bc219713e7ded5ae9677Howard Hinnant#include <time.h> // clock_gettime, CLOCK_MONOTONIC 1816e6e1d72fd6a10fc165eba4ca4ed2fa7c45df78Howard Hinnant#endif // __APPLE__ 19bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 20bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant_LIBCPP_BEGIN_NAMESPACE_STD 21bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 22bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantnamespace chrono 23bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{ 24bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 25bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// system_clock 26bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 27bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantsystem_clock::time_point 28756a1763d1a57d7d3439bb7c83b411c8f6dc4da8Howard Hinnantsystem_clock::now() _NOEXCEPT 29bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{ 30bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant timeval tv; 31bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant gettimeofday(&tv, 0); 32bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec)); 33bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant} 34bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 35bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnanttime_t 36756a1763d1a57d7d3439bb7c83b411c8f6dc4da8Howard Hinnantsystem_clock::to_time_t(const time_point& t) _NOEXCEPT 37bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{ 38bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant return time_t(duration_cast<seconds>(t.time_since_epoch()).count()); 39bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant} 40bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 41bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantsystem_clock::time_point 42756a1763d1a57d7d3439bb7c83b411c8f6dc4da8Howard Hinnantsystem_clock::from_time_t(time_t t) _NOEXCEPT 43bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{ 44bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant return system_clock::time_point(seconds(t)); 45bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant} 46bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 47f8f852138f86e4588916021e1afedfcab25298c0Howard Hinnant// steady_clock 48bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 49adff4895b2746f30b271bc219713e7ded5ae9677Howard Hinnant#if __APPLE__ 50bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// mach_absolute_time() * MachInfo.numer / MachInfo.denom is the number of 51bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// nanoseconds since the computer booted up. MachInfo.numer and MachInfo.denom 52bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// are run time constants supplied by the OS. This clock has no relationship 53bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// to the Gregorian calendar. It's main use is as a high resolution timer. 54bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 55bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// MachInfo.numer / MachInfo.denom is often 1 on the latest equipment. Specialize 56bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// for that case as an optimization. 57bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 58bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#pragma GCC visibility push(hidden) 59bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 60bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantstatic 61f8f852138f86e4588916021e1afedfcab25298c0Howard Hinnantsteady_clock::rep 62f8f852138f86e4588916021e1afedfcab25298c0Howard Hinnantsteady_simplified() 63bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{ 64ec3773c2dadbeadfc5def927116c2ee9d9c53066Howard Hinnant return static_cast<steady_clock::rep>(mach_absolute_time()); 65bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant} 66bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 67bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantstatic 68bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantdouble 69f8f852138f86e4588916021e1afedfcab25298c0Howard Hinnantcompute_steady_factor() 70bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{ 71bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant mach_timebase_info_data_t MachInfo; 72bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant mach_timebase_info(&MachInfo); 73bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant return static_cast<double>(MachInfo.numer) / MachInfo.denom; 74bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant} 75bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 76bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantstatic 77f8f852138f86e4588916021e1afedfcab25298c0Howard Hinnantsteady_clock::rep 78f8f852138f86e4588916021e1afedfcab25298c0Howard Hinnantsteady_full() 79bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{ 80f8f852138f86e4588916021e1afedfcab25298c0Howard Hinnant static const double factor = compute_steady_factor(); 81f8f852138f86e4588916021e1afedfcab25298c0Howard Hinnant return static_cast<steady_clock::rep>(mach_absolute_time() * factor); 82bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant} 83bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 84f8f852138f86e4588916021e1afedfcab25298c0Howard Hinnanttypedef steady_clock::rep (*FP)(); 85bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 86bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantstatic 87bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard HinnantFP 88f8f852138f86e4588916021e1afedfcab25298c0Howard Hinnantinit_steady_clock() 89bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{ 90bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant mach_timebase_info_data_t MachInfo; 91bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant mach_timebase_info(&MachInfo); 92bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant if (MachInfo.numer == MachInfo.denom) 93f8f852138f86e4588916021e1afedfcab25298c0Howard Hinnant return &steady_simplified; 94f8f852138f86e4588916021e1afedfcab25298c0Howard Hinnant return &steady_full; 95bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant} 96bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 9704acacadca196a2587b52942c33d4fea51411e1bDaniel Dunbar#pragma GCC visibility pop 98bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 99f8f852138f86e4588916021e1afedfcab25298c0Howard Hinnantsteady_clock::time_point 100756a1763d1a57d7d3439bb7c83b411c8f6dc4da8Howard Hinnantsteady_clock::now() _NOEXCEPT 101bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant{ 102f8f852138f86e4588916021e1afedfcab25298c0Howard Hinnant static FP fp = init_steady_clock(); 103bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant return time_point(duration(fp())); 104bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant} 105bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 10616e6e1d72fd6a10fc165eba4ca4ed2fa7c45df78Howard Hinnant#else // __APPLE__ 107adff4895b2746f30b271bc219713e7ded5ae9677Howard Hinnant// FIXME: We assume that clock_gettime(CLOCK_MONOTONIC) works on 108adff4895b2746f30b271bc219713e7ded5ae9677Howard Hinnant// non-apple systems. Instead, we should check _POSIX_TIMERS and 109adff4895b2746f30b271bc219713e7ded5ae9677Howard Hinnant// _POSIX_MONOTONIC_CLOCK and fall back to something else if those 110adff4895b2746f30b271bc219713e7ded5ae9677Howard Hinnant// don't exist. 111adff4895b2746f30b271bc219713e7ded5ae9677Howard Hinnant 112f8f852138f86e4588916021e1afedfcab25298c0Howard Hinnant// Warning: If this is not truly steady, then it is non-conforming. It is 113adff4895b2746f30b271bc219713e7ded5ae9677Howard Hinnant// better for it to not exist and have the rest of libc++ use system_clock 114adff4895b2746f30b271bc219713e7ded5ae9677Howard Hinnant// instead. 115adff4895b2746f30b271bc219713e7ded5ae9677Howard Hinnant 116f8f852138f86e4588916021e1afedfcab25298c0Howard Hinnantsteady_clock::time_point 117756a1763d1a57d7d3439bb7c83b411c8f6dc4da8Howard Hinnantsteady_clock::now() _NOEXCEPT 118adff4895b2746f30b271bc219713e7ded5ae9677Howard Hinnant{ 119adff4895b2746f30b271bc219713e7ded5ae9677Howard Hinnant struct timespec tp; 120adff4895b2746f30b271bc219713e7ded5ae9677Howard Hinnant if (0 != clock_gettime(CLOCK_MONOTONIC, &tp)) 121adff4895b2746f30b271bc219713e7ded5ae9677Howard Hinnant __throw_system_error(errno, "clock_gettime(CLOCK_MONOTONIC) failed"); 122adff4895b2746f30b271bc219713e7ded5ae9677Howard Hinnant return time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec)); 123adff4895b2746f30b271bc219713e7ded5ae9677Howard Hinnant} 12416e6e1d72fd6a10fc165eba4ca4ed2fa7c45df78Howard Hinnant#endif // __APPLE__ 125adff4895b2746f30b271bc219713e7ded5ae9677Howard Hinnant 126bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant} 127bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 128bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant_LIBCPP_END_NAMESPACE_STD 129