Apache Mesos
stopwatch.hpp
Go to the documentation of this file.
1 // Licensed under the Apache License, Version 2.0 (the "License");
2 // you may not use this file except in compliance with the License.
3 // You may obtain a copy of the License at
4 //
5 // http://www.apache.org/licenses/LICENSE-2.0
6 //
7 // Unless required by applicable law or agreed to in writing, software
8 // distributed under the License is distributed on an "AS IS" BASIS,
9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 // See the License for the specific language governing permissions and
11 // limitations under the License.
12 
13 #ifndef __STOUT_STOPWATCH_HPP__
14 #define __STOUT_STOPWATCH_HPP__
15 
16 #include <stdint.h>
17 #include <time.h>
18 
19 #ifdef __MACH__
20 #include <mach/clock.h>
21 #include <mach/mach.h>
22 #endif // __MACH__
23 
24 #ifndef __WINDOWS__
25 #include <sys/time.h>
26 #endif
27 
28 #include "duration.hpp"
29 
30 class Stopwatch
31 {
32 public:
34  : running(false)
35  {
36  started.tv_sec = 0;
37  started.tv_nsec = 0;
38  stopped.tv_sec = 0;
39  stopped.tv_nsec = 0;
40  }
41 
42  void start()
43  {
44  started = now();
45  running = true;
46  }
47 
48  void stop()
49  {
50  stopped = now();
51  running = false;
52  }
53 
55  {
56  if (!running) {
57  return Nanoseconds(diff(stopped, started));
58  }
59 
60  return Nanoseconds(diff(now(), started));
61  }
62 
63 private:
64  static timespec now()
65  {
66  timespec ts;
67 #ifdef __MACH__
68  // OS X does not have clock_gettime, use clock_get_time.
69  clock_serv_t cclock;
70  mach_timespec_t mts;
71  host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
72  clock_get_time(cclock, &mts);
73  mach_port_deallocate(mach_task_self(), cclock);
74  ts.tv_sec = mts.tv_sec;
75  ts.tv_nsec = mts.tv_nsec;
76 #elif __WINDOWS__
77  const static __int64 ticks_in_second = 10000000i64;
78  const static __int64 ns_in_tick = 100;
79 
80  // Interpret the filetime as a 64-bit unsigned integer to simplify the math
81  // of converting to `timespec`.
82  static_assert(
83  sizeof(FILETIME) == sizeof(__int64),
84  "stopwatch: We currently require `FILETIME` to be 64 bits in size");
85  __int64 filetime_in_ticks;
86 
87  GetSystemTimeAsFileTime(reinterpret_cast<FILETIME*>(&filetime_in_ticks));
88 
89  // Conversions. `tv_sec` is elapsed seconds, and `tv_nsec` is the remainder
90  // of the elapsed time, in nanoseconds.
91  ts.tv_sec = filetime_in_ticks / ticks_in_second;
92  ts.tv_nsec = filetime_in_ticks % ticks_in_second * ns_in_tick;
93 #else
94  clock_gettime(CLOCK_REALTIME, &ts);
95 #endif // __MACH__
96  return ts;
97  }
98 
99  static uint64_t diff(const timespec& from, const timespec& to)
100  {
101  return ((from.tv_sec - to.tv_sec) * 1000000000LL)
102  + (from.tv_nsec - to.tv_nsec);
103  }
104 
105  bool running;
106  timespec started, stopped;
107 };
108 
109 #endif // __STOUT_STOPWATCH_HPP__
Definition: stopwatch.hpp:30
void stop()
Definition: stopwatch.hpp:48
Nanoseconds elapsed() const
Definition: stopwatch.hpp:54
Stopwatch()
Definition: stopwatch.hpp:33
void start()
Definition: stopwatch.hpp:42
Definition: duration.hpp:217