annotate DEPENDENCIES/generic/include/boost/chrono/detail/inlined/mac/chrono.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 // mac/chrono.cpp --------------------------------------------------------------//
Chris@16 2
Chris@16 3 // Copyright Beman Dawes 2008
Chris@16 4 // Copyright 2009-2010 Vicente J. Botet Escriba
Chris@16 5
Chris@16 6 // Distributed under the Boost Software License, Version 1.0.
Chris@16 7 // See http://www.boost.org/LICENSE_1_0.txt
Chris@16 8
Chris@16 9
Chris@16 10 //----------------------------------------------------------------------------//
Chris@16 11 // Mac //
Chris@16 12 //----------------------------------------------------------------------------//
Chris@16 13
Chris@16 14 #include <sys/time.h> //for gettimeofday and timeval
Chris@16 15 #include <mach/mach_time.h> // mach_absolute_time, mach_timebase_info_data_t
Chris@16 16
Chris@16 17 namespace boost
Chris@16 18 {
Chris@16 19 namespace chrono
Chris@16 20 {
Chris@16 21
Chris@16 22 // system_clock
Chris@16 23
Chris@16 24 // gettimeofday is the most precise "system time" available on this platform.
Chris@16 25 // It returns the number of microseconds since New Years 1970 in a struct called timeval
Chris@16 26 // which has a field for seconds and a field for microseconds.
Chris@16 27 // Fill in the timeval and then convert that to the time_point
Chris@16 28 system_clock::time_point
Chris@16 29 system_clock::now() BOOST_NOEXCEPT
Chris@16 30 {
Chris@16 31 timeval tv;
Chris@16 32 gettimeofday(&tv, 0);
Chris@16 33 return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec));
Chris@16 34 }
Chris@16 35
Chris@16 36 #if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
Chris@16 37 system_clock::time_point
Chris@16 38 system_clock::now(system::error_code & ec)
Chris@16 39 {
Chris@16 40 timeval tv;
Chris@16 41 gettimeofday(&tv, 0);
Chris@16 42 if (!BOOST_CHRONO_IS_THROWS(ec))
Chris@16 43 {
Chris@16 44 ec.clear();
Chris@16 45 }
Chris@16 46 return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec));
Chris@16 47 }
Chris@16 48 #endif
Chris@16 49 // Take advantage of the fact that on this platform time_t is nothing but
Chris@16 50 // an integral count of seconds since New Years 1970 (same epoch as timeval).
Chris@16 51 // Just get the duration out of the time_point and truncate it to seconds.
Chris@16 52 time_t
Chris@16 53 system_clock::to_time_t(const time_point& t) BOOST_NOEXCEPT
Chris@16 54 {
Chris@16 55 return time_t(duration_cast<seconds>(t.time_since_epoch()).count());
Chris@16 56 }
Chris@16 57
Chris@16 58 // Just turn the time_t into a count of seconds and construct a time_point with it.
Chris@16 59 system_clock::time_point
Chris@16 60 system_clock::from_time_t(time_t t) BOOST_NOEXCEPT
Chris@16 61 {
Chris@16 62 return system_clock::time_point(seconds(t));
Chris@16 63 }
Chris@16 64
Chris@16 65 namespace chrono_detail
Chris@16 66 {
Chris@16 67
Chris@16 68 // steady_clock
Chris@16 69
Chris@16 70 // Note, in this implementation steady_clock and high_resolution_clock
Chris@16 71 // are the same clock. They are both based on mach_absolute_time().
Chris@16 72 // mach_absolute_time() * MachInfo.numer / MachInfo.denom is the number of
Chris@16 73 // nanoseconds since the computer booted up. MachInfo.numer and MachInfo.denom
Chris@16 74 // are run time constants supplied by the OS. This clock has no relationship
Chris@16 75 // to the Gregorian calendar. It's main use is as a high resolution timer.
Chris@16 76
Chris@16 77 // MachInfo.numer / MachInfo.denom is often 1 on the latest equipment. Specialize
Chris@16 78 // for that case as an optimization.
Chris@16 79 BOOST_CHRONO_STATIC
Chris@16 80 steady_clock::rep
Chris@16 81 steady_simplified()
Chris@16 82 {
Chris@16 83 return mach_absolute_time();
Chris@16 84 }
Chris@16 85
Chris@16 86 #if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
Chris@16 87 BOOST_CHRONO_STATIC
Chris@16 88 steady_clock::rep
Chris@16 89 steady_simplified_ec(system::error_code & ec)
Chris@16 90 {
Chris@16 91 if (!BOOST_CHRONO_IS_THROWS(ec))
Chris@16 92 {
Chris@16 93 ec.clear();
Chris@16 94 }
Chris@16 95 return mach_absolute_time();
Chris@16 96 }
Chris@16 97 #endif
Chris@16 98
Chris@16 99 BOOST_CHRONO_STATIC
Chris@16 100 double
Chris@16 101 compute_steady_factor(kern_return_t& err)
Chris@16 102 {
Chris@16 103 mach_timebase_info_data_t MachInfo;
Chris@16 104 err = mach_timebase_info(&MachInfo);
Chris@16 105 if ( err != 0 ) {
Chris@16 106 return 0;
Chris@16 107 }
Chris@16 108 return static_cast<double>(MachInfo.numer) / MachInfo.denom;
Chris@16 109 }
Chris@16 110
Chris@16 111 BOOST_CHRONO_STATIC
Chris@16 112 steady_clock::rep
Chris@16 113 steady_full()
Chris@16 114 {
Chris@16 115 static kern_return_t err;
Chris@16 116 static const double factor = chrono_detail::compute_steady_factor(err);
Chris@16 117 if (err != 0)
Chris@16 118 {
Chris@16 119 BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
Chris@16 120 }
Chris@16 121 return static_cast<steady_clock::rep>(mach_absolute_time() * factor);
Chris@16 122 }
Chris@16 123
Chris@16 124 #if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
Chris@16 125 BOOST_CHRONO_STATIC
Chris@16 126 steady_clock::rep
Chris@16 127 steady_full_ec(system::error_code & ec)
Chris@16 128 {
Chris@16 129 static kern_return_t err;
Chris@16 130 static const double factor = chrono_detail::compute_steady_factor(err);
Chris@16 131 if (err != 0)
Chris@16 132 {
Chris@16 133 if (BOOST_CHRONO_IS_THROWS(ec))
Chris@16 134 {
Chris@16 135 boost::throw_exception(
Chris@16 136 system::system_error(
Chris@16 137 err,
Chris@16 138 BOOST_CHRONO_SYSTEM_CATEGORY,
Chris@16 139 "chrono::steady_clock" ));
Chris@16 140 }
Chris@16 141 else
Chris@16 142 {
Chris@16 143 ec.assign( errno, BOOST_CHRONO_SYSTEM_CATEGORY );
Chris@16 144 return steady_clock::rep();
Chris@16 145 }
Chris@16 146 }
Chris@16 147 if (!BOOST_CHRONO_IS_THROWS(ec))
Chris@16 148 {
Chris@16 149 ec.clear();
Chris@16 150 }
Chris@16 151 return static_cast<steady_clock::rep>(mach_absolute_time() * factor);
Chris@16 152 }
Chris@16 153 #endif
Chris@16 154
Chris@16 155 typedef steady_clock::rep (*FP)();
Chris@16 156 #if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
Chris@16 157 typedef steady_clock::rep (*FP_ec)(system::error_code &);
Chris@16 158 #endif
Chris@16 159
Chris@16 160 BOOST_CHRONO_STATIC
Chris@16 161 FP
Chris@16 162 init_steady_clock(kern_return_t & err)
Chris@16 163 {
Chris@16 164 mach_timebase_info_data_t MachInfo;
Chris@16 165 err = mach_timebase_info(&MachInfo);
Chris@16 166 if ( err != 0 )
Chris@16 167 {
Chris@16 168 return 0;
Chris@16 169 }
Chris@16 170
Chris@16 171 if (MachInfo.numer == MachInfo.denom)
Chris@16 172 {
Chris@16 173 return &chrono_detail::steady_simplified;
Chris@16 174 }
Chris@16 175 return &chrono_detail::steady_full;
Chris@16 176 }
Chris@16 177
Chris@16 178 #if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
Chris@16 179 BOOST_CHRONO_STATIC
Chris@16 180 FP_ec
Chris@16 181 init_steady_clock_ec(kern_return_t & err)
Chris@16 182 {
Chris@16 183 mach_timebase_info_data_t MachInfo;
Chris@16 184 err = mach_timebase_info(&MachInfo);
Chris@16 185 if ( err != 0 )
Chris@16 186 {
Chris@16 187 return 0;
Chris@16 188 }
Chris@16 189
Chris@16 190 if (MachInfo.numer == MachInfo.denom)
Chris@16 191 {
Chris@16 192 return &chrono_detail::steady_simplified_ec;
Chris@16 193 }
Chris@16 194 return &chrono_detail::steady_full_ec;
Chris@16 195 }
Chris@16 196 #endif
Chris@16 197 }
Chris@16 198
Chris@16 199 steady_clock::time_point
Chris@16 200 steady_clock::now() BOOST_NOEXCEPT
Chris@16 201 {
Chris@16 202 static kern_return_t err;
Chris@16 203 static chrono_detail::FP fp = chrono_detail::init_steady_clock(err);
Chris@16 204 if ( err != 0 )
Chris@16 205 {
Chris@16 206 BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
Chris@16 207 }
Chris@16 208 return time_point(duration(fp()));
Chris@16 209 }
Chris@16 210
Chris@16 211 #if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
Chris@16 212 steady_clock::time_point
Chris@16 213 steady_clock::now(system::error_code & ec)
Chris@16 214 {
Chris@16 215 static kern_return_t err;
Chris@16 216 static chrono_detail::FP_ec fp = chrono_detail::init_steady_clock_ec(err);
Chris@16 217 if ( err != 0 )
Chris@16 218 {
Chris@16 219 if (BOOST_CHRONO_IS_THROWS(ec))
Chris@16 220 {
Chris@16 221 boost::throw_exception(
Chris@16 222 system::system_error(
Chris@16 223 err,
Chris@16 224 BOOST_CHRONO_SYSTEM_CATEGORY,
Chris@16 225 "chrono::steady_clock" ));
Chris@16 226 }
Chris@16 227 else
Chris@16 228 {
Chris@16 229 ec.assign( err, BOOST_CHRONO_SYSTEM_CATEGORY );
Chris@16 230 return time_point();
Chris@16 231 }
Chris@16 232 }
Chris@16 233 if (!BOOST_CHRONO_IS_THROWS(ec))
Chris@16 234 {
Chris@16 235 ec.clear();
Chris@16 236 }
Chris@16 237 return time_point(duration(fp(ec)));
Chris@16 238 }
Chris@16 239 #endif
Chris@16 240 } // namespace chrono
Chris@16 241 } // namespace boost