/*
Copyright 2006-2026 The QElectroTech Team
This file is part of QElectroTech.
QElectroTech 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.
QElectroTech 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 QElectroTech. If not, see .
*/
#include "eventloopwatchdog.h"
#include
#include
EventLoopWatchdog::EventLoopWatchdog(QObject *parent) :
QObject(parent)
{
m_disabled = QProcessEnvironment::systemEnvironment()
.value(QStringLiteral("QET_WATCHDOG_DISABLE")) == QStringLiteral("1");
// Precise, not the default Coarse: Coarse explicitly trades timing
// accuracy for power/scheduling efficiency (platform-dependent, but
// commonly +/- a double-digit percentage), which would show up as
// noise indistinguishable from a real stall in exactly the
// measurement this class exists to make trustworthy.
m_timer.setTimerType(Qt::PreciseTimer);
connect(&m_timer, &QTimer::timeout, this, &EventLoopWatchdog::tick);
}
void EventLoopWatchdog::start()
{
if (m_disabled)
return;
m_elapsed.start();
m_timer.start(kTickIntervalMs);
}
void EventLoopWatchdog::tick()
{
// restart() returns the elapsed time and resets the clock in one
// call, so this tick's own cost is never counted against the next.
const qint64 actual_ms = m_elapsed.restart();
if (actual_ms > kStallThresholdMs) {
qWarning() << "EventLoopWatchdog: main thread stalled for"
<< actual_ms << "ms (expected a tick every"
<< kTickIntervalMs << "ms)";
}
}