1 | /* |
2 | * Copyright Andrey Semashev 2007 - 2015. |
3 | * Distributed under the Boost Software License, Version 1.0. |
4 | * (See accompanying file LICENSE_1_0.txt or copy at |
5 | * http://www.boost.org/LICENSE_1_0.txt) |
6 | */ |
7 | /*! |
8 | * \file timer.cpp |
9 | * \author Andrey Semashev |
10 | * \date 02.12.2007 |
11 | * |
12 | * \brief This header is the Boost.Log library implementation, see the library documentation |
13 | * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html. |
14 | */ |
15 | |
16 | #include <boost/log/detail/config.hpp> |
17 | #include <boost/log/attributes/timer.hpp> |
18 | #include <boost/log/attributes/attribute_value_impl.hpp> |
19 | |
20 | #if defined(BOOST_WINDOWS) && !defined(BOOST_LOG_NO_QUERY_PERFORMANCE_COUNTER) |
21 | |
22 | #include <boost/assert.hpp> |
23 | #include <boost/cstdint.hpp> |
24 | #if !defined(BOOST_LOG_NO_THREADS) |
25 | #include <boost/log/detail/locks.hpp> |
26 | #include <boost/thread/mutex.hpp> |
27 | #endif |
28 | #include <windows.h> |
29 | #include <boost/log/detail/header.hpp> |
30 | |
31 | namespace boost { |
32 | |
33 | BOOST_LOG_OPEN_NAMESPACE |
34 | |
35 | namespace attributes { |
36 | |
37 | //! Factory implementation |
38 | class BOOST_SYMBOL_VISIBLE timer::impl : |
39 | public attribute::impl |
40 | { |
41 | private: |
42 | #if !defined(BOOST_LOG_NO_THREADS) |
43 | //! Synchronization mutex type |
44 | typedef boost::mutex mutex_type; |
45 | //! Synchronization mutex |
46 | mutex_type m_Mutex; |
47 | #endif |
48 | //! Frequency factor for calculating duration |
49 | double m_FrequencyFactor; |
50 | //! Last value of the performance counter |
51 | uint64_t m_LastCounter; |
52 | //! Elapsed time duration, in microseconds |
53 | uint64_t m_Duration; |
54 | |
55 | public: |
56 | //! Constructor |
57 | impl() : m_Duration(0) |
58 | { |
59 | LARGE_INTEGER li; |
60 | QueryPerformanceFrequency(&li); |
61 | BOOST_ASSERT(li.QuadPart != 0LL); |
62 | m_FrequencyFactor = 1000000.0 / static_cast< double >(li.QuadPart); |
63 | |
64 | QueryPerformanceCounter(&li); |
65 | m_LastCounter = static_cast< uint64_t >(li.QuadPart); |
66 | } |
67 | |
68 | //! The method returns the actual attribute value. It must not return NULL. |
69 | attribute_value get_value() |
70 | { |
71 | uint64_t duration; |
72 | { |
73 | BOOST_LOG_EXPR_IF_MT(log::aux::exclusive_lock_guard< mutex_type > lock(m_Mutex);) |
74 | |
75 | LARGE_INTEGER li; |
76 | QueryPerformanceCounter(&li); |
77 | const uint64_t counter = static_cast< uint64_t >(li.QuadPart); |
78 | const uint64_t counts = counter - m_LastCounter; |
79 | m_LastCounter = counter; |
80 | duration = m_Duration + static_cast< uint64_t >(counts * m_FrequencyFactor); |
81 | m_Duration = duration; |
82 | } |
83 | |
84 | return attribute_value(new attribute_value_impl< value_type >(boost::posix_time::microseconds(duration))); |
85 | } |
86 | }; |
87 | |
88 | //! Constructor |
89 | timer::timer() : attribute(new impl()) |
90 | { |
91 | } |
92 | |
93 | //! Constructor for casting support |
94 | timer::timer(cast_source const& source) : attribute(source.as< impl >()) |
95 | { |
96 | } |
97 | |
98 | } // namespace attributes |
99 | |
100 | BOOST_LOG_CLOSE_NAMESPACE // namespace log |
101 | |
102 | } // namespace boost |
103 | |
104 | #include <boost/log/detail/footer.hpp> |
105 | |
106 | #else // defined(BOOST_WINDOWS) && !defined(BOOST_LOG_NO_QUERY_PERFORMANCE_COUNTER) |
107 | |
108 | #include <boost/log/detail/header.hpp> |
109 | |
110 | namespace boost { |
111 | |
112 | BOOST_LOG_OPEN_NAMESPACE |
113 | |
114 | namespace attributes { |
115 | |
116 | //! Factory implementation |
117 | class BOOST_SYMBOL_VISIBLE timer::impl : |
118 | public attribute::impl |
119 | { |
120 | public: |
121 | //! Time type |
122 | typedef utc_time_traits::time_type time_type; |
123 | |
124 | private: |
125 | //! Base time point |
126 | const time_type m_BaseTimePoint; |
127 | |
128 | public: |
129 | /*! |
130 | * Constructor. Starts time counting. |
131 | */ |
132 | impl() : m_BaseTimePoint(utc_time_traits::get_clock()) {} |
133 | |
134 | attribute_value get_value() BOOST_OVERRIDE |
135 | { |
136 | return attribute_value(new attribute_value_impl< value_type >( |
137 | utc_time_traits::get_clock() - m_BaseTimePoint)); |
138 | } |
139 | }; |
140 | |
141 | //! Constructor |
142 | timer::timer() : attribute(new impl()) |
143 | { |
144 | } |
145 | |
146 | //! Constructor for casting support |
147 | timer::timer(cast_source const& source) : attribute(source.as< impl >()) |
148 | { |
149 | } |
150 | |
151 | } // namespace attributes |
152 | |
153 | BOOST_LOG_CLOSE_NAMESPACE // namespace log |
154 | |
155 | } // namespace boost |
156 | |
157 | #include <boost/log/detail/footer.hpp> |
158 | |
159 | #endif // defined(BOOST_WINDOWS) && !defined(BOOST_LOG_NO_QUERY_PERFORMANCE_COUNTER) |
160 | |