Chris@16
|
1 // win/chrono.cpp --------------------------------------------------------------//
|
Chris@16
|
2
|
Chris@16
|
3 // Copyright Beman Dawes 2008
|
Chris@16
|
4 // Copyright 2009-2010 Vicente J. Botet Escriba
|
Chris@16
|
5
|
Chris@16
|
6 // Distributed under the Boost Software License, Version 1.0.
|
Chris@16
|
7 // See http://www.boost.org/LICENSE_1_0.txt
|
Chris@16
|
8
|
Chris@16
|
9 //----------------------------------------------------------------------------//
|
Chris@16
|
10 // Windows //
|
Chris@16
|
11 //----------------------------------------------------------------------------//
|
Chris@16
|
12 #ifndef BOOST_CHRONO_DETAIL_INLINED_WIN_CHRONO_HPP
|
Chris@16
|
13 #define BOOST_CHRONO_DETAIL_INLINED_WIN_CHRONO_HPP
|
Chris@16
|
14
|
Chris@16
|
15 #include <boost/detail/winapi/time.hpp>
|
Chris@16
|
16 #include <boost/detail/winapi/timers.hpp>
|
Chris@16
|
17 #include <boost/detail/winapi/GetLastError.hpp>
|
Chris@16
|
18
|
Chris@16
|
19 namespace boost
|
Chris@16
|
20 {
|
Chris@16
|
21 namespace chrono
|
Chris@16
|
22 {
|
Chris@16
|
23 namespace chrono_detail
|
Chris@16
|
24 {
|
Chris@16
|
25
|
Chris@16
|
26 BOOST_CHRONO_INLINE double get_nanosecs_per_tic() BOOST_NOEXCEPT
|
Chris@16
|
27 {
|
Chris@16
|
28 boost::detail::winapi::LARGE_INTEGER_ freq;
|
Chris@16
|
29 if ( !boost::detail::winapi::QueryPerformanceFrequency( &freq ) )
|
Chris@16
|
30 return 0.0L;
|
Chris@16
|
31 return double(1000000000.0L / freq.QuadPart);
|
Chris@16
|
32 }
|
Chris@16
|
33
|
Chris@16
|
34 }
|
Chris@16
|
35
|
Chris@16
|
36 steady_clock::time_point steady_clock::now() BOOST_NOEXCEPT
|
Chris@16
|
37 {
|
Chris@101
|
38 double nanosecs_per_tic = chrono_detail::get_nanosecs_per_tic();
|
Chris@16
|
39
|
Chris@16
|
40 boost::detail::winapi::LARGE_INTEGER_ pcount;
|
Chris@101
|
41 if ( nanosecs_per_tic <= 0.0L )
|
Chris@16
|
42 {
|
Chris@101
|
43 BOOST_ASSERT(0 && "Boost::Chrono - get_nanosecs_per_tic Internal Error");
|
Chris@16
|
44 return steady_clock::time_point();
|
Chris@16
|
45 }
|
Chris@101
|
46 unsigned times=0;
|
Chris@101
|
47 while ( ! boost::detail::winapi::QueryPerformanceCounter( &pcount ) )
|
Chris@101
|
48 {
|
Chris@101
|
49 if ( ++times > 3 )
|
Chris@101
|
50 {
|
Chris@101
|
51 BOOST_ASSERT(0 && "Boost::Chrono - QueryPerformanceCounter Internal Error");
|
Chris@101
|
52 return steady_clock::time_point();
|
Chris@101
|
53 }
|
Chris@101
|
54 }
|
Chris@16
|
55
|
Chris@16
|
56 return steady_clock::time_point(steady_clock::duration(
|
Chris@16
|
57 static_cast<steady_clock::rep>((nanosecs_per_tic) * pcount.QuadPart)));
|
Chris@16
|
58 }
|
Chris@16
|
59
|
Chris@16
|
60
|
Chris@16
|
61 #if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
|
Chris@16
|
62 steady_clock::time_point steady_clock::now( system::error_code & ec )
|
Chris@16
|
63 {
|
Chris@101
|
64 double nanosecs_per_tic = chrono_detail::get_nanosecs_per_tic();
|
Chris@16
|
65
|
Chris@16
|
66 boost::detail::winapi::LARGE_INTEGER_ pcount;
|
Chris@16
|
67 if ( (nanosecs_per_tic <= 0.0L)
|
Chris@16
|
68 || (!boost::detail::winapi::QueryPerformanceCounter( &pcount )) )
|
Chris@16
|
69 {
|
Chris@16
|
70 boost::detail::winapi::DWORD_ cause =
|
Chris@16
|
71 ((nanosecs_per_tic <= 0.0L)
|
Chris@16
|
72 ? ERROR_NOT_SUPPORTED
|
Chris@16
|
73 : boost::detail::winapi::GetLastError());
|
Chris@16
|
74 if (BOOST_CHRONO_IS_THROWS(ec)) {
|
Chris@16
|
75 boost::throw_exception(
|
Chris@16
|
76 system::system_error(
|
Chris@16
|
77 cause,
|
Chris@16
|
78 BOOST_CHRONO_SYSTEM_CATEGORY,
|
Chris@16
|
79 "chrono::steady_clock" ));
|
Chris@16
|
80 }
|
Chris@16
|
81 else
|
Chris@16
|
82 {
|
Chris@16
|
83 ec.assign( cause, BOOST_CHRONO_SYSTEM_CATEGORY );
|
Chris@16
|
84 return steady_clock::time_point(duration(0));
|
Chris@16
|
85 }
|
Chris@16
|
86 }
|
Chris@16
|
87
|
Chris@16
|
88 if (!BOOST_CHRONO_IS_THROWS(ec))
|
Chris@16
|
89 {
|
Chris@16
|
90 ec.clear();
|
Chris@16
|
91 }
|
Chris@16
|
92 return time_point(duration(
|
Chris@16
|
93 static_cast<steady_clock::rep>(nanosecs_per_tic * pcount.QuadPart)));
|
Chris@16
|
94 }
|
Chris@16
|
95 #endif
|
Chris@16
|
96
|
Chris@16
|
97 BOOST_CHRONO_INLINE
|
Chris@16
|
98 system_clock::time_point system_clock::now() BOOST_NOEXCEPT
|
Chris@16
|
99 {
|
Chris@16
|
100 boost::detail::winapi::FILETIME_ ft;
|
Chris@16
|
101 boost::detail::winapi::GetSystemTimeAsFileTime( &ft ); // never fails
|
Chris@16
|
102 return system_clock::time_point(
|
Chris@16
|
103 system_clock::duration(
|
Chris@16
|
104 ((static_cast<__int64>( ft.dwHighDateTime ) << 32) | ft.dwLowDateTime)
|
Chris@101
|
105 - 116444736000000000LL
|
Chris@101
|
106 //- (134775LL*864000000000LL)
|
Chris@16
|
107 )
|
Chris@16
|
108 );
|
Chris@16
|
109 }
|
Chris@16
|
110
|
Chris@16
|
111 #if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
|
Chris@16
|
112 BOOST_CHRONO_INLINE
|
Chris@16
|
113 system_clock::time_point system_clock::now( system::error_code & ec )
|
Chris@16
|
114 {
|
Chris@16
|
115 boost::detail::winapi::FILETIME_ ft;
|
Chris@16
|
116 boost::detail::winapi::GetSystemTimeAsFileTime( &ft ); // never fails
|
Chris@16
|
117 if (!BOOST_CHRONO_IS_THROWS(ec))
|
Chris@16
|
118 {
|
Chris@16
|
119 ec.clear();
|
Chris@16
|
120 }
|
Chris@16
|
121 return system_clock::time_point(
|
Chris@16
|
122 system_clock::duration(
|
Chris@16
|
123 ((static_cast<__int64>( ft.dwHighDateTime ) << 32) | ft.dwLowDateTime)
|
Chris@101
|
124 - 116444736000000000LL
|
Chris@101
|
125 //- (134775LL*864000000000LL)
|
Chris@16
|
126 ));
|
Chris@16
|
127 }
|
Chris@16
|
128 #endif
|
Chris@16
|
129
|
Chris@16
|
130 BOOST_CHRONO_INLINE
|
Chris@16
|
131 std::time_t system_clock::to_time_t(const system_clock::time_point& t) BOOST_NOEXCEPT
|
Chris@16
|
132 {
|
Chris@16
|
133 __int64 temp = t.time_since_epoch().count();
|
Chris@16
|
134 temp /= 10000000;
|
Chris@16
|
135 return static_cast<std::time_t>( temp );
|
Chris@16
|
136 }
|
Chris@16
|
137
|
Chris@16
|
138 BOOST_CHRONO_INLINE
|
Chris@16
|
139 system_clock::time_point system_clock::from_time_t(std::time_t t) BOOST_NOEXCEPT
|
Chris@16
|
140 {
|
Chris@16
|
141 __int64 temp = t;
|
Chris@16
|
142 temp *= 10000000;
|
Chris@16
|
143 return time_point(duration(temp));
|
Chris@16
|
144 }
|
Chris@16
|
145
|
Chris@16
|
146 } // namespace chrono
|
Chris@16
|
147 } // namespace boost
|
Chris@16
|
148
|
Chris@16
|
149 #endif
|