File indexing completed on 2025-01-30 09:46:48
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #ifndef BOOST_MOVE_DETAIL_NSEC_CLOCK_HPP
0025 #define BOOST_MOVE_DETAIL_NSEC_CLOCK_HPP
0026
0027 #include <boost/config.hpp>
0028 #include <boost/cstdint.hpp>
0029 #include <boost/move/detail/workaround.hpp>
0030 #include <cstdlib>
0031
0032
0033 # if (defined(_WIN32) || defined(__WIN32__) || defined(WIN32))
0034 # define BOOST_MOVE_DETAIL_WINDOWS_API
0035 # elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
0036 # define BOOST_MOVE_DETAIL_MAC_API
0037 # else
0038 # define BOOST_MOVE_DETAIL_POSIX_API
0039 # endif
0040
0041 #if defined(BOOST_MOVE_DETAIL_WINDOWS_API)
0042
0043 #include <cassert>
0044
0045 #if defined( BOOST_USE_WINDOWS_H )
0046 #include <Windows.h>
0047 #else
0048
0049 #if defined (WIN32_PLATFORM_PSPC)
0050 #define BOOST_MOVE_WINAPI_IMPORT BOOST_SYMBOL_IMPORT
0051 #define BOOST_MOVE_WINAPI_IMPORT_EXCEPT_WM
0052 #elif defined (_WIN32_WCE)
0053 #define BOOST_MOVE_WINAPI_IMPORT
0054 #define BOOST_MOVE_WINAPI_IMPORT_EXCEPT_WM
0055 #else
0056 #define BOOST_MOVE_WINAPI_IMPORT BOOST_SYMBOL_IMPORT
0057 #define BOOST_MOVE_WINAPI_IMPORT_EXCEPT_WM BOOST_SYMBOL_IMPORT
0058 #endif
0059
0060 #if defined(WINAPI)
0061 #define BOOST_MOVE_WINAPI_CC WINAPI
0062 #else
0063 #if defined(_M_IX86) || defined(__i386__)
0064 #define BOOST_MOVE_WINAPI_CC __stdcall
0065 #else
0066
0067 #define BOOST_MOVE_WINAPI_CC
0068 #endif
0069 #endif
0070
0071
0072 extern "C" {
0073
0074 union _LARGE_INTEGER;
0075 typedef long long QuadPart;
0076
0077 BOOST_MOVE_WINAPI_IMPORT_EXCEPT_WM int BOOST_MOVE_WINAPI_CC
0078 QueryPerformanceCounter(::_LARGE_INTEGER* lpPerformanceCount);
0079
0080 BOOST_MOVE_WINAPI_IMPORT_EXCEPT_WM int BOOST_MOVE_WINAPI_CC
0081 QueryPerformanceFrequency(::_LARGE_INTEGER* lpFrequency);
0082
0083 }
0084 #endif
0085
0086
0087 namespace boost { namespace move_detail {
0088
0089 BOOST_FORCEINLINE int QueryPerformanceCounter(long long* lpPerformanceCount)
0090 {
0091 return ::QueryPerformanceCounter(reinterpret_cast< ::_LARGE_INTEGER* >(lpPerformanceCount));
0092 }
0093
0094 BOOST_FORCEINLINE int QueryPerformanceFrequency(long long* lpFrequency)
0095 {
0096 return ::QueryPerformanceFrequency(reinterpret_cast< ::_LARGE_INTEGER* >(lpFrequency));
0097 }
0098
0099
0100 template<int Dummy>
0101 struct QPFHolder
0102 {
0103 static inline double get_nsec_per_tic()
0104 {
0105 long long freq;
0106
0107
0108 (void)boost::move_detail::QueryPerformanceFrequency(&freq);
0109 return double(1000000000.0L / double(freq));
0110 }
0111
0112 static const double nanosecs_per_tic;
0113 };
0114
0115 template<int Dummy>
0116 const double QPFHolder<Dummy>::nanosecs_per_tic = get_nsec_per_tic();
0117
0118 inline boost::uint64_t nsec_clock() BOOST_NOEXCEPT
0119 {
0120 double nanosecs_per_tic = QPFHolder<0>::nanosecs_per_tic;
0121
0122 long long pcount;
0123
0124
0125 (void)boost::move_detail::QueryPerformanceCounter( &pcount );
0126 return static_cast<boost::uint64_t>(nanosecs_per_tic * double(pcount));
0127 }
0128
0129 }}
0130
0131 #elif defined(BOOST_MOVE_DETAIL_MAC_API)
0132
0133 #include <mach/mach_time.h> // mach_absolute_time, mach_timebase_info_data_t
0134
0135 inline boost::uint64_t nsec_clock() BOOST_NOEXCEPT
0136 {
0137 boost::uint64_t count = ::mach_absolute_time();
0138
0139 mach_timebase_info_data_t info;
0140 mach_timebase_info(&info);
0141 return static_cast<boost::uint64_t>
0142 ( static_cast<double>(count)*(static_cast<double>(info.numer) / info.denom) );
0143 }
0144
0145 #elif defined(BOOST_MOVE_DETAIL_POSIX_API)
0146
0147 #include <time.h>
0148
0149 # if defined(CLOCK_MONOTONIC_PRECISE)
0150 # define BOOST_MOVE_DETAIL_CLOCK_MONOTONIC CLOCK_MONOTONIC_PRECISE
0151 # elif defined(CLOCK_MONOTONIC_RAW)
0152 # define BOOST_MOVE_DETAIL_CLOCK_MONOTONIC CLOCK_MONOTONIC_RAW
0153 # elif defined(CLOCK_HIGHRES)
0154 # define BOOST_MOVE_DETAIL_CLOCK_MONOTONIC CLOCK_HIGHRES
0155 # elif defined(CLOCK_MONOTONIC)
0156 # define BOOST_MOVE_DETAIL_CLOCK_MONOTONIC CLOCK_MONOTONIC
0157 # else
0158 # error "No high resolution steady clock in your system, please provide a patch"
0159 # endif
0160
0161 inline boost::uint64_t nsec_clock() BOOST_NOEXCEPT
0162 {
0163 struct timespec count;
0164 ::clock_gettime(BOOST_MOVE_DETAIL_CLOCK_MONOTONIC, &count);
0165 boost::uint64_t r = static_cast<boost::uint64_t>(count.tv_sec);
0166 r *= 1000000000U;
0167 r += static_cast<boost::uint64_t>(count.tv_nsec);
0168 return r;
0169 }
0170
0171 #endif
0172
0173 namespace boost { namespace move_detail {
0174
0175 typedef boost::uint64_t nanosecond_type;
0176
0177 struct cpu_times
0178 {
0179 nanosecond_type wall;
0180 nanosecond_type user;
0181 nanosecond_type system;
0182
0183 void clear() { wall = user = system = 0; }
0184
0185 cpu_times()
0186 { this->clear(); }
0187 };
0188
0189
0190 inline void get_cpu_times(boost::move_detail::cpu_times& current)
0191 {
0192 current.wall = nsec_clock();
0193 }
0194
0195
0196 class cpu_timer
0197 {
0198 public:
0199
0200
0201 cpu_timer() BOOST_NOEXCEPT { start(); }
0202
0203
0204 bool is_stopped() const BOOST_NOEXCEPT { return m_is_stopped; }
0205 cpu_times elapsed() const BOOST_NOEXCEPT;
0206
0207
0208 void start() BOOST_NOEXCEPT;
0209 void stop() BOOST_NOEXCEPT;
0210 void resume() BOOST_NOEXCEPT;
0211
0212 private:
0213 cpu_times m_times;
0214 bool m_is_stopped;
0215 };
0216
0217
0218
0219
0220 inline void cpu_timer::start() BOOST_NOEXCEPT
0221 {
0222 m_is_stopped = false;
0223 get_cpu_times(m_times);
0224 }
0225
0226 inline void cpu_timer::stop() BOOST_NOEXCEPT
0227 {
0228 if (is_stopped())
0229 return;
0230 m_is_stopped = true;
0231
0232 cpu_times current;
0233 get_cpu_times(current);
0234 m_times.wall = (current.wall - m_times.wall);
0235 m_times.user = (current.user - m_times.user);
0236 m_times.system = (current.system - m_times.system);
0237 }
0238
0239 inline cpu_times cpu_timer::elapsed() const BOOST_NOEXCEPT
0240 {
0241 if (is_stopped())
0242 return m_times;
0243 cpu_times current;
0244 get_cpu_times(current);
0245 current.wall -= m_times.wall;
0246 current.user -= m_times.user;
0247 current.system -= m_times.system;
0248 return current;
0249 }
0250
0251 inline void cpu_timer::resume() BOOST_NOEXCEPT
0252 {
0253 if (is_stopped())
0254 {
0255 cpu_times current (m_times);
0256 start();
0257 m_times.wall -= current.wall;
0258 m_times.user -= current.user;
0259 m_times.system -= current.system;
0260 }
0261 }
0262
0263
0264
0265 }
0266 }
0267
0268 #endif