1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/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)
11 // Copyright: (c) 1998-2003 wxWidgets Team
12 // Licence: wxWindows licence
13 ///////////////////////////////////////////////////////////////////////////////
15 // ============================================================================
17 // ============================================================================
19 // ----------------------------------------------------------------------------
21 // ----------------------------------------------------------------------------
23 // for compilers that support precompilation, includes "wx.h".
24 #include "wx/wxprec.h"
30 #include "wx/stopwatch.h"
36 #include "wx/msw/wrapwin.h"
39 #include "wx/thread.h"
42 // ============================================================================
44 // ============================================================================
46 // ----------------------------------------------------------------------------
48 // ----------------------------------------------------------------------------
62 bool CanBeUsed() const
64 return freq
.QuadPart
!= 0;
67 wxCRIT_SECT_DECLARE_MEMBER(cs
);
74 const int MILLISECONDS_PER_SECOND
= 1000;
75 const int MICROSECONDS_PER_MILLISECOND
= 1000;
76 const int MICROSECONDS_PER_SECOND
= 1000*1000;
78 } // anonymous namespace
80 void wxStopWatch::DoStart()
83 if ( !gs_perfCounter
.init
)
85 wxCRIT_SECT_LOCKER(lock
, gs_perfCounter
.cs
);
86 ::QueryPerformanceFrequency(&gs_perfCounter
.freq
);
88 // Just a sanity check: it's not supposed to happen but verify that
89 // ::QueryPerformanceCounter() succeeds so that we can really use it.
90 LARGE_INTEGER counter
;
91 if ( !::QueryPerformanceCounter(&counter
) )
93 wxLogDebug("QueryPerformanceCounter() unexpected failed (%s), "
94 "will not use it.", wxSysErrorMsg());
96 gs_perfCounter
.freq
.QuadPart
= 0;
99 gs_perfCounter
.init
= true;
101 #endif // __WINDOWS__
103 m_t0
= GetCurrentClockValue();
106 wxLongLong
wxStopWatch::GetClockFreq() const
109 // Under MSW we use the high resolution performance counter timer which has
110 // its own frequency (usually related to the CPU clock speed).
111 if ( gs_perfCounter
.CanBeUsed() )
112 return gs_perfCounter
.freq
.QuadPart
;
113 #endif // __WINDOWS__
115 #ifdef HAVE_GETTIMEOFDAY
116 // With gettimeofday() we can have nominally microsecond precision and
117 // while this is not the case in practice, it's still better than
119 return MICROSECONDS_PER_SECOND
;
120 #else // !HAVE_GETTIMEOFDAY
121 // Currently milliseconds are used everywhere else.
122 return MILLISECONDS_PER_SECOND
;
123 #endif // HAVE_GETTIMEOFDAY/!HAVE_GETTIMEOFDAY
126 void wxStopWatch::Start(long t0
)
128 // Calling Start() makes the stop watch run however many times it was
134 m_t0
-= (wxLongLong(t0
)*GetClockFreq())/MILLISECONDS_PER_SECOND
;
137 wxLongLong
wxStopWatch::GetCurrentClockValue() const
140 if ( gs_perfCounter
.CanBeUsed() )
142 LARGE_INTEGER counter
;
143 ::QueryPerformanceCounter(&counter
);
144 return counter
.QuadPart
;
146 #endif // __WINDOWS__
148 #ifdef HAVE_GETTIMEOFDAY
149 return wxGetUTCTimeUSec();
150 #else // !HAVE_GETTIMEOFDAY
151 return wxGetUTCTimeMillis();
152 #endif // HAVE_GETTIMEOFDAY/!HAVE_GETTIMEOFDAY
155 wxLongLong
wxStopWatch::TimeInMicro() const
157 const wxLongLong
elapsed(m_pauseCount
? m_elapsedBeforePause
158 : GetCurrentClockValue() - m_t0
);
160 return (elapsed
*MICROSECONDS_PER_SECOND
)/GetClockFreq();
163 #endif // wxUSE_STOPWATCH
165 // ----------------------------------------------------------------------------
166 // old timer functions superceded by wxStopWatch
167 // ----------------------------------------------------------------------------
171 static wxLongLong wxStartTime
= 0l;
173 // starts the global timer
176 wxStartTime
= wxGetUTCTimeMillis();
179 // Returns elapsed time in milliseconds
180 long wxGetElapsedTime(bool resetTimer
)
182 wxLongLong oldTime
= wxStartTime
;
183 wxLongLong newTime
= wxGetUTCTimeMillis();
186 wxStartTime
= newTime
;
188 return (newTime
- oldTime
).GetLo();
191 #endif // wxUSE_LONGLONG