diff --git a/include/system.hpp b/include/system.hpp index b83b9c43..ec9dfded 100644 --- a/include/system.hpp +++ b/include/system.hpp @@ -28,7 +28,7 @@ int getLogicalCoreCount(); /** Sets a name of the current thread for debuggers and OS-specific process viewers. */ void setThreadName(const std::string &name); /** Sets the current thread to be high-priority. */ -void setThreadRealTime(); +void setThreadRealTime(bool realTime); /** Returns the caller's human-readable stack trace with "\n"-separated lines. */ std::string getStackTrace(); /** Opens a URL, also happens to work with PDFs and folders. diff --git a/src/audio.cpp b/src/audio.cpp index 974224fa..f465bbb7 100644 --- a/src/audio.cpp +++ b/src/audio.cpp @@ -211,7 +211,7 @@ static int rtCallback(void *outputBuffer, void *inputBuffer, unsigned int nFrame // Exploit the stream time to run code on startup of the audio thread if (streamTime == 0.0) { system::setThreadName("Audio"); - system::setThreadRealTime(); + // system::setThreadRealTime(); } port->processStream((const float *) inputBuffer, (float *) outputBuffer, nFrames); return 0; diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index 75234b6b..33608cde 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -116,15 +116,7 @@ struct EngineWorker { thread.join(); } - void run() { - system::setThreadName("Engine worker"); - // system::setThreadRealTime(); - disableDenormals(); - while (running) { - step(); - } - } - + void run(); void step(); }; @@ -168,6 +160,8 @@ Engine::Engine() { internal->sampleRate = 44100.f; internal->sampleTime = 1 / internal->sampleRate; + + system::setThreadRealTime(false); } Engine::~Engine() { @@ -300,22 +294,31 @@ static void Engine_relaunchWorkers(Engine *that) { assert(1 <= internal->threadCount); // Stop all workers + DEBUG("1"); for (EngineWorker &worker : internal->workers) { worker.stop(); } + DEBUG("2"); internal->engineBarrier.wait(); // Destroy all workers + DEBUG("3"); for (EngineWorker &worker : internal->workers) { worker.join(); } + DEBUG("4"); internal->workers.resize(0); + DEBUG("5"); + + // Configure main thread + system::setThreadRealTime(internal->realTime); // Set barrier counts internal->engineBarrier.total = internal->threadCount; internal->workerBarrier.total = internal->threadCount; // Create workers + DEBUG("6"); internal->workers.resize(internal->threadCount - 1); for (int id = 1; id < internal->threadCount; id++) { EngineWorker &worker = internal->workers[id - 1]; @@ -323,6 +326,7 @@ static void Engine_relaunchWorkers(Engine *that) { worker.engine = that; worker.start(); } + DEBUG("7"); } static void Engine_run(Engine *that) { @@ -351,8 +355,9 @@ static void Engine_run(Engine *that) { } // Launch workers - if (internal->threadCount != settings::threadCount) { + if (internal->threadCount != settings::threadCount || internal->realTime != settings::realTime) { internal->threadCount = settings::threadCount; + internal->realTime = settings::realTime; Engine_relaunchWorkers(that); } @@ -696,6 +701,15 @@ void Engine::updateParamHandle(ParamHandle *paramHandle, int moduleId, int param } +void EngineWorker::run() { + system::setThreadName("Engine worker"); + system::setThreadRealTime(engine->internal->realTime); + disableDenormals(); + while (running) { + step(); + } +} + void EngineWorker::step() { engine->internal->engineBarrier.wait(); if (!running) diff --git a/src/system.cpp b/src/system.cpp index 1e000a16..ce81c4ee 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -105,17 +105,37 @@ void setThreadName(const std::string &name) { #endif } -void setThreadRealTime() { +void setThreadRealTime(bool realTime) { #if defined ARCH_LIN || defined ARCH_MAC - // Round-robin scheduler policy - int policy = SCHED_RR; + int err; + int policy; struct sched_param param; - param.sched_priority = sched_get_priority_max(policy); - pthread_setschedparam(pthread_self(), policy, ¶m); + if (realTime) { + // Round-robin scheduler policy + policy = SCHED_RR; + param.sched_priority = sched_get_priority_max(policy); + } + else { + // Default scheduler policy + policy = 0; + param.sched_priority = 0; + } + err = pthread_setschedparam(pthread_self(), policy, ¶m); + assert(!err); + + // pthread_getschedparam(pthread_self(), &policy, ¶m); + // DEBUG("policy %d priority %d", policy, param.sched_priority); + #elif defined ARCH_WIN // Set process class first - SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); + if (realTime) { + SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); + } + else { + SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS); + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL); + } #endif }