2011-03-20 18:05:19 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Name: src/common/stopwatch.cpp
|
|
|
|
// Purpose: wxStopWatch and other non-GUI stuff from wx/timer.h
|
|
|
|
// Author:
|
|
|
|
// Original version by Julian Smart
|
|
|
|
// Vadim Zeitlin got rid of all ifdefs (11.12.99)
|
|
|
|
// Sylvain Bougnoux added wxStopWatch class
|
|
|
|
// Guillermo Rodriguez <guille@iies.es> rewrote from scratch (Dic/99)
|
|
|
|
// Modified by:
|
|
|
|
// Created: 20.06.2003 (extracted from common/timercmn.cpp)
|
|
|
|
// Copyright: (c) 1998-2003 wxWidgets Team
|
|
|
|
// Licence: wxWindows licence
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
// declarations
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// headers
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// for compilers that support precompilation, includes "wx.h".
|
|
|
|
#include "wx/wxprec.h"
|
|
|
|
|
|
|
|
#ifdef __BORLANDC__
|
|
|
|
#pragma hdrstop
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "wx/stopwatch.h"
|
|
|
|
|
2012-03-17 18:12:27 -07:00
|
|
|
#if wxUSE_STOPWATCH
|
|
|
|
|
2011-03-20 18:05:19 +00:00
|
|
|
#ifndef WX_PRECOMP
|
2012-03-17 18:12:27 -07:00
|
|
|
#ifdef __WINDOWS__
|
2011-03-20 18:05:19 +00:00
|
|
|
#include "wx/msw/wrapwin.h"
|
|
|
|
#endif
|
|
|
|
#include "wx/log.h"
|
2012-03-17 18:12:27 -07:00
|
|
|
#include "wx/thread.h"
|
2011-03-20 18:05:19 +00:00
|
|
|
#endif //WX_PRECOMP
|
|
|
|
|
2012-03-17 18:12:27 -07:00
|
|
|
// ============================================================================
|
|
|
|
// implementation
|
|
|
|
// ============================================================================
|
|
|
|
|
2011-03-20 18:05:19 +00:00
|
|
|
// ----------------------------------------------------------------------------
|
2012-03-17 18:12:27 -07:00
|
|
|
// wxStopWatch
|
2011-03-20 18:05:19 +00:00
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
2012-03-17 18:12:27 -07:00
|
|
|
namespace
|
|
|
|
{
|
2011-03-20 18:05:19 +00:00
|
|
|
|
2012-03-17 18:12:27 -07:00
|
|
|
#ifdef __WINDOWS__
|
2011-03-20 18:05:19 +00:00
|
|
|
|
2012-03-17 18:12:27 -07:00
|
|
|
struct PerfCounter
|
|
|
|
{
|
|
|
|
PerfCounter()
|
|
|
|
{
|
|
|
|
init = false;
|
|
|
|
}
|
2011-03-20 18:05:19 +00:00
|
|
|
|
2012-03-17 18:12:27 -07:00
|
|
|
wxCRIT_SECT_DECLARE_MEMBER(cs);
|
|
|
|
LARGE_INTEGER freq;
|
|
|
|
bool init;
|
2016-06-26 05:25:29 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// Return the global perf counter state.
|
|
|
|
//
|
|
|
|
// This is wrapped in a function to avoid initialization order problems,
|
|
|
|
// otherwise simply creating a global wxStopWatch variable could crash because
|
|
|
|
// it would be using a (possibly) still uninitialized critical section.
|
|
|
|
PerfCounter& GetPerfCounterState()
|
|
|
|
{
|
|
|
|
static PerfCounter s_perfCounter;
|
|
|
|
|
|
|
|
return s_perfCounter;
|
|
|
|
}
|
2011-03-20 18:05:19 +00:00
|
|
|
|
2012-03-17 18:12:27 -07:00
|
|
|
#endif // __WINDOWS__
|
2011-03-20 18:05:19 +00:00
|
|
|
|
2012-03-17 18:12:27 -07:00
|
|
|
const int MILLISECONDS_PER_SECOND = 1000;
|
|
|
|
const int MICROSECONDS_PER_SECOND = 1000*1000;
|
2011-03-20 18:05:19 +00:00
|
|
|
|
2012-03-17 18:12:27 -07:00
|
|
|
} // anonymous namespace
|
2011-03-20 18:05:19 +00:00
|
|
|
|
2012-03-17 18:12:27 -07:00
|
|
|
void wxStopWatch::DoStart()
|
|
|
|
{
|
|
|
|
#ifdef __WINDOWS__
|
2016-06-26 05:25:29 +00:00
|
|
|
PerfCounter& perfCounter = GetPerfCounterState();
|
|
|
|
if ( !perfCounter.init )
|
2012-03-17 18:12:27 -07:00
|
|
|
{
|
2016-06-26 05:25:29 +00:00
|
|
|
wxCRIT_SECT_LOCKER(lock, perfCounter.cs);
|
|
|
|
::QueryPerformanceFrequency(&perfCounter.freq);
|
2011-03-20 18:05:19 +00:00
|
|
|
|
2016-06-26 05:25:29 +00:00
|
|
|
perfCounter.init = true;
|
2011-03-20 18:05:19 +00:00
|
|
|
}
|
2012-03-17 18:12:27 -07:00
|
|
|
#endif // __WINDOWS__
|
|
|
|
|
|
|
|
m_t0 = GetCurrentClockValue();
|
|
|
|
}
|
|
|
|
|
|
|
|
wxLongLong wxStopWatch::GetClockFreq() const
|
|
|
|
{
|
|
|
|
#ifdef __WINDOWS__
|
|
|
|
// Under MSW we use the high resolution performance counter timer which has
|
|
|
|
// its own frequency (usually related to the CPU clock speed).
|
2016-06-26 05:25:29 +00:00
|
|
|
return GetPerfCounterState().freq.QuadPart;
|
|
|
|
#elif defined(HAVE_GETTIMEOFDAY)
|
2012-03-17 18:12:27 -07:00
|
|
|
// With gettimeofday() we can have nominally microsecond precision and
|
|
|
|
// while this is not the case in practice, it's still better than
|
|
|
|
// millisecond.
|
|
|
|
return MICROSECONDS_PER_SECOND;
|
|
|
|
#else // !HAVE_GETTIMEOFDAY
|
|
|
|
// Currently milliseconds are used everywhere else.
|
|
|
|
return MILLISECONDS_PER_SECOND;
|
2016-06-26 05:25:29 +00:00
|
|
|
#endif // __WINDOWS__/HAVE_GETTIMEOFDAY/else
|
2012-03-17 18:12:27 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void wxStopWatch::Start(long t0)
|
|
|
|
{
|
|
|
|
// Calling Start() makes the stop watch run however many times it was
|
|
|
|
// paused before.
|
2011-03-20 18:05:19 +00:00
|
|
|
m_pauseCount = 0;
|
2012-03-17 18:12:27 -07:00
|
|
|
|
|
|
|
DoStart();
|
|
|
|
|
|
|
|
m_t0 -= (wxLongLong(t0)*GetClockFreq())/MILLISECONDS_PER_SECOND;
|
2011-03-20 18:05:19 +00:00
|
|
|
}
|
|
|
|
|
2012-03-17 18:12:27 -07:00
|
|
|
wxLongLong wxStopWatch::GetCurrentClockValue() const
|
2011-03-20 18:05:19 +00:00
|
|
|
{
|
2012-03-17 18:12:27 -07:00
|
|
|
#ifdef __WINDOWS__
|
2016-06-26 05:25:29 +00:00
|
|
|
LARGE_INTEGER counter;
|
|
|
|
::QueryPerformanceCounter(&counter);
|
|
|
|
return counter.QuadPart;
|
|
|
|
#elif defined(HAVE_GETTIMEOFDAY)
|
2012-03-17 18:12:27 -07:00
|
|
|
return wxGetUTCTimeUSec();
|
|
|
|
#else // !HAVE_GETTIMEOFDAY
|
|
|
|
return wxGetUTCTimeMillis();
|
2016-06-26 05:25:29 +00:00
|
|
|
#endif // __WINDOWS__/HAVE_GETTIMEOFDAY/else
|
2011-03-20 18:05:19 +00:00
|
|
|
}
|
|
|
|
|
2012-03-17 18:12:27 -07:00
|
|
|
wxLongLong wxStopWatch::TimeInMicro() const
|
2011-03-20 18:05:19 +00:00
|
|
|
{
|
2012-03-17 18:12:27 -07:00
|
|
|
const wxLongLong elapsed(m_pauseCount ? m_elapsedBeforePause
|
|
|
|
: GetCurrentClockValue() - m_t0);
|
|
|
|
|
|
|
|
return (elapsed*MICROSECONDS_PER_SECOND)/GetClockFreq();
|
2011-03-20 18:05:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif // wxUSE_STOPWATCH
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// old timer functions superceded by wxStopWatch
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#if wxUSE_LONGLONG
|
|
|
|
|
|
|
|
static wxLongLong wxStartTime = 0l;
|
|
|
|
|
|
|
|
// starts the global timer
|
|
|
|
void wxStartTimer()
|
|
|
|
{
|
2012-03-17 18:12:27 -07:00
|
|
|
wxStartTime = wxGetUTCTimeMillis();
|
2011-03-20 18:05:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Returns elapsed time in milliseconds
|
|
|
|
long wxGetElapsedTime(bool resetTimer)
|
|
|
|
{
|
|
|
|
wxLongLong oldTime = wxStartTime;
|
2012-03-17 18:12:27 -07:00
|
|
|
wxLongLong newTime = wxGetUTCTimeMillis();
|
2011-03-20 18:05:19 +00:00
|
|
|
|
|
|
|
if ( resetTimer )
|
|
|
|
wxStartTime = newTime;
|
|
|
|
|
|
|
|
return (newTime - oldTime).GetLo();
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // wxUSE_LONGLONG
|