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)
12 // Copyright: (c) 1998-2003 wxWidgets Team
13 // Licence: wxWindows licence
14 ///////////////////////////////////////////////////////////////////////////////
16 // ============================================================================
18 // ============================================================================
20 // ----------------------------------------------------------------------------
22 // ----------------------------------------------------------------------------
24 // for compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
31 #include "wx/stopwatch.h"
37 #include "wx/msw/wrapwin.h"
40 #include "wx/thread.h"
43 // ============================================================================
45 // ============================================================================
47 // ----------------------------------------------------------------------------
49 // ----------------------------------------------------------------------------
63 bool CanBeUsed() const
65 return freq
.QuadPart
!= 0;
68 wxCRIT_SECT_DECLARE_MEMBER(cs
);
75 const int MILLISECONDS_PER_SECOND
= 1000;
76 const int MICROSECONDS_PER_MILLISECOND
= 1000;
77 const int MICROSECONDS_PER_SECOND
= 1000*1000;
79 } // anonymous namespace
81 void wxStopWatch::DoStart()
84 if ( !gs_perfCounter
.init
)
86 wxCRIT_SECT_LOCKER(lock
, gs_perfCounter
.cs
);
87 ::QueryPerformanceFrequency(&gs_perfCounter
.freq
);
89 // Just a sanity check: it's not supposed to happen but verify that
90 // ::QueryPerformanceCounter() succeeds so that we can really use it.
91 LARGE_INTEGER counter
;
92 if ( !::QueryPerformanceCounter(&counter
) )
94 wxLogDebug("QueryPerformanceCounter() unexpected failed (%s), "
95 "will not use it.", wxSysErrorMsg());
97 gs_perfCounter
.freq
.QuadPart
= 0;
100 gs_perfCounter
.init
= true;
104 m_t0
= GetCurrentClockValue();
107 wxLongLong
wxStopWatch::GetClockFreq() const
110 // Under MSW we use the high resolution performance counter timer which has
111 // its own frequency (usually related to the CPU clock speed).
112 if ( gs_perfCounter
.CanBeUsed() )
113 return gs_perfCounter
.freq
.QuadPart
;
116 #ifdef HAVE_GETTIMEOFDAY
117 // With gettimeofday() we can have nominally microsecond precision and
118 // while this is not the case in practice, it's still better than
120 return MICROSECONDS_PER_SECOND
;
121 #else // !HAVE_GETTIMEOFDAY
122 // Currently milliseconds are used everywhere else.
123 return MILLISECONDS_PER_SECOND
;
124 #endif // HAVE_GETTIMEOFDAY/!HAVE_GETTIMEOFDAY
127 void wxStopWatch::Start(long t0
)
129 // Calling Start() makes the stop watch run however many times it was
135 m_t0
-= (wxLongLong(t0
)*GetClockFreq())/MILLISECONDS_PER_SECOND
;
138 wxLongLong
wxStopWatch::GetCurrentClockValue() const
141 if ( gs_perfCounter
.CanBeUsed() )
143 LARGE_INTEGER counter
;
144 ::QueryPerformanceCounter(&counter
);
145 return counter
.QuadPart
;
149 #ifdef HAVE_GETTIMEOFDAY
150 return wxGetUTCTimeUSec();
151 #else // !HAVE_GETTIMEOFDAY
152 return wxGetUTCTimeMillis();
153 #endif // HAVE_GETTIMEOFDAY/!HAVE_GETTIMEOFDAY
156 wxLongLong
wxStopWatch::TimeInMicro() const
158 const wxLongLong
elapsed(m_pauseCount
? m_elapsedBeforePause
159 : GetCurrentClockValue() - m_t0
);
161 return (elapsed
*MICROSECONDS_PER_SECOND
)/GetClockFreq();
164 #endif // wxUSE_STOPWATCH
166 // ----------------------------------------------------------------------------
167 // old timer functions superceded by wxStopWatch
168 // ----------------------------------------------------------------------------
172 static wxLongLong wxStartTime
= 0l;
174 // starts the global timer
177 wxStartTime
= wxGetUTCTimeMillis();
180 // Returns elapsed time in milliseconds
181 long wxGetElapsedTime(bool resetTimer
)
183 wxLongLong oldTime
= wxStartTime
;
184 wxLongLong newTime
= wxGetUTCTimeMillis();
187 wxStartTime
= newTime
;
189 return (newTime
- oldTime
).GetLo();
192 #endif // wxUSE_LONGLONG