#ifndef BOOST_DATE_TIME_MONOTONIC_TIME_HPP #define BOOST_DATE_TIME_MONOTONIC_TIME_HPP #include #include #include #include #include #ifdef _WIN32 #include #endif namespace ext { template struct microsec_clock { typedef typename time_type::date_type date_type; typedef typename time_type::time_duration_type time_duration_type; typedef typename time_duration_type::rep_type resolution_traits_type; static time_type monotonic_time() { #ifdef _WIN32 struct local { static double nanosec_per_tick() { LARGE_INTEGER freq; // counts/seconds if (0 == QueryPerformanceFrequency(&freq)) { DWORD const errcode = GetLastError(); throw boost::system::system_error(boost::system::error_code(errcode, boost::system::get_system_category()), "QueryPerformanceFrequency()"); } return 1000000000.0 / freq.QuadPart; } }; LARGE_INTEGER cnt; if (0 == QueryPerformanceCounter(&cnt)) { DWORD const errcode = GetLastError(); throw boost::system::system_error(boost::system::error_code(errcode, boost::system::get_system_category()), "QueryPerformanceCounter()"); } double const w = cnt.QuadPart * local::nanosec_per_tick(); LONGLONG const sec = LONGLONG(w) / 1000000000LL; LONGLONG const nsec = LONGLONG(w) % 1000000000LL; std::tm cur; std::tm const* p = boost::date_time::c_time::gmtime(&sec, &cur); date_type const d(p->tm_year + 1900, p->tm_mon + 1, p->tm_mday); LONGLONG const adjust = static_cast(resolution_traits_type::res_adjust() / 1000000LL); LONGLONG const ns = nsec / 1000 * adjust; time_duration_type const td = time_duration_type(p->tm_hour, p->tm_min, p->tm_sec, ns); return time_type(d, td); #elif defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0 && defined(_POSIX_MONOTONIC_CLOCK) timespec tv; int const s = clock_gettime(CLOCK_MONOTONIC, &tv); if (s < 0) { int const errcode = errno; throw boost::system::system_error(boost::system::error_code(errcode, boost::system::get_system_category()), "clock_gettime()"); } std::tm cur; std::tm const* p = boost::date_time::c_time::gmtime(&tv.tv_sec, &cur); date_type const d(p->tm_year + 1900, p->tm_mon + 1, p->tm_mday); long const adjust = static_cast(resolution_traits_type::res_adjust() / 1000000); long const ns = tv.tv_nsec / 1000 * adjust; time_duration_type const td = time_duration_type(p->tm_hour, p->tm_min, p->tm_sec, ns); return time_type(d, td); #else #error monotonic_clock() is not available on this platform #endif } }; } #endif