Chris@16: // win/chrono.cpp --------------------------------------------------------------// Chris@16: Chris@16: // Copyright Beman Dawes 2008 Chris@16: // Copyright 2009-2010 Vicente J. Botet Escriba Chris@16: Chris@16: // Distributed under the Boost Software License, Version 1.0. Chris@16: // See http://www.boost.org/LICENSE_1_0.txt Chris@16: Chris@16: //----------------------------------------------------------------------------// Chris@16: // Windows // Chris@16: //----------------------------------------------------------------------------// Chris@16: #ifndef BOOST_CHRONO_DETAIL_INLINED_WIN_CHRONO_HPP Chris@16: #define BOOST_CHRONO_DETAIL_INLINED_WIN_CHRONO_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost Chris@16: { Chris@16: namespace chrono Chris@16: { Chris@16: namespace chrono_detail Chris@16: { Chris@16: Chris@16: BOOST_CHRONO_INLINE double get_nanosecs_per_tic() BOOST_NOEXCEPT Chris@16: { Chris@16: boost::detail::winapi::LARGE_INTEGER_ freq; Chris@16: if ( !boost::detail::winapi::QueryPerformanceFrequency( &freq ) ) Chris@16: return 0.0L; Chris@16: return double(1000000000.0L / freq.QuadPart); Chris@16: } Chris@16: Chris@16: } Chris@16: Chris@16: steady_clock::time_point steady_clock::now() BOOST_NOEXCEPT Chris@16: { Chris@101: double nanosecs_per_tic = chrono_detail::get_nanosecs_per_tic(); Chris@16: Chris@16: boost::detail::winapi::LARGE_INTEGER_ pcount; Chris@101: if ( nanosecs_per_tic <= 0.0L ) Chris@16: { Chris@101: BOOST_ASSERT(0 && "Boost::Chrono - get_nanosecs_per_tic Internal Error"); Chris@16: return steady_clock::time_point(); Chris@16: } Chris@101: unsigned times=0; Chris@101: while ( ! boost::detail::winapi::QueryPerformanceCounter( &pcount ) ) Chris@101: { Chris@101: if ( ++times > 3 ) Chris@101: { Chris@101: BOOST_ASSERT(0 && "Boost::Chrono - QueryPerformanceCounter Internal Error"); Chris@101: return steady_clock::time_point(); Chris@101: } Chris@101: } Chris@16: Chris@16: return steady_clock::time_point(steady_clock::duration( Chris@16: static_cast((nanosecs_per_tic) * pcount.QuadPart))); Chris@16: } Chris@16: Chris@16: Chris@16: #if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING Chris@16: steady_clock::time_point steady_clock::now( system::error_code & ec ) Chris@16: { Chris@101: double nanosecs_per_tic = chrono_detail::get_nanosecs_per_tic(); Chris@16: Chris@16: boost::detail::winapi::LARGE_INTEGER_ pcount; Chris@16: if ( (nanosecs_per_tic <= 0.0L) Chris@16: || (!boost::detail::winapi::QueryPerformanceCounter( &pcount )) ) Chris@16: { Chris@16: boost::detail::winapi::DWORD_ cause = Chris@16: ((nanosecs_per_tic <= 0.0L) Chris@16: ? ERROR_NOT_SUPPORTED Chris@16: : boost::detail::winapi::GetLastError()); Chris@16: if (BOOST_CHRONO_IS_THROWS(ec)) { Chris@16: boost::throw_exception( Chris@16: system::system_error( Chris@16: cause, Chris@16: BOOST_CHRONO_SYSTEM_CATEGORY, Chris@16: "chrono::steady_clock" )); Chris@16: } Chris@16: else Chris@16: { Chris@16: ec.assign( cause, BOOST_CHRONO_SYSTEM_CATEGORY ); Chris@16: return steady_clock::time_point(duration(0)); Chris@16: } Chris@16: } Chris@16: Chris@16: if (!BOOST_CHRONO_IS_THROWS(ec)) Chris@16: { Chris@16: ec.clear(); Chris@16: } Chris@16: return time_point(duration( Chris@16: static_cast(nanosecs_per_tic * pcount.QuadPart))); Chris@16: } Chris@16: #endif Chris@16: Chris@16: BOOST_CHRONO_INLINE Chris@16: system_clock::time_point system_clock::now() BOOST_NOEXCEPT Chris@16: { Chris@16: boost::detail::winapi::FILETIME_ ft; Chris@16: boost::detail::winapi::GetSystemTimeAsFileTime( &ft ); // never fails Chris@16: return system_clock::time_point( Chris@16: system_clock::duration( Chris@16: ((static_cast<__int64>( ft.dwHighDateTime ) << 32) | ft.dwLowDateTime) Chris@101: - 116444736000000000LL Chris@101: //- (134775LL*864000000000LL) Chris@16: ) Chris@16: ); Chris@16: } Chris@16: Chris@16: #if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING Chris@16: BOOST_CHRONO_INLINE Chris@16: system_clock::time_point system_clock::now( system::error_code & ec ) Chris@16: { Chris@16: boost::detail::winapi::FILETIME_ ft; Chris@16: boost::detail::winapi::GetSystemTimeAsFileTime( &ft ); // never fails Chris@16: if (!BOOST_CHRONO_IS_THROWS(ec)) Chris@16: { Chris@16: ec.clear(); Chris@16: } Chris@16: return system_clock::time_point( Chris@16: system_clock::duration( Chris@16: ((static_cast<__int64>( ft.dwHighDateTime ) << 32) | ft.dwLowDateTime) Chris@101: - 116444736000000000LL Chris@101: //- (134775LL*864000000000LL) Chris@16: )); Chris@16: } Chris@16: #endif Chris@16: Chris@16: BOOST_CHRONO_INLINE Chris@16: std::time_t system_clock::to_time_t(const system_clock::time_point& t) BOOST_NOEXCEPT Chris@16: { Chris@16: __int64 temp = t.time_since_epoch().count(); Chris@16: temp /= 10000000; Chris@16: return static_cast( temp ); Chris@16: } Chris@16: Chris@16: BOOST_CHRONO_INLINE Chris@16: system_clock::time_point system_clock::from_time_t(std::time_t t) BOOST_NOEXCEPT Chris@16: { Chris@16: __int64 temp = t; Chris@16: temp *= 10000000; Chris@16: return time_point(duration(temp)); Chris@16: } Chris@16: Chris@16: } // namespace chrono Chris@16: } // namespace boost Chris@16: Chris@16: #endif