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