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()89timer::timer() : attribute(new impl()) 90 { 91 } 92 93 //! Constructor for casting support timer(cast_source const & source)94timer::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()142timer::timer() : attribute(new impl()) 143 { 144 } 145 146 //! Constructor for casting support timer(cast_source const & source)147timer::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