355 lines
		
	
	
		
			9.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			355 lines
		
	
	
		
			9.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | //  boost process_cpu_clocks.cpp  -----------------------------------------------------------// | ||
|  | 
 | ||
|  | //  Copyright Beman Dawes 1994, 2006, 2008 | ||
|  | //  Copyright Vicente J. Botet Escriba 2009 | ||
|  | 
 | ||
|  | //  Distributed under the Boost Software License, Version 1.0. | ||
|  | //  See http://www.boost.org/LICENSE_1_0.txt | ||
|  | 
 | ||
|  | //  See http://www.boost.org/libs/chrono for documentation. | ||
|  | 
 | ||
|  | //--------------------------------------------------------------------------------------// | ||
|  | 
 | ||
|  | #include <boost/chrono/config.hpp> | ||
|  | #include <boost/chrono/process_cpu_clocks.hpp> | ||
|  | #include <boost/assert.hpp> | ||
|  | 
 | ||
|  | #include <sys/times.h> | ||
|  | #include <unistd.h> | ||
|  | #include <time.h>  // for clock_gettime | ||
|  | 
 | ||
|  | 
 | ||
|  | namespace boost { namespace chrono { | ||
|  | namespace chrono_detail | ||
|  | { | ||
|  |   inline nanoseconds::rep tick_factor()        // multiplier to convert ticks | ||
|  |                             //  to nanoseconds; -1 if unknown | ||
|  |   { | ||
|  |     long factor = 0; | ||
|  |     if ( !factor ) | ||
|  |     { | ||
|  |       if ( (factor = ::sysconf( _SC_CLK_TCK )) <= 0 ) | ||
|  |         factor = -1; | ||
|  |       else | ||
|  |       { | ||
|  |         BOOST_ASSERT( factor <= 1000000000l ); // doesn't handle large ticks | ||
|  |         factor = 1000000000l / factor;  // compute factor | ||
|  |         if ( !factor ) factor = -1; | ||
|  |       } | ||
|  |     } | ||
|  |     return factor; | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | process_real_cpu_clock::time_point process_real_cpu_clock::now() BOOST_NOEXCEPT | ||
|  | { | ||
|  |     tms tm; | ||
|  |     clock_t c = ::times( &tm ); | ||
|  |     if ( c == clock_t(-1) ) // error | ||
|  |     { | ||
|  |       BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); | ||
|  |     } | ||
|  |     else | ||
|  |     { | ||
|  |         if ( chrono_detail::tick_factor() != -1 ) | ||
|  |         { | ||
|  |             return time_point( | ||
|  |                     nanoseconds(c*chrono_detail::tick_factor())); | ||
|  |         } | ||
|  |         else | ||
|  |         { | ||
|  |           BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); | ||
|  |         } | ||
|  |     } | ||
|  |     return time_point(); | ||
|  | } | ||
|  | 
 | ||
|  | #if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING | ||
|  | process_real_cpu_clock::time_point process_real_cpu_clock::now( | ||
|  |         system::error_code & ec) | ||
|  | { | ||
|  | 
 | ||
|  |     tms tm; | ||
|  |     clock_t c = ::times( &tm ); | ||
|  |     if ( c == clock_t(-1) ) // error | ||
|  |     { | ||
|  |         if (BOOST_CHRONO_IS_THROWS(ec)) | ||
|  |         { | ||
|  |             boost::throw_exception( | ||
|  |                     system::system_error( | ||
|  |                             errno, | ||
|  |                             BOOST_CHRONO_SYSTEM_CATEGORY, | ||
|  |                             "chrono::process_real_cpu_clock" )); | ||
|  |         } | ||
|  |         else | ||
|  |         { | ||
|  |             ec.assign( errno, BOOST_CHRONO_SYSTEM_CATEGORY ); | ||
|  |             return time_point(); | ||
|  |         } | ||
|  |     } | ||
|  |     else | ||
|  |     { | ||
|  |         if ( chrono_detail::tick_factor() != -1 ) | ||
|  |         { | ||
|  |             if (!BOOST_CHRONO_IS_THROWS(ec)) | ||
|  |             { | ||
|  |                 ec.clear(); | ||
|  |             } | ||
|  |             return time_point( | ||
|  |                 nanoseconds(c*chrono_detail::tick_factor())); | ||
|  |         } | ||
|  |         else | ||
|  |         { | ||
|  |             if (BOOST_CHRONO_IS_THROWS(ec)) | ||
|  |             { | ||
|  |                 boost::throw_exception( | ||
|  |                         system::system_error( | ||
|  |                                 errno, | ||
|  |                                 BOOST_CHRONO_SYSTEM_CATEGORY, | ||
|  |                                 "chrono::process_real_cpu_clock" )); | ||
|  |             } | ||
|  |             else | ||
|  |             { | ||
|  |                 ec.assign( errno, BOOST_CHRONO_SYSTEM_CATEGORY ); | ||
|  |                 return time_point(); | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  | } | ||
|  | #endif | ||
|  | 
 | ||
|  | process_user_cpu_clock::time_point process_user_cpu_clock::now() BOOST_NOEXCEPT | ||
|  | { | ||
|  |     tms tm; | ||
|  |     clock_t c = ::times( &tm ); | ||
|  |     if ( c == clock_t(-1) ) // error | ||
|  |     { | ||
|  |           BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); | ||
|  |     } | ||
|  |     else | ||
|  |     { | ||
|  |         if ( chrono_detail::tick_factor() != -1 ) | ||
|  |         { | ||
|  |             return time_point( | ||
|  |                 nanoseconds((tm.tms_utime + tm.tms_cutime)*chrono_detail::tick_factor())); | ||
|  |         } | ||
|  |         else | ||
|  |         { | ||
|  |           BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); | ||
|  |         } | ||
|  |     } | ||
|  |     return time_point(); | ||
|  | } | ||
|  | 
 | ||
|  | #if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING | ||
|  | process_user_cpu_clock::time_point process_user_cpu_clock::now( | ||
|  |         system::error_code & ec) | ||
|  | { | ||
|  |     tms tm; | ||
|  |     clock_t c = ::times( &tm ); | ||
|  |     if ( c == clock_t(-1) ) // error | ||
|  |     { | ||
|  |         if (BOOST_CHRONO_IS_THROWS(ec)) | ||
|  |         { | ||
|  |             boost::throw_exception( | ||
|  |                     system::system_error( | ||
|  |                             errno, | ||
|  |                             BOOST_CHRONO_SYSTEM_CATEGORY, | ||
|  |                             "chrono::process_user_cpu_clock" )); | ||
|  |         } | ||
|  |         else | ||
|  |         { | ||
|  |             ec.assign( errno, BOOST_CHRONO_SYSTEM_CATEGORY ); | ||
|  |             return time_point(); | ||
|  |         } | ||
|  |     } | ||
|  |     else | ||
|  |     { | ||
|  |         if ( chrono_detail::tick_factor() != -1 ) | ||
|  |         { | ||
|  |             if (!BOOST_CHRONO_IS_THROWS(ec)) | ||
|  |             { | ||
|  |                 ec.clear(); | ||
|  |             } | ||
|  |             return time_point( | ||
|  |                 nanoseconds((tm.tms_utime + tm.tms_cutime)*chrono_detail::tick_factor())); | ||
|  |         } | ||
|  |         else | ||
|  |         { | ||
|  |             if (BOOST_CHRONO_IS_THROWS(ec)) | ||
|  |             { | ||
|  |                 boost::throw_exception( | ||
|  |                         system::system_error( | ||
|  |                                 errno, | ||
|  |                                 BOOST_CHRONO_SYSTEM_CATEGORY, | ||
|  |                                 "chrono::process_user_cpu_clock" )); | ||
|  |             } | ||
|  |             else | ||
|  |             { | ||
|  |                 ec.assign( errno, BOOST_CHRONO_SYSTEM_CATEGORY ); | ||
|  |                 return time_point(); | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  | } | ||
|  | #endif | ||
|  | 
 | ||
|  | process_system_cpu_clock::time_point process_system_cpu_clock::now() BOOST_NOEXCEPT | ||
|  | { | ||
|  |     tms tm; | ||
|  |     clock_t c = ::times( &tm ); | ||
|  |     if ( c == clock_t(-1) ) // error | ||
|  |     { | ||
|  |       BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); | ||
|  |       return time_point(); | ||
|  |     } | ||
|  |     else | ||
|  |     { | ||
|  |         if ( chrono_detail::tick_factor() != -1 ) | ||
|  |         { | ||
|  |             return time_point( | ||
|  |                 nanoseconds((tm.tms_stime + tm.tms_cstime)*chrono_detail::tick_factor())); | ||
|  |         } | ||
|  |         else | ||
|  |         { | ||
|  |           BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); | ||
|  |           return time_point(); | ||
|  |         } | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | #if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING | ||
|  | process_system_cpu_clock::time_point process_system_cpu_clock::now( | ||
|  |         system::error_code & ec) | ||
|  | { | ||
|  |     tms tm; | ||
|  |     clock_t c = ::times( &tm ); | ||
|  |     if ( c == clock_t(-1) ) // error | ||
|  |     { | ||
|  |         if (BOOST_CHRONO_IS_THROWS(ec)) | ||
|  |         { | ||
|  |             boost::throw_exception( | ||
|  |                     system::system_error( | ||
|  |                             errno, | ||
|  |                             BOOST_CHRONO_SYSTEM_CATEGORY, | ||
|  |                             "chrono::process_system_cpu_clock" )); | ||
|  |         } | ||
|  |         else | ||
|  |         { | ||
|  |             ec.assign( errno, BOOST_CHRONO_SYSTEM_CATEGORY ); | ||
|  |             return time_point(); | ||
|  |         } | ||
|  |     } | ||
|  |     else | ||
|  |     { | ||
|  |         if ( chrono_detail::tick_factor() != -1 ) | ||
|  |         { | ||
|  |             if (!BOOST_CHRONO_IS_THROWS(ec)) | ||
|  |             { | ||
|  |                 ec.clear(); | ||
|  |             } | ||
|  |             return time_point( | ||
|  |                 nanoseconds((tm.tms_stime + tm.tms_cstime)*chrono_detail::tick_factor())); | ||
|  |         } | ||
|  |         else | ||
|  |         { | ||
|  |             if (BOOST_CHRONO_IS_THROWS(ec)) | ||
|  |             { | ||
|  |                 boost::throw_exception( | ||
|  |                         system::system_error( | ||
|  |                                 errno, | ||
|  |                                 BOOST_CHRONO_SYSTEM_CATEGORY, | ||
|  |                                 "chrono::process_system_cpu_clock" )); | ||
|  |             } | ||
|  |             else | ||
|  |             { | ||
|  |                 ec.assign( errno, BOOST_CHRONO_SYSTEM_CATEGORY ); | ||
|  |                 return time_point(); | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  | } | ||
|  | #endif | ||
|  | 
 | ||
|  | process_cpu_clock::time_point process_cpu_clock::now() BOOST_NOEXCEPT | ||
|  | { | ||
|  |     tms tm; | ||
|  |     clock_t c = ::times( &tm ); | ||
|  |     if ( c == clock_t(-1) ) // error | ||
|  |     { | ||
|  |       BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); | ||
|  |     } | ||
|  |     else | ||
|  |     { | ||
|  |         nanoseconds::rep factor = chrono_detail::tick_factor(); | ||
|  |         if ( factor != -1 ) | ||
|  |         { | ||
|  |             time_point::rep r( | ||
|  |                     c*factor, | ||
|  |                     (tm.tms_utime + tm.tms_cutime)*factor, | ||
|  |                     (tm.tms_stime + tm.tms_cstime)*factor); | ||
|  |             return time_point(duration(r)); | ||
|  |         } | ||
|  |         else | ||
|  |         { | ||
|  |           BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); | ||
|  |         } | ||
|  |     } | ||
|  |     return time_point(); | ||
|  | } | ||
|  | 
 | ||
|  | #if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING | ||
|  | process_cpu_clock::time_point process_cpu_clock::now( | ||
|  |         system::error_code & ec ) | ||
|  | { | ||
|  |     tms tm; | ||
|  |     clock_t c = ::times( &tm ); | ||
|  |     if ( c == clock_t(-1) ) // error | ||
|  |     { | ||
|  |         if (BOOST_CHRONO_IS_THROWS(ec)) | ||
|  |         { | ||
|  |             boost::throw_exception( | ||
|  |                     system::system_error( | ||
|  |                             errno, | ||
|  |                             BOOST_CHRONO_SYSTEM_CATEGORY, | ||
|  |                             "chrono::process_clock" )); | ||
|  |         } | ||
|  |         else | ||
|  |         { | ||
|  |             ec.assign( errno, BOOST_CHRONO_SYSTEM_CATEGORY ); | ||
|  |             return time_point(); | ||
|  |         } | ||
|  |     } | ||
|  |     else | ||
|  |     { | ||
|  |         if ( chrono_detail::tick_factor() != -1 ) | ||
|  |         { | ||
|  |             time_point::rep r( | ||
|  |                 c*chrono_detail::tick_factor(), | ||
|  |                 (tm.tms_utime + tm.tms_cutime)*chrono_detail::tick_factor(), | ||
|  |                 (tm.tms_stime + tm.tms_cstime)*chrono_detail::tick_factor()); | ||
|  |             return time_point(duration(r)); | ||
|  |         } | ||
|  |         else | ||
|  |         { | ||
|  |             if (BOOST_CHRONO_IS_THROWS(ec)) | ||
|  |             { | ||
|  |                 boost::throw_exception( | ||
|  |                         system::system_error( | ||
|  |                                 errno, | ||
|  |                                 BOOST_CHRONO_SYSTEM_CATEGORY, | ||
|  |                                 "chrono::process_clock" )); | ||
|  |             } | ||
|  |             else | ||
|  |             { | ||
|  |                 ec.assign( errno, BOOST_CHRONO_SYSTEM_CATEGORY ); | ||
|  |                 return time_point(); | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  | } | ||
|  | #endif | ||
|  | 
 | ||
|  | } } |