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