Main Page · Modules · All Classes · Class Hierarchy
MCTimer.cpp
1 /*
2  * This file is part of the AiBO+ project
3  *
4  * Copyright (C) 2005-2016 Csaba Kertész (csaba.kertesz@gmail.com)
5  *
6  * AiBO+ is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * AiBO+ is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
19  *
20  */
21 
22 #include "MCTimer.hpp"
23 
24 #include <limits.h>
25 #include <stdio.h>
26 
27 #include "MCDefs.hpp"
28 #include "MCThreadLocalData.hpp"
29 
30 #ifndef __AIBO_BUILD__
31 #include <QElapsedTimer>
32 #endif
33 
34 namespace
35 {
36 #ifdef __AIBO_BUILD__
37 // Get the current time on Aibo
38 static SystemTime AiboTimer;
39 #else
40 // Global timer
41 MCThreadLocalData<QElapsedTimer> GlobalTimer(true);
42 #endif
43 // Optional custom system time handler
44 MCThreadLocalData<MASystemTimeHandler> SystemTimeHandler(true);
45 // System time start in a thread
46 MCThreadLocalData<int64_t> SystemTimeStart(true);
47 // System time shift caused by hibernation in a thread
48 MCThreadLocalData<int64_t> HibernationTimeShift(true);
49 // Start of time hibernation in a thread
50 MCThreadLocalData<int64_t> HibernationStartTime(true);
51 // System time shift caused by hibernation in a thread
52 MCThreadLocalData<MCTimer> HibernationTimer(true);
53 
54 bool CheckStaticTimerVariables()
55 {
56  if (!SystemTimeStart.get())
57  {
58  SystemTimeStart.reset(new int64_t);
59  *SystemTimeStart = 0;
60  HibernationTimeShift.reset(new int64_t);
61  *HibernationTimeShift = 0;
62  HibernationStartTime.reset(new int64_t);
63  *HibernationStartTime = 0;
64  HibernationTimer.reset(new MCTimer(MC::NoExpiration, 0));
65  return true;
66  }
67  return false;
68 }
69 }
70 
71 MCTimer::MCTimer(MC::TimerType timer_type, int duration) : TimerType(timer_type),
72  Duration((int64_t)duration*(duration > 0 ? 1000 : 1)), LastShot(-1), Shots(-1),
73  StartTime(0)
74 {
75 }
76 
77 
78 MCTimer::~MCTimer()
79 {
80 }
81 
82 
84 {
85  SystemTimeHandler.reset(&handler);
86  // Reset the system start time
87  CheckStaticTimerVariables();
88  *SystemTimeStart = handler.GetSystemTime();
89 }
90 
91 
92 int64_t MCTimer::GetElapsedSystemTime(bool relative_time)
93 {
94  int64_t CurrentTime = 0;
95 
96  if (HibernationStartTime.get() && *HibernationStartTime > 0)
97  {
98  CurrentTime = *HibernationStartTime;
99  } else
100  if (SystemTimeHandler.get())
101  {
102  CurrentTime = SystemTimeHandler->GetSystemTime();
103  } else {
104  // Get the current time in milliseconds
105 #ifdef __AIBO_BUILD__
106  GetSystemTime(&AiboTimer);
107  CurrentTime = (int64_t)AiboTimer.seconds*1000000+AiboTimer.useconds;
108 #else
109  if (unlikely(!GlobalTimer.get()))
110  {
111  GlobalTimer.reset(new QElapsedTimer);
112  GlobalTimer->start();
113  }
114  CurrentTime = (int64_t)GlobalTimer->nsecsElapsed() / 1000;
115 #endif
116  }
117  if (CheckStaticTimerVariables())
118  {
119  *SystemTimeStart = CurrentTime;
120  return 0;
121  }
122  return relative_time ? CurrentTime-*SystemTimeStart-*HibernationTimeShift : CurrentTime-*HibernationTimeShift;
123 }
124 
125 
127 {
128  CheckStaticTimerVariables();
129  *SystemTimeStart = GetElapsedSystemTime(false);
130 }
131 
132 
134 {
135  CheckStaticTimerVariables();
136  if (HibernationTimer->IsStarted())
137  return;
138 
139  HibernationTimer->Start();
140  // Set the hibernation start time to override all subsequent calls to GetElapsedSystemTime() until
141  // the system time is resumed.
142  *HibernationStartTime = GetElapsedSystemTime(false)+*HibernationTimeShift;
143 }
144 
145 
147 {
148  CheckStaticTimerVariables();
149  if (!HibernationTimer->IsStarted())
150  return;
151 
152  // First reset the hibernation start time. -> The real, elapsed hibernation time can be read back.
153  *HibernationStartTime = 0;
154  *HibernationTimeShift += HibernationTimer->GetElapsedTimeInUSecs();
155  HibernationTimer->Stop();
156 }
157 
158 
159 void MCTimer::SetDuration(int duration)
160 {
161  Duration = (int64_t)duration*(duration > 0 ? 1000 : 1);
162 }
163 
164 
166 {
167  return (int)(Duration / (Duration > 0 ? 1000 : 1));
168 }
169 
170 
172 {
173  return (int)(StartTime / 1000);
174 }
175 
176 
177 bool MCTimer::IsStarted() const
178 {
179  return Shots != -1;
180 }
181 
182 
183 void MCTimer::Start(int time_shift)
184 {
185  StartTime = GetElapsedSystemTime()-(int64_t)time_shift*1000;
187  Shots = 0;
188 }
189 
190 
191 void MCTimer::StartFromTime(int start_time)
192 {
193  StartTime = (int64_t)start_time*1000;
195  Shots = 0;
196 }
197 
198 
200 {
201  Reset();
202 }
203 
204 
206 {
207  return (int)(GetElapsedTimeInUSecs() / 1000);
208 }
209 
210 
212 {
213  if (LastShot < 0)
214  {
215  return 0;
216  }
218 }
219 
220 
222 {
223  // The timer never expires or the timer is not started. -> Return
224  if (TimerType == MC::NoExpiration || Duration < 0)
225  {
226  return false;
227  }
228  // The timer has been expired
230  {
232  {
233  return true;
234  }
236  Shots++;
238  {
239  return true;
240  }
241  }
242  return false;
243 }
244 
245 
247 {
248  LastShot = -1;
249  Shots = -1;
250  StartTime = 0;
251 }
void Start(int time_shift=0)
Start the timer.
Definition: MCTimer.cpp:183
int Shots
Shot number.
Definition: MCTimer.hpp:233
virtual int64_t GetSystemTime()=0
Get system time.
void Reset()
Reset the timer.
Definition: MCTimer.cpp:246
void StartFromTime(int start_time)
Start from a given time.
Definition: MCTimer.cpp:191
bool IsStarted() const
Check if the timer has been started.
Definition: MCTimer.cpp:177
void Stop()
Stop the timer.
Definition: MCTimer.cpp:199
int64_t LastShot
The last shot in microseconds.
Definition: MCTimer.hpp:231
int GetStartTime() const
Get the start time.
Definition: MCTimer.cpp:171
static void ResumeSystemTime()
Hibernate the system time.
Definition: MCTimer.cpp:146
MC::TimerType TimerType
The type of the timer.
Definition: MCTimer.hpp:227
System timer handler.
Definition: MCTimer.hpp:243
int GetDuration() const
Get the duration of the time.
Definition: MCTimer.cpp:165
void SetDuration(int duration)
Set the duration of the timer.
Definition: MCTimer.cpp:159
int64_t Duration
Duration.
Definition: MCTimer.hpp:229
TimerType
Definition: MCTimer.hpp:45
int GetElapsedTime()
Get the elapsed time since the timer has been started or since the last timeout.
Definition: MCTimer.cpp:205
MCTimer(MC::TimerType timer_type=MC::SingleShot, int duration=-1)
Constructs a given type of the timer varying the expiration and the shot method.
Definition: MCTimer.cpp:71
static int64_t GetElapsedSystemTime(bool relative_time=true)
Get the system time.
Definition: MCTimer.cpp:92
int64_t StartTime
Start time.
Definition: MCTimer.hpp:235
static void ResetElapsedSystemTime()
Reset the system time measurement.
Definition: MCTimer.cpp:126
Simple timer class with microsecond precision.
Definition: MCTimer.hpp:59
int64_t GetElapsedTimeInUSecs()
Get the elapsed time in microseconds since the timer has been started or since the last timeout...
Definition: MCTimer.cpp:211
static void HibernateSystemTime()
Hibernate the system time.
Definition: MCTimer.cpp:133
static void SetCustomHandler(MASystemTimeHandler &handler)
Set system time handler.
Definition: MCTimer.cpp:83
A wrapper class to cover boost::thread_specific_ptr/folly::ThreadLocal API on certain targets...
bool Timeout()
Check if the timer has been timed out.
Definition: MCTimer.cpp:221