MADARA  3.1.8
SimTime.cpp
Go to the documentation of this file.
1 #include "SimTime.h"
2 
3 #if defined(MADARA_FEATURE_SIMTIME) && MADARA_FEATURE_SIMTIME==1
4 
5 #include <chrono>
6 
7 namespace madara { namespace utility {
8 
9 const double minrate = 0.0000000001;
10 
11 std::mutex SimTime::mutex_{};
12 
13 sim_time_callback_fn SimTime::callback_ = nullptr;
14 
15 uint64_t SimTime::last_realtime_ = SimTime::realtime();
16 uint64_t SimTime::last_simtime_ = 0;
17 double SimTime::last_rate_ = 1.0;
18 
19 uint64_t SimTime::realtime() {
20  namespace sc = std::chrono;
21  auto now = sc::system_clock::now();
22  auto dur = now.time_since_epoch();
23  return sc::duration_cast<sc::nanoseconds>(dur).count();
24 }
25 
26 uint64_t SimTime::time() {
27  uint64_t prt;
28  uint64_t pst;
29  double pr;
30  uint64_t st;
31  double r;
32  sim_time_callback_fn callback;
33 
34  uint64_t now = realtime();
35  {
36  std::lock_guard<std::mutex> guard{mutex_};
37  callback = callback_;
38  if (callback) {
39  callback_(&st, &r);
40 
41  last_realtime_ = now;
42  last_simtime_ = st;
43  last_rate_ = r;
44  } else {
45  prt = last_realtime_;
46  pst = last_simtime_;
47  pr = last_rate_;
48  }
49  }
50 
51  if (!callback) {
52  if (pr == 0) {
53  return pst;
54  }
55 
56  int64_t offset = now - prt;
57 
58  if (pr < minrate) {
59  pr = minrate;
60  }
61 
62  double delta = offset * pr;
63  st = pst + (int64_t)delta;
64  }
65 
66  return st;
67 }
68 
69 double SimTime::rate() {
70  double r;
71  sim_time_callback_fn callback;
72 
73  {
74  std::lock_guard<std::mutex> guard{mutex_};
75  callback = callback_;
76 
77  if (callback) {
78  callback(nullptr, &r);
79  } else {
80  r = last_rate_;
81  }
82  }
83 
84  return r;
85 }
86 
87 uint64_t SimTime::duration(uint64_t sim_duration) {
88  double r = rate();
89 
90  if (r < minrate) {
91  return -1;
92  }
93 
94  return sim_duration / r;
95 }
96 
97 uint64_t SimTime::future(uint64_t sim_offset) {
98  uint64_t now = realtime();
99  uint64_t offset = duration(sim_offset);
100 
101  if (offset == -1) {
102  return -1;
103  }
104 
105  return now + offset;
106 }
107 
108 sim_time_callback_fn set_sim_time_callback(sim_time_callback_fn fn) {
109  std::lock_guard<std::mutex> guard{SimTime::mutex_};
110  sim_time_callback_fn ret = SimTime::callback_;
111  SimTime::callback_ = fn;
112  return ret;
113 }
114 
115 void sim_time_notify(uint64_t time, double rate) {
116  uint64_t now = SimTime::realtime();
117 
118  std::lock_guard<std::mutex> guard{SimTime::mutex_};
119 
120  SimTime::last_realtime_ = now;
121  SimTime::last_simtime_ = time;
122  SimTime::last_rate_ = rate;
123 }
124 
125 } }
126 
127 #endif
Provides utility functions and classes for common tasks and needs.
Definition: IteratorImpl.h:14
Copyright (c) 2015 Carnegie Mellon University.