1 // posix/chrono.cpp --------------------------------------------------------------// 2 3 // Copyright Beman Dawes 2008 4 // Copyright Vicente J. Botet Escriba 2009 5 6 // Distributed under the Boost Software License, Version 1.0. 7 // See http://www.boost.org/LICENSE_1_0.txt 8 9 //----------------------------------------------------------------------------// 10 // POSIX // 11 //----------------------------------------------------------------------------// 12 13 #include <time.h> // for clock_gettime 14 #include <boost/assert.hpp> 15 #include <boost/predef/os.h> 16 17 namespace boost 18 { 19 namespace chrono 20 { 21 now()22 system_clock::time_point system_clock::now() BOOST_NOEXCEPT 23 { 24 timespec ts; 25 if ( ::clock_gettime( CLOCK_REALTIME, &ts ) ) 26 { 27 BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); 28 } 29 30 return time_point(duration( 31 static_cast<system_clock::rep>( ts.tv_sec ) * 1000000000 + ts.tv_nsec)); 32 } 33 34 #if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING now(system::error_code & ec)35 system_clock::time_point system_clock::now(system::error_code & ec) 36 { 37 timespec ts; 38 if ( ::clock_gettime( CLOCK_REALTIME, &ts ) ) 39 { 40 if (::boost::chrono::is_throws(ec)) 41 { 42 boost::throw_exception( 43 system::system_error( 44 errno, 45 ::boost::system::system_category(), 46 "chrono::system_clock" )); 47 } 48 else 49 { 50 ec.assign( errno, ::boost::system::system_category() ); 51 return time_point(); 52 } 53 } 54 55 if (!::boost::chrono::is_throws(ec)) 56 { 57 ec.clear(); 58 } 59 return time_point(duration( 60 static_cast<system_clock::rep>( ts.tv_sec ) * 1000000000 + ts.tv_nsec)); 61 } 62 #endif 63 to_time_t(const system_clock::time_point & t)64 std::time_t system_clock::to_time_t(const system_clock::time_point& t) BOOST_NOEXCEPT 65 { 66 return static_cast<std::time_t>( t.time_since_epoch().count() / 1000000000 ); 67 } 68 from_time_t(std::time_t t)69 system_clock::time_point system_clock::from_time_t(std::time_t t) BOOST_NOEXCEPT 70 { 71 return time_point(duration(static_cast<system_clock::rep>(t) * 1000000000)); 72 } 73 74 #ifdef BOOST_CHRONO_HAS_CLOCK_STEADY 75 now()76 steady_clock::time_point steady_clock::now() BOOST_NOEXCEPT 77 { 78 timespec ts; 79 #if BOOST_OS_CYGWIN 80 // lack of thread safety in high resolution timer initialization 81 // can lead to a timespec of zero without an error; was reported 82 // to the cygwin mailing list and can be removed once fixed 83 do 84 { 85 #endif 86 if ( ::clock_gettime( CLOCK_MONOTONIC, &ts ) ) 87 { 88 BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); 89 } 90 #if BOOST_OS_CYGWIN 91 } while (ts.tv_sec == 0 && ts.tv_nsec == 0); 92 #endif 93 return time_point(duration( 94 static_cast<steady_clock::rep>( ts.tv_sec ) * 1000000000 + ts.tv_nsec)); 95 } 96 97 #if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING now(system::error_code & ec)98 steady_clock::time_point steady_clock::now(system::error_code & ec) 99 { 100 timespec ts; 101 #if BOOST_OS_CYGWIN 102 // lack of thread safety in high resolution timer initialization 103 // can lead to a timespec of zero without an error; was reported 104 // to the cygwin mailing list and can be removed once fixed 105 do 106 { 107 #endif 108 if ( ::clock_gettime( CLOCK_MONOTONIC, &ts ) ) 109 { 110 if (::boost::chrono::is_throws(ec)) 111 { 112 boost::throw_exception( 113 system::system_error( 114 errno, 115 ::boost::system::system_category(), 116 "chrono::steady_clock" )); 117 } 118 else 119 { 120 ec.assign( errno, ::boost::system::system_category() ); 121 return time_point(); 122 } 123 } 124 #if BOOST_OS_CYGWIN 125 } while (ts.tv_sec == 0 && ts.tv_nsec == 0); 126 #endif 127 128 if (!::boost::chrono::is_throws(ec)) 129 { 130 ec.clear(); 131 } 132 return time_point(duration( 133 static_cast<steady_clock::rep>( ts.tv_sec ) * 1000000000 + ts.tv_nsec)); 134 } 135 #endif 136 #endif 137 138 } // namespace chrono 139 } // namespace boost 140 141 142