-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathElapsedTimeWithPause.h
More file actions
66 lines (52 loc) · 2.37 KB
/
Copy pathElapsedTimeWithPause.h
File metadata and controls
66 lines (52 loc) · 2.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/*
* Copyright (C) 2024: Arizona Board of Regents on Behalf of the University of Arizona
*/
#pragma once
/**
* @file ElapsedTimeWithPause.h
* @brief Apache Strap-Down Pilotage utility class to maintain pausable elapsed time.
*
* @author ReliaSolve.
* @date June 24, 2024.
*/
#include <chrono>
#include <string>
#include <memory>
namespace asdp {
/// @brief A class to measure elapsed time, with the ability to pause and resume the timer.
class ElapsedTimeWithPause {
public:
/// @brief Constructor that resets the timer to zero.
ElapsedTimeWithPause();
/// @brief Pause the timer.
void Pause();
/// @brief Resume the timer.
void Resume();
/// @brief Reset the timer to zero.
void Reset();
/// @brief Report elapsed time in secconds, not counting time that was paused.
/// @return Elapsed time in seconds, not counting time that was paused.
double ElapsedTime() const;
/// @brief Test the class.
/// @return An empty string if the test passed, otherwise a message describing the failure.
static std::string Test();
protected:
// Using a mutex (even a shared mutex) caused starvation of the unique_lock on Linux when
// trying to pause and resume the timer by the multiple camera shared_lock calls for read
// access because write locks are not prioritized on Linux in this case. To deal with that
// without resorting to Boost, we use a shared_ptr to a state object that holds the state of the timer.
// This pointer is atomic so that we can safely read and write it from multiple threads without
// needing to lock it. The resulting pointed-to state object provides a consistent state that does
// not change while reading it, even though the m_state pointer itself may be replaced while a
// function is still using the old state.
typedef struct {
std::chrono::time_point<std::chrono::steady_clock> start_time;
std::chrono::duration<double> total_pause_time;
bool is_paused;
std::chrono::time_point<std::chrono::steady_clock> pause_start_time;
} State;
/// @brief Only access this variable using std::atomic_load and std::atomic_store.
// This requires C++17 and later, which can handle calling these functions on the non-atomic shared_ptr type.
std::shared_ptr<State> m_state;
};
} // namespace asdp