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>
<widget class="QLabel" name="label_56">
<property name="text">
<string>Use thread priority (experimental)</string>
<string>Use thread priority</string>
</property>
</widget>
</item>
@ -368,6 +368,13 @@
</property>
</widget>
</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>
<spacer name="horizontalSpacer_41">
<property name="orientation">

View File

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

View File

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

View File

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

View File

@ -3,7 +3,6 @@
#include <chrono>
#include <string>
#include <vector>
#include <thread>
#include <regex>
#include <mutex>
#include <fstream>
@ -256,7 +255,7 @@ typedef enum { NO_SWITCH = 0, SWITCH = 1, RANDOM_SWITCH = 2 } NoMatch;
* SwitcherData
********************************************************************************/
struct SwitcherData {
thread th;
QThread* th = nullptr;
condition_variable cv;
mutex m;
bool transitionActive = false;
@ -311,18 +310,33 @@ struct SwitcherData {
DEFAULT_PRIORITY_3, DEFAULT_PRIORITY_4, DEFAULT_PRIORITY_5,
DEFAULT_PRIORITY_6, DEFAULT_PRIORITY_7};
std::vector<std::string> threadPrioritiesNamesOrderdByPrio{
"Lowest", "Low", "Normal", "High", "Highest", "Time critical",
struct ThreadPrio {
std::string name;
std::string description;
uint32_t value;
};
std::map<std::string, int> threadPriorities = {
{"Lowest", QThread::LowestPriority},
{"Low", QThread::LowPriority},
{"Normal", QThread::NormalPriority},
{"High", QThread::HighPriority},
{"Highest", QThread::HighestPriority},
{"Time critical", QThread::TimeCriticalPriority},
std::vector<ThreadPrio> threadPriorities{
{"Idle",
"scheduled only when no other threads are running (lowest CPU load)",
QThread::IdlePriority},
{"Lowest", "scheduled less often than LowPriority",
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 Start();
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 (!switcher->th.joinable())
if (!(switcher->th && switcher->th->isRunning()))
switcher->Start();
}
@ -43,7 +43,7 @@ void stopHotkeyFunc(void* data, obs_hotkey_id id, obs_hotkey_t* hotkey, bool pre
if (pressed)
{
if (switcher->th.joinable())
if (switcher->th && switcher->th->isRunning())
switcher->Stop();
}
@ -78,7 +78,7 @@ void startStopToggleHotkeyFunc(void* data, obs_hotkey_id id, obs_hotkey_t* hotke
if (pressed)
{
if (switcher->th.joinable())
if (switcher->th && switcher->th->isRunning())
switcher->Stop();
else
switcher->Start();

View File

@ -1,44 +1,68 @@
#include <algorithm>
#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()
{
int currentIndex = ui->priorityList->currentRow();
if (currentIndex != -1 && currentIndex != 0)
{
ui->priorityList->insertItem(currentIndex - 1 ,ui->priorityList->takeItem(currentIndex));
ui->priorityList->setCurrentRow(currentIndex -1);
if (currentIndex != -1 && currentIndex != 0) {
ui->priorityList->insertItem(
currentIndex - 1,
ui->priorityList->takeItem(currentIndex));
ui->priorityList->setCurrentRow(currentIndex - 1);
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()
{
int currentIndex = ui->priorityList->currentRow();
if (currentIndex != -1 && currentIndex != ui->priorityList->count() - 1)
{
ui->priorityList->insertItem(currentIndex + 1, ui->priorityList->takeItem(currentIndex));
if (currentIndex != -1 &&
currentIndex != ui->priorityList->count() - 1) {
ui->priorityList->insertItem(
currentIndex + 1,
ui->priorityList->takeItem(currentIndex));
ui->priorityList->setCurrentRow(currentIndex + 1);
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()
{
auto it = std::unique(functionNamesByPriority.begin(), functionNamesByPriority.end());
auto it = std::unique(functionNamesByPriority.begin(),
functionNamesByPriority.end());
bool wasUnique = (it == functionNamesByPriority.end());
if (!wasUnique)
return false;
for (int p : functionNamesByPriority)
{
for (int p : functionNamesByPriority) {
if (p < 0 || p > 7)
return false;
}
return true;
}