• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
impl()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.
get_value()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
timer()89 timer::timer() : attribute(new impl())
90 {
91 }
92 
93 //! Constructor for casting support
timer(cast_source const & source)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      */
impl()132     impl() : m_BaseTimePoint(utc_time_traits::get_clock()) {}
133 
get_value()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
timer()142 timer::timer() : attribute(new impl())
143 {
144 }
145 
146 //! Constructor for casting support
timer(cast_source const & source)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