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 | |
11 | AverageLoadManager::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 | |
22 | void 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 | |
33 | bool 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 | |
42 | QPair<int, int> AverageLoadManager::workersRange() const |
43 | { |
44 | return qMakePair(value1: m_min, value2: m_max); |
45 | } |
46 | |
47 | void 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 | |