Browse Source

Refactor engine worker thread relaunching.

tags/v1.1.4
Andrew Belt 5 years ago
parent
commit
56e0ce0f79
2 changed files with 76 additions and 33 deletions
  1. +4
    -0
      .astylerc
  2. +72
    -33
      src/engine/Engine.cpp

+ 4
- 0
.astylerc View File

@@ -5,6 +5,10 @@


# Usage: # Usage:
# astyle --suffix=none --options=.astylerc filename.cpp # astyle --suffix=none --options=.astylerc filename.cpp
# or recursively
# astyle --suffix=none --options=.astylerc -r 'include/*' 'src/*'
# or using find
# find src include -type f | xargs astyle --suffix=none --options=.astylerc


style=java style=java
indent=tab=2 indent=tab=2


+ 72
- 33
src/engine/Engine.cpp View File

@@ -147,20 +147,23 @@ struct EngineWorker {
Engine* engine; Engine* engine;
int id; int id;
std::thread thread; std::thread thread;
bool running = true;
bool running = false;


void start() { void start() {
assert(!running);
running = true;
thread = std::thread([&] { thread = std::thread([&] {
random::init(); random::init();
run(); run();
}); });
} }


void stop() {
void requestStop() {
running = false; running = false;
} }


void join() { void join() {
assert(thread.joinable());
thread.join(); thread.join();
} }


@@ -168,6 +171,34 @@ struct EngineWorker {
}; };




struct ProfilerWorker {
Engine* engine;
std::thread thread;
bool running = false;

void start() {
assert(!running);
running = true;
thread = std::thread([&] {
run();
});
}

void stop() {
running = false;
if (thread.joinable())
thread.join();
}

void run() {
while (running) {
DEBUG("sample");
std::this_thread::sleep_for(std::chrono::nanoseconds(100000000));
}
}
};


struct Engine::Internal { struct Engine::Internal {
std::vector<Module*> modules; std::vector<Module*> modules;
std::vector<Cable*> cables; std::vector<Cable*> cables;
@@ -193,20 +224,18 @@ struct Engine::Internal {
VIPMutex vipMutex; VIPMutex vipMutex;


bool realTime = false; bool realTime = false;
int threadCount = 1;
int threadCount = 0;
std::vector<EngineWorker> workers; std::vector<EngineWorker> workers;
HybridBarrier engineBarrier; HybridBarrier engineBarrier;
HybridBarrier workerBarrier; HybridBarrier workerBarrier;
std::atomic<int> workerModuleIndex; std::atomic<int> workerModuleIndex;
ProfilerWorker profilerWorker;
}; };




Engine::Engine() { Engine::Engine() {
internal = new Internal; internal = new Internal;


internal->engineBarrier.total = 1;
internal->workerBarrier.total = 1;

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


@@ -351,36 +380,49 @@ static void Engine_updateExpander(Engine* that, Module::Expander* expander) {
} }
} }


static void Engine_relaunchWorkers(Engine* that) {
static void Engine_relaunchWorkers(Engine* that, int threadCount, bool realTime) {
Engine::Internal* internal = that->internal; Engine::Internal* internal = that->internal;
assert(1 <= internal->threadCount);


// Stop all workers
for (EngineWorker& worker : internal->workers) {
worker.stop();
}
internal->engineBarrier.wait();
if (internal->threadCount > 0) {
// Stop profiler
// internal->profilerWorker.stop();


// Destroy all workers
for (EngineWorker& worker : internal->workers) {
worker.join();
// Stop engine workers
for (EngineWorker& worker : internal->workers) {
worker.requestStop();
}
internal->engineBarrier.wait();

// Join and destroy engine workers
for (EngineWorker& worker : internal->workers) {
worker.join();
}
internal->workers.resize(0);
} }
internal->workers.resize(0);


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


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

// Configure main thread
system::setThreadRealTime(realTime);

if (threadCount > 0) {
// Create and start engine workers
internal->workers.resize(threadCount - 1);
for (int id = 1; id < threadCount; id++) {
EngineWorker& worker = internal->workers[id - 1];
worker.id = id;
worker.engine = that;
worker.start();
}


// Create workers
internal->workers.resize(internal->threadCount - 1);
for (int id = 1; id < internal->threadCount; id++) {
EngineWorker& worker = internal->workers[id - 1];
worker.id = id;
worker.engine = that;
worker.start();
// Start profiler
// internal->profilerWorker.start();
} }
} }


@@ -413,9 +455,7 @@ static void Engine_run(Engine* that) {


// Launch workers // Launch workers
if (internal->threadCount != settings::threadCount || internal->realTime != settings::realTime) { if (internal->threadCount != settings::threadCount || internal->realTime != settings::realTime) {
internal->threadCount = settings::threadCount;
internal->realTime = settings::realTime;
Engine_relaunchWorkers(that);
Engine_relaunchWorkers(that, settings::threadCount, settings::realTime);
} }


if (!internal->paused) { if (!internal->paused) {
@@ -450,8 +490,7 @@ static void Engine_run(Engine* that) {
} }


// Stop workers // Stop workers
internal->threadCount = 1;
Engine_relaunchWorkers(that);
Engine_relaunchWorkers(that, 0, false);
} }


void Engine::start() { void Engine::start() {


Loading…
Cancel
Save