Browse Source

Restart engine workers when setting real-time priority.

tags/v1.0.0
Andrew Belt 5 years ago
parent
commit
ce2936c0c8
4 changed files with 53 additions and 19 deletions
  1. +1
    -1
      include/system.hpp
  2. +1
    -1
      src/audio.cpp
  3. +24
    -10
      src/engine/Engine.cpp
  4. +27
    -7
      src/system.cpp

+ 1
- 1
include/system.hpp View File

@@ -28,7 +28,7 @@ int getLogicalCoreCount();
/** Sets a name of the current thread for debuggers and OS-specific process viewers. */ /** Sets a name of the current thread for debuggers and OS-specific process viewers. */
void setThreadName(const std::string &name); void setThreadName(const std::string &name);
/** Sets the current thread to be high-priority. */ /** 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. */ /** Returns the caller's human-readable stack trace with "\n"-separated lines. */
std::string getStackTrace(); std::string getStackTrace();
/** Opens a URL, also happens to work with PDFs and folders. /** Opens a URL, also happens to work with PDFs and folders.


+ 1
- 1
src/audio.cpp View File

@@ -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 // Exploit the stream time to run code on startup of the audio thread
if (streamTime == 0.0) { if (streamTime == 0.0) {
system::setThreadName("Audio"); system::setThreadName("Audio");
system::setThreadRealTime();
// system::setThreadRealTime();
} }
port->processStream((const float *) inputBuffer, (float *) outputBuffer, nFrames); port->processStream((const float *) inputBuffer, (float *) outputBuffer, nFrames);
return 0; return 0;


+ 24
- 10
src/engine/Engine.cpp View File

@@ -116,15 +116,7 @@ struct EngineWorker {
thread.join(); thread.join();
} }


void run() {
system::setThreadName("Engine worker");
// system::setThreadRealTime();
disableDenormals();
while (running) {
step();
}
}

void run();
void step(); void step();
}; };


@@ -168,6 +160,8 @@ Engine::Engine() {


internal->sampleRate = 44100.f; internal->sampleRate = 44100.f;
internal->sampleTime = 1 / internal->sampleRate; internal->sampleTime = 1 / internal->sampleRate;

system::setThreadRealTime(false);
} }


Engine::~Engine() { Engine::~Engine() {
@@ -300,22 +294,31 @@ static void Engine_relaunchWorkers(Engine *that) {
assert(1 <= internal->threadCount); assert(1 <= internal->threadCount);


// Stop all workers // Stop all workers
DEBUG("1");
for (EngineWorker &worker : internal->workers) { for (EngineWorker &worker : internal->workers) {
worker.stop(); worker.stop();
} }
DEBUG("2");
internal->engineBarrier.wait(); internal->engineBarrier.wait();


// Destroy all workers // Destroy all workers
DEBUG("3");
for (EngineWorker &worker : internal->workers) { for (EngineWorker &worker : internal->workers) {
worker.join(); worker.join();
} }
DEBUG("4");
internal->workers.resize(0); internal->workers.resize(0);
DEBUG("5");

// Configure main thread
system::setThreadRealTime(internal->realTime);


// Set barrier counts // Set barrier counts
internal->engineBarrier.total = internal->threadCount; internal->engineBarrier.total = internal->threadCount;
internal->workerBarrier.total = internal->threadCount; internal->workerBarrier.total = internal->threadCount;


// Create workers // Create workers
DEBUG("6");
internal->workers.resize(internal->threadCount - 1); internal->workers.resize(internal->threadCount - 1);
for (int id = 1; id < internal->threadCount; id++) { for (int id = 1; id < internal->threadCount; id++) {
EngineWorker &worker = internal->workers[id - 1]; EngineWorker &worker = internal->workers[id - 1];
@@ -323,6 +326,7 @@ static void Engine_relaunchWorkers(Engine *that) {
worker.engine = that; worker.engine = that;
worker.start(); worker.start();
} }
DEBUG("7");
} }


static void Engine_run(Engine *that) { static void Engine_run(Engine *that) {
@@ -351,8 +355,9 @@ static void Engine_run(Engine *that) {
} }


// Launch workers // Launch workers
if (internal->threadCount != settings::threadCount) {
if (internal->threadCount != settings::threadCount || internal->realTime != settings::realTime) {
internal->threadCount = settings::threadCount; internal->threadCount = settings::threadCount;
internal->realTime = settings::realTime;
Engine_relaunchWorkers(that); 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() { void EngineWorker::step() {
engine->internal->engineBarrier.wait(); engine->internal->engineBarrier.wait();
if (!running) if (!running)


+ 27
- 7
src/system.cpp View File

@@ -105,17 +105,37 @@ void setThreadName(const std::string &name) {
#endif #endif
} }


void setThreadRealTime() {
void setThreadRealTime(bool realTime) {
#if defined ARCH_LIN || defined ARCH_MAC #if defined ARCH_LIN || defined ARCH_MAC
// Round-robin scheduler policy
int policy = SCHED_RR;
int err;
int policy;
struct sched_param param; struct sched_param param;
param.sched_priority = sched_get_priority_max(policy);
pthread_setschedparam(pthread_self(), policy, &param);
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, &param);
assert(!err);

// pthread_getschedparam(pthread_self(), &policy, &param);
// DEBUG("policy %d priority %d", policy, param.sched_priority);

#elif defined ARCH_WIN #elif defined ARCH_WIN
// Set process class first // 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 #endif
} }




Loading…
Cancel
Save