1 /*
2  *  Created by Phil on 05/08/2013.
3  *  Copyright 2013 Two Blue Cubes Ltd. All rights reserved.
4  *
5  *  Distributed under the Boost Software License, Version 1.0. (See accompanying
6  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7  */
8 
9 #include "catch_timer.h"
10 
11 #include <chrono>
12 
13 namespace Catch {
14 
getCurrentNanosecondsSinceEpoch()15     auto getCurrentNanosecondsSinceEpoch() -> uint64_t {
16         return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count();
17     }
18 
estimateClockResolution()19     auto estimateClockResolution() -> uint64_t {
20         uint64_t sum = 0;
21         static const uint64_t iterations = 1000000;
22 
23         for( std::size_t i = 0; i < iterations; ++i ) {
24 
25             uint64_t ticks;
26             uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();
27             do {
28                 ticks = getCurrentNanosecondsSinceEpoch();
29             }
30             while( ticks == baseTicks );
31 
32             auto delta = ticks - baseTicks;
33             sum += delta;
34         }
35 
36         // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers
37         // - and potentially do more iterations if there's a high variance.
38         return sum/iterations;
39     }
getEstimatedClockResolution()40     auto getEstimatedClockResolution() -> uint64_t {
41         static auto s_resolution = estimateClockResolution();
42         return s_resolution;
43     }
44 
start()45     void Timer::start() {
46        m_nanoseconds = getCurrentNanosecondsSinceEpoch();
47     }
getElapsedNanoseconds() const48     auto Timer::getElapsedNanoseconds() const -> uint64_t {
49         return getCurrentNanosecondsSinceEpoch() - m_nanoseconds;
50     }
getElapsedMicroseconds() const51     auto Timer::getElapsedMicroseconds() const -> uint64_t {
52         return getElapsedNanoseconds()/1000;
53     }
getElapsedMilliseconds() const54     auto Timer::getElapsedMilliseconds() const -> unsigned int {
55         return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
56     }
getElapsedSeconds() const57     auto Timer::getElapsedSeconds() const -> double {
58         return getElapsedMicroseconds()/1000000.0;
59     }
60 
61 
62 } // namespace Catch
63