add thread priority option (using QThread)

This commit is contained in:
WarmUpTill 2020-06-06 15:14:08 +02:00
parent 7fef29dafb
commit f03fca85aa
7 changed files with 101 additions and 36 deletions

View File

@ -348,7 +348,7 @@
<item> <item>
<widget class="QLabel" name="label_56"> <widget class="QLabel" name="label_56">
<property name="text"> <property name="text">
<string>Use thread priority (experimental)</string> <string>Use thread priority</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -368,6 +368,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QLabel" name="label_57">
<property name="text">
<string>(raising the priority higher than &quot;Normal&quot; is usually not recommended)</string>
</property>
</widget>
</item>
<item> <item>
<spacer name="horizontalSpacer_41"> <spacer name="horizontalSpacer_41">
<property name="orientation"> <property name="orientation">

View File

@ -353,7 +353,7 @@ SceneSwitcher::SceneSwitcher(QWidget *parent)
ui->readPathLineEdit->setDisabled(true); ui->readPathLineEdit->setDisabled(true);
} }
if (switcher->th.joinable()) if (switcher->th && switcher->th->isRunning())
SetStarted(); SetStarted();
else else
SetStopped(); SetStopped();
@ -400,8 +400,17 @@ SceneSwitcher::SceneSwitcher(QWidget *parent)
item->setData(Qt::UserRole, text); item->setData(Qt::UserRole, text);
} }
for (std::string p : switcher->threadPrioritiesNamesOrderdByPrio) { for (int i = 0; i < switcher->threadPriorities.size(); ++i) {
ui->threadPriority->addItem(p.c_str()); ui->threadPriority->addItem(
switcher->threadPriorities[i].name.c_str());
ui->threadPriority->setItemData(
i, switcher->threadPriorities[i].description.c_str(),
Qt::ToolTipRole);
if (switcher->threadPriority ==
switcher->threadPriorities[i].value) {
ui->threadPriority->setCurrentText(
switcher->threadPriorities[i].name.c_str());
}
} }
} }
@ -882,6 +891,9 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
obs_data_set_int(obj, "priority7", obs_data_set_int(obj, "priority7",
switcher->functionNamesByPriority[7]); switcher->functionNamesByPriority[7]);
obs_data_set_int(obj, "threadPriority",
switcher->threadPriority);
obs_data_set_obj(save_data, "advanced-scene-switcher", obj); obs_data_set_obj(save_data, "advanced-scene-switcher", obj);
obs_data_array_release(array); obs_data_array_release(array);
@ -1362,6 +1374,11 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
(DEFAULT_PRIORITY_7); (DEFAULT_PRIORITY_7);
} }
obs_data_set_default_int(obj, "threadPriority",
QThread::NormalPriority);
switcher->threadPriority =
obs_data_get_int(obj, "threadPriority");
obs_data_array_release(array); obs_data_array_release(array);
obs_data_array_release(screenRegionArray); obs_data_array_release(screenRegionArray);
obs_data_array_release(pauseScenesArray); obs_data_array_release(pauseScenesArray);
@ -1544,19 +1561,21 @@ bool SwitcherData::sceneChangedDuringWait()
void SwitcherData::Start() void SwitcherData::Start()
{ {
if (!th.joinable()) { if (!(th && th->isRunning())) {
stop = false; stop = false;
switcher->th = thread([]() { switcher->Thread(); }); switcher->th = QThread::create([]() { switcher->Thread(); });
switcher->th->start((QThread::Priority)switcher->threadPriority);
} }
} }
void SwitcherData::Stop() void SwitcherData::Stop()
{ {
if (th.joinable()) { if (th && th->isRunning()) {
switcher->stop = true; switcher->stop = true;
transitionCv.notify_one(); transitionCv.notify_one();
cv.notify_one(); cv.notify_one();
th.join(); th->wait();
} }
} }

View File

@ -89,7 +89,7 @@ void SceneSwitcher::SetStopped()
void SceneSwitcher::on_toggleStartButton_clicked() void SceneSwitcher::on_toggleStartButton_clicked()
{ {
if (switcher->th.joinable()) if (switcher->th && switcher->th->isRunning())
{ {
switcher->Stop(); switcher->Stop();
SetStopped(); SetStopped();

View File

@ -130,6 +130,7 @@ public slots:
void on_priorityUp_clicked(); void on_priorityUp_clicked();
void on_priorityDown_clicked(); void on_priorityDown_clicked();
void on_threadPriority_currentTextChanged(const QString &text);
void updateScreenRegionCursorPos(); void updateScreenRegionCursorPos();

View File

@ -3,7 +3,6 @@
#include <chrono> #include <chrono>
#include <string> #include <string>
#include <vector> #include <vector>
#include <thread>
#include <regex> #include <regex>
#include <mutex> #include <mutex>
#include <fstream> #include <fstream>
@ -256,7 +255,7 @@ typedef enum { NO_SWITCH = 0, SWITCH = 1, RANDOM_SWITCH = 2 } NoMatch;
* SwitcherData * SwitcherData
********************************************************************************/ ********************************************************************************/
struct SwitcherData { struct SwitcherData {
thread th; QThread* th = nullptr;
condition_variable cv; condition_variable cv;
mutex m; mutex m;
bool transitionActive = false; bool transitionActive = false;
@ -311,18 +310,33 @@ struct SwitcherData {
DEFAULT_PRIORITY_3, DEFAULT_PRIORITY_4, DEFAULT_PRIORITY_5, DEFAULT_PRIORITY_3, DEFAULT_PRIORITY_4, DEFAULT_PRIORITY_5,
DEFAULT_PRIORITY_6, DEFAULT_PRIORITY_7}; DEFAULT_PRIORITY_6, DEFAULT_PRIORITY_7};
std::vector<std::string> threadPrioritiesNamesOrderdByPrio{ struct ThreadPrio {
"Lowest", "Low", "Normal", "High", "Highest", "Time critical", std::string name;
std::string description;
uint32_t value;
}; };
std::map<std::string, int> threadPriorities = {
{"Lowest", QThread::LowestPriority}, std::vector<ThreadPrio> threadPriorities{
{"Low", QThread::LowPriority}, {"Idle",
{"Normal", QThread::NormalPriority}, "scheduled only when no other threads are running (lowest CPU load)",
{"High", QThread::HighPriority}, QThread::IdlePriority},
{"Highest", QThread::HighestPriority}, {"Lowest", "scheduled less often than LowPriority",
{"Time critical", QThread::TimeCriticalPriority}, QThread::LowestPriority},
{"Low", "scheduled less often than NormalPriority",
QThread::LowPriority},
{"Normal", "the default priority of the operating system",
QThread::NormalPriority},
{"High", "scheduled more often than NormalPriority",
QThread::HighPriority},
{"Highest", "scheduled more often than HighPriority",
QThread::HighestPriority},
{"Time critical",
"scheduled as often as possible (highest CPU load)",
QThread::TimeCriticalPriority},
}; };
uint32_t threadPriority = QThread::NormalPriority;
void Thread(); void Thread();
void Start(); void Start();
void Stop(); void Stop();

View File

@ -8,7 +8,7 @@ void startHotkeyFunc(void* data, obs_hotkey_id id, obs_hotkey_t* hotkey, bool pr
if (pressed) if (pressed)
{ {
if (!switcher->th.joinable()) if (!(switcher->th && switcher->th->isRunning()))
switcher->Start(); switcher->Start();
} }
@ -43,7 +43,7 @@ void stopHotkeyFunc(void* data, obs_hotkey_id id, obs_hotkey_t* hotkey, bool pre
if (pressed) if (pressed)
{ {
if (switcher->th.joinable()) if (switcher->th && switcher->th->isRunning())
switcher->Stop(); switcher->Stop();
} }
@ -78,7 +78,7 @@ void startStopToggleHotkeyFunc(void* data, obs_hotkey_id id, obs_hotkey_t* hotke
if (pressed) if (pressed)
{ {
if (switcher->th.joinable()) if (switcher->th && switcher->th->isRunning())
switcher->Stop(); switcher->Stop();
else else
switcher->Start(); switcher->Start();

View File

@ -1,44 +1,68 @@
#include <algorithm> #include <algorithm>
#include "headers/advanced-scene-switcher.hpp" #include "headers/advanced-scene-switcher.hpp"
void SceneSwitcher::on_threadPriority_currentTextChanged(const QString &text)
{
if (loading || ui->threadPriority->count() != switcher->threadPriorities.size())
return;
lock_guard<mutex> lock(switcher->m);
for (auto p : switcher->threadPriorities) {
if (p.name == text.toUtf8()
.constData()) {
switcher->threadPriority = p.value;
break;
}
}
}
void SceneSwitcher::on_priorityUp_clicked() void SceneSwitcher::on_priorityUp_clicked()
{ {
int currentIndex = ui->priorityList->currentRow(); int currentIndex = ui->priorityList->currentRow();
if (currentIndex != -1 && currentIndex != 0) if (currentIndex != -1 && currentIndex != 0) {
{ ui->priorityList->insertItem(
ui->priorityList->insertItem(currentIndex - 1 ,ui->priorityList->takeItem(currentIndex)); currentIndex - 1,
ui->priorityList->setCurrentRow(currentIndex -1); ui->priorityList->takeItem(currentIndex));
ui->priorityList->setCurrentRow(currentIndex - 1);
lock_guard<mutex> lock(switcher->m); lock_guard<mutex> lock(switcher->m);
iter_swap(switcher->functionNamesByPriority.begin() + currentIndex, switcher->functionNamesByPriority.begin() + currentIndex - 1); iter_swap(switcher->functionNamesByPriority.begin() +
currentIndex,
switcher->functionNamesByPriority.begin() +
currentIndex - 1);
} }
} }
void SceneSwitcher::on_priorityDown_clicked() void SceneSwitcher::on_priorityDown_clicked()
{ {
int currentIndex = ui->priorityList->currentRow(); int currentIndex = ui->priorityList->currentRow();
if (currentIndex != -1 && currentIndex != ui->priorityList->count() - 1) if (currentIndex != -1 &&
{ currentIndex != ui->priorityList->count() - 1) {
ui->priorityList->insertItem(currentIndex + 1, ui->priorityList->takeItem(currentIndex)); ui->priorityList->insertItem(
currentIndex + 1,
ui->priorityList->takeItem(currentIndex));
ui->priorityList->setCurrentRow(currentIndex + 1); ui->priorityList->setCurrentRow(currentIndex + 1);
lock_guard<mutex> lock(switcher->m); lock_guard<mutex> lock(switcher->m);
iter_swap(switcher->functionNamesByPriority.begin() + currentIndex, switcher->functionNamesByPriority.begin() + currentIndex + 1); iter_swap(switcher->functionNamesByPriority.begin() +
currentIndex,
switcher->functionNamesByPriority.begin() +
currentIndex + 1);
} }
} }
bool SwitcherData::prioFuncsValid() bool SwitcherData::prioFuncsValid()
{ {
auto it = std::unique(functionNamesByPriority.begin(), functionNamesByPriority.end()); auto it = std::unique(functionNamesByPriority.begin(),
functionNamesByPriority.end());
bool wasUnique = (it == functionNamesByPriority.end()); bool wasUnique = (it == functionNamesByPriority.end());
if (!wasUnique) if (!wasUnique)
return false; return false;
for (int p : functionNamesByPriority) for (int p : functionNamesByPriority) {
{
if (p < 0 || p > 7) if (p < 0 || p > 7)
return false; return false;
} }
return true; return true;
} }