1#ifdef Q_OS_UNIX
2#include <stdlib.h>
3#endif
4
5#include <QDebug>
6#include <QThread>
7#include <QTimer>
8
9#include "AverageLoadManager.h"
10
11AverageLoadManager::AverageLoadManager(QObject *parent)
12 : QObject(parent)
13 , m_timer(new QTimer(this))
14 , m_min()
15 , m_max(0)
16{
17 m_timer->setSingleShot(false);
18 m_timer->setInterval(500);
19 connect(asender: m_timer, SIGNAL(timeout()), SLOT(update()));
20}
21
22void AverageLoadManager::activate(bool enabled)
23{
24 if (available()) {
25 if (enabled) {
26 m_timer->start();
27 } else {
28 m_timer->stop();
29 }
30 }
31}
32
33bool AverageLoadManager::available() const
34{
35#if defined(Q_OS_UNIX) && !defined(Q_OS_ANDROID)
36 return true;
37#else
38 return false;
39#endif
40}
41
42QPair<int, int> AverageLoadManager::workersRange() const
43{
44 return qMakePair(value1: m_min, value2: m_max);
45}
46
47void AverageLoadManager::update()
48{
49#if defined(Q_OS_UNIX) && !defined(Q_OS_ANDROID)
50 double averages[3];
51 if (getloadavg(loadavg: averages, nelem: 3) == -1) {
52 return;
53 }
54
55 const float processors = QThread::idealThreadCount();
56 const float relativeLoadPerProcessor = averages[0] / processors; // relative system load
57 const float targetedBaseLoad = 0.7f;
58
59 const float x = relativeLoadPerProcessor / targetedBaseLoad;
60 auto const linearLoadFunction = [](float x) {
61 return -x + 2.0f;
62 };
63 // auto const reciprocalLoadFunction = [](float x) { return 1.0f / (0.5*x+0.5); };
64
65 m_min = qRound(f: qMax(a: 1.0f, b: linearLoadFunction(1000 * processors)));
66 m_max = qRound(f: qMin(a: 2 * processors, b: processors * linearLoadFunction(0.0)));
67 const float y = linearLoadFunction(x);
68 const int threads = qBound(min: m_min, val: qRound(f: processors * y), max: m_max);
69 qDebug() << threads << y << x << relativeLoadPerProcessor << averages[0] << processors;
70 Q_EMIT recommendedWorkerCount(threads);
71#endif
72}
73
74#include "moc_AverageLoadManager.cpp"
75

source code of threadweaver/examples/ThumbNailer/AverageLoadManager.cpp