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. */
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.


+ 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
if (streamTime == 0.0) {
system::setThreadName("Audio");
system::setThreadRealTime();
// system::setThreadRealTime();
}
port->processStream((const float *) inputBuffer, (float *) outputBuffer, nFrames);
return 0;


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

@@ -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)


+ 27
- 7
src/system.cpp View File

@@ -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, &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
// 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
}



Loading…
Cancel
Save