From fa673dddb5bb7a8c851bacea6727b3d68d543456 Mon Sep 17 00:00:00 2001 From: Andrew Christian Date: Fri, 9 Mar 2012 17:09:36 +0100 Subject: Revert "Cpu polling for prelaunch" This reverts commit 9181b78247567f1c21b9f85a9eb149133425941a Inappropriate implementation. Having two PrelaunchProcessBackendFactories will result in extraneous polling. Autotests now only succeed if you run on a machine with low CPU load. Autotests on Macintosh platform simply fail. Change-Id: I3e7061e8fbf89bd3f6a2907a406ca1fbfbc88e3c Reviewed-by: Chris Craig --- src/core/core-lib.pri | 6 +- src/core/cpuload.cpp | 79 ---------- src/core/cpuload.h | 30 ---- src/core/prelaunchprocessbackendfactory.cpp | 222 +++++++--------------------- src/core/prelaunchprocessbackendfactory.h | 13 +- 5 files changed, 60 insertions(+), 290 deletions(-) delete mode 100644 src/core/cpuload.cpp delete mode 100644 src/core/cpuload.h diff --git a/src/core/core-lib.pri b/src/core/core-lib.pri index a72388e..42e7f69 100644 --- a/src/core/core-lib.pri +++ b/src/core/core-lib.pri @@ -37,8 +37,7 @@ PUBLIC_HEADERS += \ HEADERS += \ $$PUBLIC_HEADERS \ - $$PWD/unixsandboxprocess.h \ - $$PWD/cpuload.h + $$PWD/unixsandboxprocess.h SOURCES += \ $$PWD/process.cpp \ @@ -69,5 +68,4 @@ SOURCES += \ $$PWD/socketlauncher.cpp \ $$PWD/procutils.cpp \ $$PWD/forklauncher.cpp \ - $$PWD/prefork.cpp \ - $$PWD/cpuload.cpp + $$PWD/prefork.cpp diff --git a/src/core/cpuload.cpp b/src/core/cpuload.cpp deleted file mode 100644 index 5640066..0000000 --- a/src/core/cpuload.cpp +++ /dev/null @@ -1,79 +0,0 @@ -#include "cpuload.h" -#include -#include - -/*! - * \class CPULoad - * \brief CPULoad calculates the current CPU load. - */ -int CPULoad::m_forcedLoad = -1; - -//! Constructor -CPULoad::CPULoad() : - m_load(-1) -{} - -/*! - * Reads /proc/stat file - * ToDo: use sscanf if it faster - */ -CPULoad::TimeList CPULoad::readTimeList() -{ -#ifdef Q_OS_LINUX - QFile fin(QStringLiteral("/proc/stat")); - if (fin.open(QIODevice::ReadOnly | QIODevice::Text)) - return fin.readLine().split(' '); -#endif - return TimeList(); -} - -/*! - * Initialize. Currently only sets the value to -1. - */ -void CPULoad::init() -{ - m_load = -1; -} - -/*! - * Update the value. - * This must be called periodically (e.g. 1 - 5 seconds) in order to update the measurement. - * The data is obtained from first line of /proc/stat file - */ -void CPULoad::update() -{ - // Read timing from the file - TimeList v(readTimeList()); - - if (m_timeList.length()) { - // Take delta with the previous timing - int sum = 0; - int idle = 0; - int iowait = 0; - int cpu = 0; - - for (int i = 2; i < 7 && i < v.length(); i++) - sum += v.at(i).toInt() - m_timeList.at(i).toInt(); - - idle = v.at(5).toInt() - m_timeList.at(5).toInt(); - iowait = v.at(6).toInt() - m_timeList.at(6).toInt(); - cpu = sum - idle - iowait; - - // Calculate load - m_load = 100.0 - (100.0 * idle / sum); - } else { - m_load = -1; - } - - // Store the current timing - m_timeList = v; -} - -/*! - * Returns The current value of the load in the range of 0 to 100 - * or -1 if nothing measured. - */ -int CPULoad::cpuLoad() const -{ - return m_forcedLoad > -1 ? m_forcedLoad : m_load; -} diff --git a/src/core/cpuload.h b/src/core/cpuload.h deleted file mode 100644 index 3ec4d03..0000000 --- a/src/core/cpuload.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef CPULOAD_H -#define CPULOAD_H - -#include -#include - -class CPULoad -{ -public: - - CPULoad(); - - void init(); - void update(); - int cpuLoad() const; - -private: - typedef QList TimeList; - - CPULoad(const CPULoad &); - CPULoad & operator= (const CPULoad &); - TimeList readTimeList(); - -private: - TimeList m_timeList; - int m_load; - static int m_forcedLoad; -}; - -#endif // CPULOAD_H diff --git a/src/core/prelaunchprocessbackendfactory.cpp b/src/core/prelaunchprocessbackendfactory.cpp index cc47985..f7eb263 100644 --- a/src/core/prelaunchprocessbackendfactory.cpp +++ b/src/core/prelaunchprocessbackendfactory.cpp @@ -42,21 +42,10 @@ #include "prelaunchprocessbackendfactory.h" #include "prelaunchprocessbackend.h" #include "processinfo.h" -#include "cpuload.h" QT_BEGIN_NAMESPACE_PROCESSMANAGER -const int kPrelaunchCpuPollingInterval = 1000; -const int kPrelaunchDefaultTimeout = 20000; -const int kPrelaunchCpuThreshold = 50; -const int kPrelaunchStablilityInterval = 2; - -#ifdef Q_OS_LINUX - const bool kCpuPollingEnabled = true; -#else - const bool kCpuPollingEnabled = false; -#endif - +const int kPrelaunchTimerInterval = 1000; /*! \class PrelaunchProcessBackendFactory @@ -81,29 +70,20 @@ PrelaunchProcessBackendFactory::PrelaunchProcessBackendFactory(QObject *parent) , m_prelaunch(NULL) , m_info(NULL) , m_prelaunchEnabled(true) - , m_pollingCpu(false) - , m_prelaunchDelay(kPrelaunchDefaultTimeout) -#ifdef Q_OS_LINUX - , m_cpuLoad(new CPULoad) -#else - , m_cpuLoad(NULL) -#endif { + connect(&m_timer, SIGNAL(timeout()), SLOT(timeout())); + m_timer.setSingleShot(true); + m_timer.setInterval(kPrelaunchTimerInterval); } /*! - * Destroy this and child objects. - */ + Destroy this and child objects. +*/ PrelaunchProcessBackendFactory::~PrelaunchProcessBackendFactory() { - delete m_cpuLoad; } -/*! - * Returns true if corresponding prelaunch can be created - */ - bool PrelaunchProcessBackendFactory::canCreate(const ProcessInfo &info) const { if (!m_info) @@ -113,8 +93,8 @@ bool PrelaunchProcessBackendFactory::canCreate(const ProcessInfo &info) const } /*! - * Construct a PrelaunchProcessBackend from a ProcessInfo \a info record with \a parent. - */ + Construct a PrelaunchProcessBackend from a ProcessInfo \a info record with \a parent. +*/ ProcessBackend * PrelaunchProcessBackendFactory::create(const ProcessInfo &info, QObject *parent) { @@ -125,7 +105,7 @@ ProcessBackend * PrelaunchProcessBackendFactory::create(const ProcessInfo &info, if (hasPrelaunchedProcess()) { // qDebug() << "Using existing prelaunch"; m_prelaunch = NULL; - prelaunchWhenPossible(); + startPrelaunchTimer(); prelaunch->setInfo(info); prelaunch->setParent(parent); prelaunch->disconnect(this); @@ -139,7 +119,7 @@ ProcessBackend * PrelaunchProcessBackendFactory::create(const ProcessInfo &info, } /*! - * If there is a prelaunched process running, it will be return here. + If there is a prelaunched process running, it will be return here. */ QList PrelaunchProcessBackendFactory::internalProcesses() @@ -150,103 +130,93 @@ QList PrelaunchProcessBackendFactory::internalProcesses() return list; } -/*! - * Returns ProcessInfo object - */ - ProcessInfo *PrelaunchProcessBackendFactory::processInfo() const { return m_info; } /*! - * Return the current launch interval in milliseconds. + Return the current launch interval in milliseconds */ int PrelaunchProcessBackendFactory::launchInterval() const { - return m_prelaunchDelay; + return m_timer.interval(); } /*! - * Set the current launch interval to \a interval milliseconds. - * If the timer is ticking, the new value will affect the next round. - */ + Set the current launch interval to \a interval milliseconds +*/ void PrelaunchProcessBackendFactory::setLaunchInterval(int interval) { - if (m_prelaunchDelay != interval) { - m_prelaunchDelay = interval; + if (m_timer.interval() != interval) { + bool active = m_timer.isActive(); + m_timer.stop(); + m_timer.setInterval(interval); + if (active) + startPrelaunchTimer(); emit launchIntervalChanged(); } } /*! - * Returns whether prelaunching is enabled for this factory. - */ - + Returns whether prelaunching is enabled for this factory. +*/ bool PrelaunchProcessBackendFactory::prelaunchEnabled() const { return m_prelaunchEnabled; } -/*! - * Enables and disables prelaunch - */ - void PrelaunchProcessBackendFactory::setPrelaunchEnabled(bool value) { if (m_prelaunchEnabled != value) { m_prelaunchEnabled = value; - - if (m_prelaunchEnabled) { - prelaunchWhenPossible(); + if (!m_prelaunchEnabled) { + m_timer.stop(); } else { - disablePrelaunch(); + startPrelaunchTimer(); } emit prelaunchEnabledChanged(); } } /*! - * Returns whether there is a prelaunched process which is ready to be consumed. - */ - + Returns whether there is a prelaunched process which is ready to be consumed. +*/ bool PrelaunchProcessBackendFactory::hasPrelaunchedProcess() const { return (m_prelaunch && m_prelaunch->isReady()); } /*! - * Under memory restriction, terminate the prelaunch process. - */ - + Under memory restriction, terminate the prelaunch process. +*/ void PrelaunchProcessBackendFactory::handleMemoryRestrictionChange() { if (m_memoryRestricted) { - setPrelaunchEnabled(false); + m_timer.stop(); if (m_prelaunch) { delete m_prelaunch; // This will kill the child process as well m_prelaunch = NULL; } } else { Q_ASSERT(m_prelaunch == NULL); - setPrelaunchEnabled(true); + startPrelaunchTimer(); } } /*! - * Returns the prelaunched process backend, or null if none is created. + Returns the prelaunched process backend, or null if none is created. */ - PrelaunchProcessBackend *PrelaunchProcessBackendFactory::prelaunchProcessBackend() const { return m_prelaunch; } /*! - * Launch a new prelaunched process backend. - * In the future, it would be useful if the launch didn't require a timeout. + Launch a new prelaunched process backend. + In the future, it would be useful if the launch didn't require a timeout. */ void PrelaunchProcessBackendFactory::timeout() @@ -265,8 +235,8 @@ void PrelaunchProcessBackendFactory::timeout() } /*! - * Handle a surprise termination condition - the prelaunched process died - * unexpectedly. + Handle a surprise termination condition - the prelaunched process died + unexpectedly. */ void PrelaunchProcessBackendFactory::prelaunchFinished(int exitCode, QProcess::ExitStatus status) @@ -276,11 +246,11 @@ void PrelaunchProcessBackendFactory::prelaunchFinished(int exitCode, QProcess::E m_prelaunch->deleteLater(); m_prelaunch = NULL; } - prelaunchWhenPossible(); + startPrelaunchTimer(); } /*! - * Handle surprise error conditions on the prelaunched process. + Handle surprise error conditions on the prelaunched process. */ void PrelaunchProcessBackendFactory::prelaunchError(QProcess::ProcessError err) @@ -293,19 +263,28 @@ void PrelaunchProcessBackendFactory::prelaunchError(QProcess::ProcessError err) if (err == QProcess::FailedToStart) { qWarning() << Q_FUNC_INFO << "disabling prelaunch because of process errors"; - setPrelaunchEnabled(false); + m_prelaunchEnabled = false; + } else { // ### TODO: This isn't optimal - prelaunchWhenPossible(); + startPrelaunchTimer(); } } /*! - * Sets the ProcessInfo that is used to determine the prelaunched runtime to \a processInfo. - * An internal copy is made of the \a processInfo object. - */ + Starts the prelaunch timer only if prelaunching is enabled. +*/ +void PrelaunchProcessBackendFactory::startPrelaunchTimer() +{ + if (m_prelaunchEnabled) + m_timer.start(); +} +/*! + Sets the ProcessInfo that is used to determine the prelaunched runtime to \a processInfo. + An internal copy is made of the \a processInfo object. + */ void PrelaunchProcessBackendFactory::setProcessInfo(ProcessInfo *processInfo) { if (m_info != processInfo) { @@ -317,113 +296,26 @@ void PrelaunchProcessBackendFactory::setProcessInfo(ProcessInfo *processInfo) if (processInfo) { m_info = new ProcessInfo(*processInfo); m_info->setParent(this); - prelaunchWhenPossible(); + startPrelaunchTimer(); } else { - disablePrelaunch(); + m_timer.stop(); } emit processInfoChanged(); } } /*! - * Sets the ProcessInfo that is used to determine the prelaunched runtime to \a processInfo. + Sets the ProcessInfo that is used to determine the prelaunched runtime to \a processInfo. */ - void PrelaunchProcessBackendFactory::setProcessInfo(ProcessInfo& processInfo) { setProcessInfo(&processInfo); } -/*! - * Prelaunch runtime when cpu load is low or by timer - */ - -void PrelaunchProcessBackendFactory::prelaunchWhenPossible() -{ - if (m_prelaunchEnabled) { - if (kCpuPollingEnabled) { - m_accu = 0; - m_waitTime = 0; - enableCPULoadPolling(true); - // qDebug() << "(cpu) start cpu polling, max waiting time " << (m_prelaunchDelay/1000) << " seconds"; - } else { - m_timer.singleShot(m_prelaunchDelay, this, SLOT(timeout())); - } - } -} - -/*! - * disable prelaunch process and stops timers - */ - -void PrelaunchProcessBackendFactory::disablePrelaunch() -{ - if (kCpuPollingEnabled) { - enableCPULoadPolling(false); - } else { - m_timer.stop(); - } -} - -/*! - * Update cpu load information, triggers prelaunch start - */ - -void PrelaunchProcessBackendFactory::checkCPULoadUpdated() -{ - Q_ASSERT(kCpuPollingEnabled); - - m_cpuLoad->update(); - m_waitTime += kPrelaunchCpuPollingInterval; - int curLoad = m_cpuLoad->cpuLoad(); - - if (m_prelaunchDelay != 0 && m_waitTime >= (m_prelaunchDelay)) { - // qDebug() << "(cpu) can't wait low cpu load any longer"; - m_accu = kPrelaunchStablilityInterval; - } else { - if (curLoad < kPrelaunchCpuThreshold) - m_accu++; - else - m_accu = 0; - } - - // qDebug() << "(cpu) load is " << curLoad << " wait time " << m_waitTime/1000 << " seconds"; - - if (m_accu >= kPrelaunchStablilityInterval) { - // qDebug() << "(cpu) stop cpu polling, start runtimes prelaunching"; - enableCPULoadPolling(false); - timeout(); - } -} - -/*! - * Enables or disables cpu load polling - */ - -void PrelaunchProcessBackendFactory::enableCPULoadPolling(bool enable) -{ - Q_ASSERT(kCpuPollingEnabled); - - if (enable) { - if (m_pollingCpu) - return; - - connect(&m_timer, SIGNAL(timeout()), this, SLOT(checkCPULoadUpdated())); - m_cpuLoad->init(); - m_timer.setInterval(kPrelaunchCpuPollingInterval); - m_timer.start(); - m_pollingCpu = true; - - } else { - disconnect(&m_timer, SIGNAL(timeout()), this, SLOT(checkCPULoadUpdated())); - m_timer.stop(); - m_pollingCpu = false; - } -} /*! - * \fn void PrelaunchProcessBackendFactory::launchIntervalChanged() - * This signal is emitted when the launchInterval is changed. + \fn void PrelaunchProcessBackendFactory::launchIntervalChanged() + This signal is emitted when the launchInterval is changed. */ #include "moc_prelaunchprocessbackendfactory.cpp" diff --git a/src/core/prelaunchprocessbackendfactory.h b/src/core/prelaunchprocessbackendfactory.h index 2422a60..66c9923 100644 --- a/src/core/prelaunchprocessbackendfactory.h +++ b/src/core/prelaunchprocessbackendfactory.h @@ -44,8 +44,6 @@ #include "processmanager-global.h" #include -class CPULoad; - QT_BEGIN_NAMESPACE_PROCESSMANAGER class ProcessInfo; @@ -93,24 +91,15 @@ private slots: void timeout(); void prelaunchFinished(int, QProcess::ExitStatus); void prelaunchError(QProcess::ProcessError); - void checkCPULoadUpdated(); private: void startPrelaunchTimer(); - void enableCPULoadPolling(bool enable); - void prelaunchWhenPossible(); - void disablePrelaunch(); private: PrelaunchProcessBackend *m_prelaunch; ProcessInfo *m_info; - bool m_prelaunchEnabled; QTimer m_timer; - bool m_pollingCpu; - int m_accu; - int m_waitTime; - int m_prelaunchDelay; - CPULoad *m_cpuLoad; + bool m_prelaunchEnabled; }; QT_END_NAMESPACE_PROCESSMANAGER -- cgit v1.2.3