File indexing completed on 2024-05-12 15:50:10

0001 #ifdef Q_OS_UNIX
0002 #include <stdlib.h>
0003 #endif
0004 
0005 #include <QDebug>
0006 #include <QThread>
0007 #include <QTimer>
0008 
0009 #include "AverageLoadManager.h"
0010 
0011 AverageLoadManager::AverageLoadManager(QObject *parent)
0012     : QObject(parent)
0013     , m_timer(new QTimer(this))
0014     , m_min()
0015     , m_max(0)
0016 {
0017     m_timer->setSingleShot(false);
0018     m_timer->setInterval(500);
0019     connect(m_timer, SIGNAL(timeout()), SLOT(update()));
0020 }
0021 
0022 void AverageLoadManager::activate(bool enabled)
0023 {
0024     if (available()) {
0025         if (enabled) {
0026             m_timer->start();
0027         } else {
0028             m_timer->stop();
0029         }
0030     }
0031 }
0032 
0033 bool AverageLoadManager::available() const
0034 {
0035 #if defined(Q_OS_UNIX) && !defined(Q_OS_ANDROID)
0036     return true;
0037 #else
0038     return false;
0039 #endif
0040 }
0041 
0042 QPair<int, int> AverageLoadManager::workersRange() const
0043 {
0044     return qMakePair(m_min, m_max);
0045 }
0046 
0047 void AverageLoadManager::update()
0048 {
0049 #if defined(Q_OS_UNIX) && !defined(Q_OS_ANDROID)
0050     double averages[3];
0051     if (getloadavg(averages, 3) == -1) {
0052         return;
0053     }
0054 
0055     const float processors = QThread::idealThreadCount();
0056     const float relativeLoadPerProcessor = averages[0] / processors; // relative system load
0057     const float targetedBaseLoad = 0.7f;
0058 
0059     const float x = relativeLoadPerProcessor / targetedBaseLoad;
0060     auto const linearLoadFunction = [](float x) {
0061         return -x + 2.0f;
0062     };
0063     // auto const reciprocalLoadFunction = [](float x) { return 1.0f / (0.5*x+0.5); };
0064 
0065     m_min = qRound(qMax(1.0f, linearLoadFunction(1000 * processors)));
0066     m_max = qRound(qMin(2 * processors, processors * linearLoadFunction(0.0)));
0067     const float y = linearLoadFunction(x);
0068     const int threads = qBound(m_min, qRound(processors * y), m_max);
0069     qDebug() << threads << y << x << relativeLoadPerProcessor << averages[0] << processors;
0070     Q_EMIT recommendedWorkerCount(threads);
0071 #endif
0072 }
0073 
0074 #include "moc_AverageLoadManager.cpp"