Skip to content

Commit

Permalink
Convert MythTimer to use QElapsedTimer instead of QTime.
Browse files Browse the repository at this point in the history
Fixes #11255.

We initially created MythTimer because QTime isn't monotonic
and we wanted a wrapper that assured that time wouldn't march
backward too much. As of Qt 4.7 there is a timer available
which is monotonic on most systems. This converts MythTimer
to use this new timer.

The first version of this new wrapper was written by
Rune Petersen for the efficiency gains this has over
QTime which does an expensive DST conversion internally.
I added back a timer restart in the elapsed() method
since QElapsedTimer doesn't always provide a monotonic
timer, and I implemented the addMSecs() method so this
could be used in all instances where the original
MythTimer was used.
  • Loading branch information
daniel-kristjansson committed Jan 21, 2013
1 parent d493cec commit 440573f
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 19 deletions.
2 changes: 1 addition & 1 deletion mythtv/libs/libmythbase/libmythbase.pro
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ SOURCES += mthread.cpp mthreadpool.cpp
SOURCES += mythsocket.cpp
SOURCES += mythdbcon.cpp mythdb.cpp mythdbparams.cpp oldsettings.cpp
SOURCES += mythobservable.cpp mythevent.cpp httpcomms.cpp mcodecs.cpp
SOURCES += mythdirs.cpp mythsignalingtimer.cpp
SOURCES += mythtimer.cpp mythsignalingtimer.cpp mythdirs.cpp
SOURCES += lcddevice.cpp mythstorage.cpp remotefile.cpp
SOURCES += mythcorecontext.cpp mythsystem.cpp mythlocale.cpp storagegroup.cpp
SOURCES += mythcoreutil.cpp mythdownloadmanager.cpp mythtranslation.cpp
Expand Down
101 changes: 101 additions & 0 deletions mythtv/libs/libmythbase/mythtimer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* Class MythTimer
*
* Copyright (C) Rune Petersen 2012
* Copyright (C) Daniel Kristjansson 2013
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

// MythTV includes
#include "mythtimer.h"

/// starts measuring elapsed time.
void MythTimer::start(void)
{
m_timer.start();
m_offset = 0;
}

/** Returns milliseconds elapsed since last start() or restart()
* and resets the count.
*
* \note If timer had not been started before this is called,
* this returns zero.
*
* \note If addMSecs() has been called and the total offset applied
* is negative then this can return a negative number.
*/
int MythTimer::restart(void)
{
if (m_timer.isValid())
{
int val = static_cast<int>(m_timer.restart() + m_offset);
m_offset = 0;
return val;
}
return start(), 0;
}

/** Stops timer, next call to isRunning() will return false and
* any calls to elapsed() or restart() will return 0 until after
* timer is restarted by a call to start() or restart().
*/
void MythTimer::stop(void)
{
m_timer.invalidate();
}

/** Returns milliseconds elapsed since last start() or restart()
*
* \note If timer had not been started before this is called,
* this returns zero.
*
* \note If addMSecs() has been called and the total offset applied
* is negative then this can return a negative number.
*/
int MythTimer::elapsed(void) const
{
if (!m_timer.isValid())
return 0;

int64_t e = m_timer.elapsed();
if (!m_timer.isMonotonic() && (e > 86300000))
{
const_cast<MythTimer*>(this)->start();
e = 0;
}

return static_cast<int>(e + m_offset);
}

/** Returns true if start() or restart() has been called at least
* once since construction and since any call to stop().
*/
bool MythTimer::isRunning(void) const
{
return m_timer.isValid();
}

/** Adds an offset to the last call to start() or restart().
*
* This offset is removed if start() or restart() is called
* again. The offset may be positive or negative. This
* may be called multiple times to accrete various offsets.
*/
void MythTimer::addMSecs(int ms)
{
m_offset += ms;
}
36 changes: 18 additions & 18 deletions mythtv/libs/libmythbase/mythtimer.h
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
#ifndef MYTHTIMER_H_
#define MYTHTIMER_H_

#include <QTime>
#include <QElapsedTimer>
#include "mythbaseexp.h"

/** A QElapsedTimer based timer to replace use of QTime as a timer.
*
* This class is not thread-safe.
*/

class MBASE_PUBLIC MythTimer
{
public:
MythTimer() : m_running(false) {}

void start() { m_running = true; m_timer.start(); }
int restart() { int ret = elapsed();
m_timer.restart();
return ret;
}
int elapsed() { int ret = m_timer.elapsed();
if (ret > 86300000) { ret = 0; m_timer.restart(); }
return ret;
}
void stop() { m_running = false; }
bool isRunning() const { return m_running; }

void addMSecs(int ms) { m_timer.addMSecs(ms); }
MythTimer() : m_offset(0) { m_timer.invalidate(); }

void start(void);
int restart(void);
void stop(void);

void addMSecs(int ms);

int elapsed(void) const;
bool isRunning(void) const;

private:
QTime m_timer;
bool m_running;
QElapsedTimer m_timer;
int m_offset;
};

#endif
Expand Down

0 comments on commit 440573f

Please sign in to comment.