m2etis  0.4
Clock.h
Go to the documentation of this file.
1 /*
2  Copyright (2016) Michael Baer, Daniel Bonrath, All rights reserved.
3 
4  Licensed under the Apache License, Version 2.0 (the "License");
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7 
8  http://www.apache.org/licenses/LICENSE-2.0
9 
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15  */
16 
22 #ifndef __M2ETIS_UTIL_CLOCK_H__
23 #define __M2ETIS_UTIL_CLOCK_H__
24 
25 #include <climits>
26 #include <map>
27 
28 #include "m2etis/util/Logger.h"
29 
30 #include "boost/thread.hpp"
31 
32 namespace m2etis {
33 namespace util {
34 
38  template<class Updater>
39  class Clock : public Updater {
40  public:
44  Clock() : Updater(boost::bind(&Clock::Update, this)), timer_(), lock_(), usedIds_(0), systemTime_(0), running_(true), offset_(0) {
45  Updater::Init();
46  }
47 
51  ~Clock() {
52  Updater::Stop();
53  running_ = false;
54  boost::mutex::scoped_lock l(lock_);
55  for (std::map<uint64_t, std::pair<uint64_t, boost::condition_variable *>>::iterator it = timer_.begin(); it != timer_.end(); ++it) {
56  it->second.second->notify_all();
57  // FIXME: but there musn't be any remaing waiting processes...
58  delete it->second.second;
59  }
60  timer_.clear();
61  }
62 
68  uint64_t getTime() const {
69  return systemTime_ + offset_;
70  }
71 
77  uint64_t getRealTime() const {
78  return systemTime_;
79  }
80 
84  uint64_t registerTimer() {
85  std::pair<uint64_t, boost::condition_variable *> p(std::make_pair(UINT64_MAX, new boost::condition_variable()));
86 
87  boost::mutex::scoped_lock lock(lock_);
88  uint64_t id = usedIds_++;
89  timer_[id] = p;
90 
91  return id;
92  }
93 
97  void unregisterTimer(uint64_t timerID) {
98  boost::mutex::scoped_lock lock(lock_);
99  delete timer_[timerID].second;
100  timer_.erase(timerID);
101  }
102 
106  void updateWaitTime(uint64_t timerID, uint64_t time) {
107  boost::mutex::scoped_lock lock(lock_);
108  if (time <= systemTime_ + offset_) {
109  timer_[timerID].second->notify_all();
110  return;
111  }
112  timer_[timerID].first = time;
113  }
114 
118  bool waitForTime(uint64_t timerID, uint64_t time) {
119  if (!running_) {
120  return false;
121  }
122  boost::mutex::scoped_lock lock(lock_); // Is a scoped lock
123  if (time <= systemTime_ + offset_) {
124  return true;
125  }
126  timer_[timerID].first = time;
127  timer_[timerID].second->wait(lock);
128  return running_;
129  }
130 
134  bool isRunning() {
135  return running_;
136  }
137 
141  void setOffset(uint64_t offset) {
142  offset_ = offset;
143  }
144 
145  private:
146  // id wakeuptime variable
147  std::map<uint64_t, std::pair<uint64_t, boost::condition_variable *>> timer_;
148 
149  boost::mutex lock_;
150  uint64_t usedIds_;
151 
152  // last system time
153  volatile uint64_t systemTime_;
154 
155  volatile bool running_;
156 
157  volatile uint64_t offset_;
158 
159  void Update() {
160  if (!running_) {
161  return;
162  }
163  // Get current time.
164  boost::mutex::scoped_lock sl(lock_);
165  systemTime_ = Updater::getCurrentTime(systemTime_);
166  notifyTimer();
167  }
168 
169  void notifyTimer() {
170  for (std::map<uint64_t, std::pair<uint64_t, boost::condition_variable *>>::iterator it = timer_.begin(); it != timer_.end(); ++it) {
171  if (systemTime_ + offset_ >= it->second.first) {
172  it->second.first = UINT64_MAX;
173  it->second.second->notify_all();
174  }
175  }
176  }
177 
178  Clock(const Clock &) = delete;
179  Clock & operator=(const Clock &) = delete;
180  };
181 
182 } /* namespace util */
183 } /* namespace m2etis */
184 
185 #endif /* __M2ETIS_UTIL_CLOCK_H__ */
186 
Clock for time handling, Updater is the implementation of the time, like a RealTimeClock measuring re...
Definition: Clock.h:39
void setOffset(uint64_t offset)
sets offset of this Clock to adjust times over network
Definition: Clock.h:141
bool isRunning()
gets state of the Clock
Definition: Clock.h:134
void updateWaitTime(uint64_t timerID, uint64_t time)
updates the time a given timer has to wait
Definition: Clock.h:106
void unregisterTimer(uint64_t timerID)
frees a timer ID
Definition: Clock.h:97
Clock()
initializes Clock and propagates Update method to Updater
Definition: Clock.h:44
uint64_t registerTimer()
returns a new ID for a timer
Definition: Clock.h:84
uint64_t getRealTime() const
Will return the real time since the Clock has been started.
Definition: Clock.h:77
uint64_t getTime() const
Will return the time since the Clock on the rendezvouz node has started.
Definition: Clock.h:68
~Clock()
destructor
Definition: Clock.h:51
bool waitForTime(uint64_t timerID, uint64_t time)
timer with timerID will wait for time and then be unlocked again
Definition: Clock.h:118