1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: common/stopwatch.cpp
3 // Purpose: wxStopWatch and other non-GUI stuff from wx/timer.h
5 // Original version by Julian Smart
6 // Vadim Zeitlin got rid of all ifdefs (11.12.99)
7 // Sylvain Bougnoux added wxStopWatch class
8 // Guillermo Rodriguez <guille@iies.es> rewrote from scratch (Dic/99)
10 // Created: 20.06.2003 (extracted from common/timercmn.cpp)
12 // Copyright: (c) 1998-2003 wxWidgets Team
13 // License: wxWindows license
14 ///////////////////////////////////////////////////////////////////////////////
16 // ============================================================================
18 // ============================================================================
20 // ----------------------------------------------------------------------------
22 // ----------------------------------------------------------------------------
24 // for compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
36 #include "wx/longlong.h"
37 #include "wx/stopwatch.h"
39 // ----------------------------------------------------------------------------
41 // ----------------------------------------------------------------------------
43 #if defined(__WIN32__)
44 #include "wx/msw/wrapwin.h"
47 #if defined(__WIN32__) && !defined(HAVE_FTIME) && !defined(__MWERKS__) && !defined(__WXWINCE__)
51 #if defined(__VISAGECPP__) && !defined(HAVE_FTIME)
53 # if __IBMCPP__ >= 400
54 # define ftime(x) _ftime(x)
58 #if defined(__MWERKS__) && defined(__WXMSW__)
60 # undef HAVE_GETTIMEOFDAY
66 #include "wx/msw/private.h"
67 #include "wx/msw/wince/time.h"
70 #if !defined(__WXMAC__) && !defined(__WXWINCE__)
71 #include <sys/types.h> // for time_t
74 #if defined(HAVE_GETTIMEOFDAY)
77 #elif defined(HAVE_FTIME)
78 #include <sys/timeb.h>
84 #include <DriverServices.h>
86 #include <Carbon/Carbon.h>
93 #include <SystemMgr.h>
96 // ----------------------------------------------------------------------------
98 // ----------------------------------------------------------------------------
100 // on some really old systems gettimeofday() doesn't have the second argument,
101 // define wxGetTimeOfDay() to hide this difference
102 #ifdef HAVE_GETTIMEOFDAY
103 #ifdef WX_GETTIMEOFDAY_NO_TZ
105 #define wxGetTimeOfDay(tv, tz) gettimeofday(tv)
107 #define wxGetTimeOfDay(tv, tz) gettimeofday((tv), (tz))
109 #endif // HAVE_GETTIMEOFDAY
111 // ============================================================================
113 // ============================================================================
115 // ----------------------------------------------------------------------------
117 // ----------------------------------------------------------------------------
121 void wxStopWatch::Start(long t
)
125 LARGE_INTEGER frequency_li
;
126 ::QueryPerformanceFrequency( &frequency_li
);
127 m_frequency
= frequency_li
.QuadPart
;
128 if (m_frequency
== 0)
130 m_t0
= wxGetLocalTimeMillis() - t
;
134 LARGE_INTEGER counter_li
;
135 ::QueryPerformanceCounter( &counter_li
);
136 wxLongLong counter
= counter_li
.QuadPart
;
137 m_t0
= (counter
* 10000 / m_frequency
) - t
*10;
140 m_t0
= wxGetLocalTimeMillis() - t
;
146 long wxStopWatch::GetElapsedTime() const
150 if (m_frequency
== 0)
152 return (wxGetLocalTimeMillis() - m_t0
).GetLo();
156 LARGE_INTEGER counter_li
;
157 ::QueryPerformanceCounter( &counter_li
);
158 wxLongLong counter
= counter_li
.QuadPart
;
159 wxLongLong res
= (counter
* 10000 / m_frequency
) - m_t0
;
160 return res
.GetLo() / 10;
163 return (wxGetLocalTimeMillis() - m_t0
).GetLo();
167 long wxStopWatch::Time() const
169 return m_pauseCount
? m_pause
: GetElapsedTime();
172 #endif // wxUSE_STOPWATCH
174 // ----------------------------------------------------------------------------
175 // old timer functions superceded by wxStopWatch
176 // ----------------------------------------------------------------------------
180 static wxLongLong wxStartTime
= 0l;
182 // starts the global timer
185 wxStartTime
= wxGetLocalTimeMillis();
188 // Returns elapsed time in milliseconds
189 long wxGetElapsedTime(bool resetTimer
)
191 wxLongLong oldTime
= wxStartTime
;
192 wxLongLong newTime
= wxGetLocalTimeMillis();
195 wxStartTime
= newTime
;
197 return (newTime
- oldTime
).GetLo();
200 #endif // wxUSE_LONGLONG
202 // ----------------------------------------------------------------------------
203 // the functions to get the current time and timezone info
204 // ----------------------------------------------------------------------------
206 // Get local time as seconds since 00:00:00, Jan 1st 1970
207 long wxGetLocalTime()
212 // This cannot be made static because mktime can overwrite it.
214 memset(&tm
, 0, sizeof(tm
));
217 tm
.tm_mday
= 5; // not Jan 1st 1970 due to mktime 'feature'
221 tm
.tm_isdst
= -1; // let mktime guess
223 // Note that mktime assumes that the struct tm contains local time.
225 t1
= time(&t1
); // now
226 t0
= mktime(&tm
); // origin
228 // Return the difference in seconds.
230 if (( t0
!= (time_t)-1 ) && ( t1
!= (time_t)-1 ))
231 return (long)difftime(t1
, t0
) + (60 * 60 * 24 * 4);
233 wxLogSysError(_("Failed to get the local system time"));
237 // Get UTC time as seconds since 00:00:00, Jan 1st 1970
240 return (long)time(NULL
);
245 // Get local time as milliseconds since 00:00:00, Jan 1st 1970
246 wxLongLong
wxGetLocalTimeMillis()
248 wxLongLong val
= 1000l;
250 // If possible, use a function which avoids conversions from
251 // broken-up time structures to milliseconds
253 #if defined(__WXPALMOS__)
262 uint32_t now
= TimGetSeconds();
263 uint32_t then
= TimDateTimeToSeconds (&thenst
);
264 return SysTimeToMilliSecs(SysTimeInSecs(now
- then
));
265 #elif defined(__WXMSW__) && (defined(__WINE__) || defined(__MWERKS__))
266 // This should probably be the way all WXMSW compilers should do it
267 // Go direct to the OS for time
269 SYSTEMTIME thenst
= { 1970, 1, 4, 1, 0, 0, 0, 0 }; // 00:00:00 Jan 1st 1970
271 SystemTimeToFileTime( &thenst
, &thenft
);
272 wxLongLong
then( thenft
.dwHighDateTime
, thenft
.dwLowDateTime
); // time in 100 nanoseconds
275 GetLocalTime( &nowst
);
277 SystemTimeToFileTime( &nowst
, &nowft
);
278 wxLongLong
now( nowft
.dwHighDateTime
, nowft
.dwLowDateTime
); // time in 100 nanoseconds
280 return ( now
- then
) / 10000.0; // time from 00:00:00 Jan 1st 1970 to now in milliseconds
282 #elif defined(HAVE_GETTIMEOFDAY)
284 if ( wxGetTimeOfDay(&tp
, (struct timezone
*)NULL
) != -1 )
287 return (val
+ (tp
.tv_usec
/ 1000));
291 wxLogError(_("wxGetTimeOfDay failed."));
294 #elif defined(HAVE_FTIME)
297 // ftime() is void and not int in some mingw32 headers, so don't
298 // test the return code (well, it shouldn't fail anyhow...)
301 return (val
+ tp
.millitm
);
302 #elif defined(__WXMAC__)
304 static UInt64 gMilliAtStart
= 0;
306 Nanoseconds upTime
= AbsoluteToNanoseconds( UpTime() );
308 if ( gMilliAtStart
== 0 )
310 time_t start
= time(NULL
);
311 gMilliAtStart
= ((UInt64
) start
) * 1000000L;
312 gMilliAtStart
-= upTime
.lo
/ 1000 ;
313 gMilliAtStart
-= ( ( (UInt64
) upTime
.hi
) << 32 ) / (1000 * 1000);
316 UInt64 millival
= gMilliAtStart
;
317 millival
+= upTime
.lo
/ (1000 * 1000);
318 millival
+= ( ( (UInt64
) upTime
.hi
) << 32 ) / (1000 * 1000);
322 #else // no gettimeofday() nor ftime()
323 // We use wxGetLocalTime() to get the seconds since
324 // 00:00:00 Jan 1st 1970 and then whatever is available
325 // to get millisecond resolution.
327 // NOTE that this might lead to a problem if the clocks
328 // use different sources, so this approach should be
329 // avoided where possible.
331 val
*= wxGetLocalTime();
333 // GRG: This will go soon as all WIN32 seem to have ftime
334 // JACS: unfortunately not. WinCE doesn't have it.
335 #if defined (__WIN32__)
336 // If your platform/compiler needs to use two different functions
337 // to get ms resolution, please do NOT just shut off these warnings,
338 // drop me a line instead at <guille@iies.es>
342 #warning "Possible clock skew bug in wxGetLocalTimeMillis()!"
347 val
+= st
.wMilliseconds
;
349 // If your platform/compiler does not support ms resolution please
350 // do NOT just shut off these warnings, drop me a line instead at
353 #if defined(__VISUALC__) || defined (__WATCOMC__)
354 #pragma message("wxStopWatch will be up to second resolution!")
355 #elif defined(__BORLANDC__)
356 #pragma message "wxStopWatch will be up to second resolution!"
358 #warning "wxStopWatch will be up to second resolution!"
364 #endif // time functions
367 #else // !wxUSE_LONGLONG
369 double wxGetLocalTimeMillis(void)
371 return (double(clock()) / double(CLOCKS_PER_SEC
)) * 1000.0;
374 #endif // wxUSE_LONGLONG/!wxUSE_LONGLONG