Warning, file /include/boost/thread/detail/platform_time.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 #ifndef BOOST_THREAD_DETAIL_PLATFORM_TIME_HPP
0002 #define BOOST_THREAD_DETAIL_PLATFORM_TIME_HPP
0003
0004
0005
0006
0007
0008
0009
0010 #include <boost/thread/detail/config.hpp>
0011 #include <boost/thread/thread_time.hpp>
0012 #if defined BOOST_THREAD_USES_DATETIME
0013 #include <boost/date_time/posix_time/conversion.hpp>
0014 #endif
0015 #ifndef _WIN32
0016 #include <unistd.h>
0017 #endif
0018 #ifdef BOOST_THREAD_USES_CHRONO
0019 #include <boost/chrono/duration.hpp>
0020 #include <boost/chrono/system_clocks.hpp>
0021 #include <boost/chrono/ceil.hpp>
0022 #endif
0023
0024 #if defined(BOOST_THREAD_CHRONO_WINDOWS_API)
0025 #include <boost/winapi/time.hpp>
0026 #include <boost/winapi/timers.hpp>
0027 #include <boost/thread/win32/thread_primitives.hpp>
0028 #elif defined(BOOST_THREAD_CHRONO_MAC_API)
0029 #include <sys/time.h> //for gettimeofday and timeval
0030 #include <mach/mach_time.h> // mach_absolute_time, mach_timebase_info_data_t
0031
0032 #else
0033 #include <time.h> // for clock_gettime
0034 #endif
0035
0036 #include <limits>
0037
0038 #include <boost/config/abi_prefix.hpp>
0039
0040 namespace boost
0041 {
0042
0043 typedef boost::intmax_t time_max_t;
0044
0045 #if defined BOOST_THREAD_CHRONO_MAC_API
0046 namespace threads
0047 {
0048
0049 namespace chrono_details
0050 {
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064 inline time_max_t
0065 steady_simplified()
0066 {
0067 return mach_absolute_time();
0068 }
0069
0070 inline double compute_steady_factor(kern_return_t& err)
0071 {
0072 mach_timebase_info_data_t MachInfo;
0073 err = mach_timebase_info(&MachInfo);
0074 if ( err != 0 ) {
0075 return 0;
0076 }
0077 return static_cast<double>(MachInfo.numer) / MachInfo.denom;
0078 }
0079
0080 inline time_max_t steady_full()
0081 {
0082 kern_return_t err;
0083 const double factor = chrono_details::compute_steady_factor(err);
0084 if (err != 0)
0085 {
0086 BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
0087 }
0088 return static_cast<time_max_t>(mach_absolute_time() * factor);
0089 }
0090
0091
0092 typedef time_max_t (*FP)();
0093
0094 inline FP init_steady_clock(kern_return_t & err)
0095 {
0096 mach_timebase_info_data_t MachInfo;
0097 err = mach_timebase_info(&MachInfo);
0098 if ( err != 0 )
0099 {
0100 return 0;
0101 }
0102
0103 if (MachInfo.numer == MachInfo.denom)
0104 {
0105 return &chrono_details::steady_simplified;
0106 }
0107 return &chrono_details::steady_full;
0108 }
0109
0110 }
0111 }
0112 #endif
0113
0114 namespace detail
0115 {
0116 #if defined BOOST_THREAD_CHRONO_POSIX_API || defined BOOST_THREAD_CHRONO_MAC_API
0117 inline timespec ns_to_timespec(boost::time_max_t const& ns)
0118 {
0119 boost::time_max_t s = ns / 1000000000l;
0120 timespec ts;
0121 ts.tv_sec = static_cast<long> (s);
0122 ts.tv_nsec = static_cast<long> (ns - s * 1000000000l);
0123 return ts;
0124 }
0125 inline boost::time_max_t timespec_to_ns(timespec const& ts)
0126 {
0127 return static_cast<boost::time_max_t>(ts.tv_sec) * 1000000000l + ts.tv_nsec;
0128 }
0129 #endif
0130
0131 struct platform_duration
0132 {
0133 #if defined BOOST_THREAD_CHRONO_POSIX_API || defined BOOST_THREAD_CHRONO_MAC_API
0134 explicit platform_duration(timespec const& v) : ts_val(v) {}
0135 timespec const& getTs() const { return ts_val; }
0136
0137 explicit platform_duration(boost::time_max_t const& ns = 0) : ts_val(ns_to_timespec(ns)) {}
0138 boost::time_max_t getNs() const { return timespec_to_ns(ts_val); }
0139 #else
0140 explicit platform_duration(boost::time_max_t const& ns = 0) : ns_val(ns) {}
0141 boost::time_max_t getNs() const { return ns_val; }
0142 #endif
0143
0144 #if defined BOOST_THREAD_USES_DATETIME
0145 platform_duration(boost::posix_time::time_duration const& rel_time)
0146 {
0147 #if defined BOOST_THREAD_CHRONO_POSIX_API || defined BOOST_THREAD_CHRONO_MAC_API
0148 ts_val.tv_sec = rel_time.total_seconds();
0149 ts_val.tv_nsec = static_cast<long>(rel_time.fractional_seconds() * (1000000000l / rel_time.ticks_per_second()));
0150 #else
0151 ns_val = static_cast<boost::time_max_t>(rel_time.total_seconds()) * 1000000000l;
0152 ns_val += rel_time.fractional_seconds() * (1000000000l / rel_time.ticks_per_second());
0153 #endif
0154 }
0155 #endif
0156
0157 #if defined BOOST_THREAD_USES_CHRONO
0158 template <class Rep, class Period>
0159 platform_duration(chrono::duration<Rep, Period> const& d)
0160 {
0161 #if defined BOOST_THREAD_CHRONO_POSIX_API || defined BOOST_THREAD_CHRONO_MAC_API
0162 ts_val = ns_to_timespec(chrono::ceil<chrono::nanoseconds>(d).count());
0163 #else
0164 ns_val = chrono::ceil<chrono::nanoseconds>(d).count();
0165 #endif
0166 }
0167 #endif
0168
0169 boost::time_max_t getMs() const
0170 {
0171 const boost::time_max_t ns = getNs();
0172
0173 if (ns >= 0)
0174 {
0175
0176 return (ns + 999999) / 1000000;
0177 }
0178 else
0179 {
0180
0181 return (ns - 999999) / 1000000;
0182 }
0183 }
0184
0185 static platform_duration zero()
0186 {
0187 return platform_duration(0);
0188 }
0189
0190 private:
0191 #if defined BOOST_THREAD_CHRONO_POSIX_API || defined BOOST_THREAD_CHRONO_MAC_API
0192 timespec ts_val;
0193 #else
0194 boost::time_max_t ns_val;
0195 #endif
0196 };
0197
0198 inline bool operator==(platform_duration const& lhs, platform_duration const& rhs)
0199 {
0200 return lhs.getNs() == rhs.getNs();
0201 }
0202 inline bool operator!=(platform_duration const& lhs, platform_duration const& rhs)
0203 {
0204 return lhs.getNs() != rhs.getNs();
0205 }
0206 inline bool operator<(platform_duration const& lhs, platform_duration const& rhs)
0207 {
0208 return lhs.getNs() < rhs.getNs();
0209 }
0210 inline bool operator<=(platform_duration const& lhs, platform_duration const& rhs)
0211 {
0212 return lhs.getNs() <= rhs.getNs();
0213 }
0214 inline bool operator>(platform_duration const& lhs, platform_duration const& rhs)
0215 {
0216 return lhs.getNs() > rhs.getNs();
0217 }
0218 inline bool operator>=(platform_duration const& lhs, platform_duration const& rhs)
0219 {
0220 return lhs.getNs() >= rhs.getNs();
0221 }
0222
0223 static inline platform_duration platform_milliseconds(long const& ms)
0224 {
0225 return platform_duration(ms * 1000000l);
0226 }
0227
0228 struct real_platform_timepoint
0229 {
0230 #if defined BOOST_THREAD_CHRONO_POSIX_API || defined BOOST_THREAD_CHRONO_MAC_API
0231 explicit real_platform_timepoint(timespec const& v) : dur(v) {}
0232 timespec const& getTs() const { return dur.getTs(); }
0233 #endif
0234
0235 explicit real_platform_timepoint(boost::time_max_t const& ns) : dur(ns) {}
0236 boost::time_max_t getNs() const { return dur.getNs(); }
0237
0238 #if defined BOOST_THREAD_USES_DATETIME
0239 real_platform_timepoint(boost::system_time const& abs_time)
0240 : dur(abs_time - boost::posix_time::from_time_t(0)) {}
0241 #endif
0242
0243 #if defined BOOST_THREAD_USES_CHRONO
0244 template <class Duration>
0245 real_platform_timepoint(chrono::time_point<chrono::system_clock, Duration> const& abs_time)
0246 : dur(abs_time.time_since_epoch()) {}
0247 #endif
0248
0249 private:
0250 platform_duration dur;
0251 };
0252
0253 inline bool operator==(real_platform_timepoint const& lhs, real_platform_timepoint const& rhs)
0254 {
0255 return lhs.getNs() == rhs.getNs();
0256 }
0257 inline bool operator!=(real_platform_timepoint const& lhs, real_platform_timepoint const& rhs)
0258 {
0259 return lhs.getNs() != rhs.getNs();
0260 }
0261 inline bool operator<(real_platform_timepoint const& lhs, real_platform_timepoint const& rhs)
0262 {
0263 return lhs.getNs() < rhs.getNs();
0264 }
0265 inline bool operator<=(real_platform_timepoint const& lhs, real_platform_timepoint const& rhs)
0266 {
0267 return lhs.getNs() <= rhs.getNs();
0268 }
0269 inline bool operator>(real_platform_timepoint const& lhs, real_platform_timepoint const& rhs)
0270 {
0271 return lhs.getNs() > rhs.getNs();
0272 }
0273 inline bool operator>=(real_platform_timepoint const& lhs, real_platform_timepoint const& rhs)
0274 {
0275 return lhs.getNs() >= rhs.getNs();
0276 }
0277
0278 inline real_platform_timepoint operator+(real_platform_timepoint const& lhs, platform_duration const& rhs)
0279 {
0280 return real_platform_timepoint(lhs.getNs() + rhs.getNs());
0281 }
0282 inline real_platform_timepoint operator+(platform_duration const& lhs, real_platform_timepoint const& rhs)
0283 {
0284 return real_platform_timepoint(lhs.getNs() + rhs.getNs());
0285 }
0286 inline platform_duration operator-(real_platform_timepoint const& lhs, real_platform_timepoint const& rhs)
0287 {
0288 return platform_duration(lhs.getNs() - rhs.getNs());
0289 }
0290
0291 struct real_platform_clock
0292 {
0293 static real_platform_timepoint now()
0294 {
0295 #if defined(BOOST_THREAD_CHRONO_WINDOWS_API)
0296 boost::winapi::FILETIME_ ft;
0297 boost::winapi::GetSystemTimeAsFileTime(&ft);
0298 boost::time_max_t ns = ((((static_cast<boost::time_max_t>(ft.dwHighDateTime) << 32) | ft.dwLowDateTime) - 116444736000000000LL) * 100LL);
0299 return real_platform_timepoint(ns);
0300 #elif defined(BOOST_THREAD_CHRONO_MAC_API)
0301 timeval tv;
0302 ::gettimeofday(&tv, 0);
0303 timespec ts;
0304 ts.tv_sec = tv.tv_sec;
0305 ts.tv_nsec = tv.tv_usec * 1000;
0306 return real_platform_timepoint(ts);
0307 #else
0308 timespec ts;
0309 if ( ::clock_gettime( CLOCK_REALTIME, &ts ) )
0310 {
0311 BOOST_ASSERT(0 && "Boost::Thread - clock_gettime(CLOCK_REALTIME) Internal Error");
0312 return real_platform_timepoint(0);
0313 }
0314 return real_platform_timepoint(ts);
0315 #endif
0316 }
0317 };
0318
0319 #if defined(BOOST_THREAD_HAS_MONO_CLOCK)
0320
0321 struct mono_platform_timepoint
0322 {
0323 #if defined BOOST_THREAD_CHRONO_POSIX_API || defined BOOST_THREAD_CHRONO_MAC_API
0324
0325 explicit mono_platform_timepoint(timespec const& v) : dur(v) {}
0326 timespec const& getTs() const { return dur.getTs(); }
0327 #endif
0328
0329 explicit mono_platform_timepoint(boost::time_max_t const& ns) : dur(ns) {}
0330 boost::time_max_t getNs() const { return dur.getNs(); }
0331
0332 #if defined BOOST_THREAD_USES_CHRONO
0333
0334 template <class Duration>
0335 mono_platform_timepoint(chrono::time_point<chrono::steady_clock, Duration> const& abs_time)
0336 : dur(abs_time.time_since_epoch()) {}
0337 #endif
0338
0339
0340 static mono_platform_timepoint getMax()
0341 {
0342 #if defined BOOST_THREAD_CHRONO_POSIX_API || defined BOOST_THREAD_CHRONO_MAC_API
0343 timespec ts;
0344 ts.tv_sec = (std::numeric_limits<time_t>::max)();
0345 ts.tv_nsec = 999999999;
0346 return mono_platform_timepoint(ts);
0347 #else
0348 boost::time_max_t ns = (std::numeric_limits<boost::time_max_t>::max)();
0349 return mono_platform_timepoint(ns);
0350 #endif
0351 }
0352
0353 private:
0354 platform_duration dur;
0355 };
0356
0357 inline bool operator==(mono_platform_timepoint const& lhs, mono_platform_timepoint const& rhs)
0358 {
0359 return lhs.getNs() == rhs.getNs();
0360 }
0361 inline bool operator!=(mono_platform_timepoint const& lhs, mono_platform_timepoint const& rhs)
0362 {
0363 return lhs.getNs() != rhs.getNs();
0364 }
0365 inline bool operator<(mono_platform_timepoint const& lhs, mono_platform_timepoint const& rhs)
0366 {
0367 return lhs.getNs() < rhs.getNs();
0368 }
0369 inline bool operator<=(mono_platform_timepoint const& lhs, mono_platform_timepoint const& rhs)
0370 {
0371 return lhs.getNs() <= rhs.getNs();
0372 }
0373 inline bool operator>(mono_platform_timepoint const& lhs, mono_platform_timepoint const& rhs)
0374 {
0375 return lhs.getNs() > rhs.getNs();
0376 }
0377 inline bool operator>=(mono_platform_timepoint const& lhs, mono_platform_timepoint const& rhs)
0378 {
0379 return lhs.getNs() >= rhs.getNs();
0380 }
0381
0382 inline mono_platform_timepoint operator+(mono_platform_timepoint const& lhs, platform_duration const& rhs)
0383 {
0384 return mono_platform_timepoint(lhs.getNs() + rhs.getNs());
0385 }
0386 inline mono_platform_timepoint operator+(platform_duration const& lhs, mono_platform_timepoint const& rhs)
0387 {
0388 return mono_platform_timepoint(lhs.getNs() + rhs.getNs());
0389 }
0390 inline platform_duration operator-(mono_platform_timepoint const& lhs, mono_platform_timepoint const& rhs)
0391 {
0392 return platform_duration(lhs.getNs() - rhs.getNs());
0393 }
0394
0395 struct mono_platform_clock
0396 {
0397 static mono_platform_timepoint now()
0398 {
0399 #if defined(BOOST_THREAD_CHRONO_WINDOWS_API)
0400 #if defined(BOOST_THREAD_USES_CHRONO)
0401
0402
0403
0404 boost::winapi::LARGE_INTEGER_ freq;
0405 if ( !boost::winapi::QueryPerformanceFrequency( &freq ) )
0406 {
0407 BOOST_ASSERT(0 && "Boost::Thread - QueryPerformanceFrequency Internal Error");
0408 return mono_platform_timepoint(0);
0409 }
0410 if ( freq.QuadPart <= 0 )
0411 {
0412 BOOST_ASSERT(0 && "Boost::Thread - QueryPerformanceFrequency Internal Error");
0413 return mono_platform_timepoint(0);
0414 }
0415
0416 boost::winapi::LARGE_INTEGER_ pcount;
0417 unsigned times=0;
0418 while ( ! boost::winapi::QueryPerformanceCounter( &pcount ) )
0419 {
0420 if ( ++times > 3 )
0421 {
0422 BOOST_ASSERT(0 && "Boost::Thread - QueryPerformanceCounter Internal Error");
0423 return mono_platform_timepoint(0);
0424 }
0425 }
0426
0427 long double ns = 1000000000.0L * pcount.QuadPart / freq.QuadPart;
0428 return mono_platform_timepoint(static_cast<boost::time_max_t>(ns));
0429 #else
0430
0431
0432 win32::ticks_type msec = win32::gettickcount64();
0433 return mono_platform_timepoint(msec * 1000000);
0434 #endif
0435 #elif defined(BOOST_THREAD_CHRONO_MAC_API)
0436 kern_return_t err;
0437 threads::chrono_details::FP fp = threads::chrono_details::init_steady_clock(err);
0438 if ( err != 0 )
0439 {
0440 BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
0441 }
0442 return mono_platform_timepoint(fp());
0443 #else
0444 timespec ts;
0445 if ( ::clock_gettime( CLOCK_MONOTONIC, &ts ) )
0446 {
0447 BOOST_ASSERT(0 && "Boost::Thread - clock_gettime(CLOCK_MONOTONIC) Internal Error");
0448 return mono_platform_timepoint(0);
0449 }
0450 return mono_platform_timepoint(ts);
0451 #endif
0452 }
0453 };
0454
0455 #endif
0456
0457 #if defined(BOOST_THREAD_INTERNAL_CLOCK_IS_MONO)
0458 typedef mono_platform_clock internal_platform_clock;
0459 typedef mono_platform_timepoint internal_platform_timepoint;
0460 #else
0461 typedef real_platform_clock internal_platform_clock;
0462 typedef real_platform_timepoint internal_platform_timepoint;
0463 #endif
0464
0465 #ifdef BOOST_THREAD_USES_CHRONO
0466 #ifdef BOOST_THREAD_INTERNAL_CLOCK_IS_MONO
0467 typedef chrono::steady_clock internal_chrono_clock;
0468 #else
0469 typedef chrono::system_clock internal_chrono_clock;
0470 #endif
0471 #endif
0472
0473 }
0474 }
0475
0476 #include <boost/config/abi_suffix.hpp>
0477
0478 #endif