Browse Source

Make global context a thread_local variable. Add contextSet().

tags/v2.0.0
Andrew Belt 4 years ago
parent
commit
3f83066966
8 changed files with 30 additions and 5 deletions
  1. +2
    -0
      include/audio.hpp
  2. +4
    -0
      include/context.hpp
  3. +2
    -0
      include/midi.hpp
  4. +7
    -0
      src/audio.cpp
  5. +6
    -1
      src/context.cpp
  6. +3
    -0
      src/engine/Engine.cpp
  7. +4
    -4
      src/main.cpp
  8. +2
    -0
      src/midi.cpp

+ 2
- 0
include/audio.hpp View File

@@ -1,5 +1,6 @@
#pragma once #pragma once
#include <common.hpp> #include <common.hpp>
#include <context.hpp>
#include <jansson.h> #include <jansson.h>
#include <vector> #include <vector>
#include <set> #include <set>
@@ -106,6 +107,7 @@ struct Port {
/** Not owned */ /** Not owned */
Driver* driver = NULL; Driver* driver = NULL;
Device* device = NULL; Device* device = NULL;
Context* context;


Port(); Port();
virtual ~Port(); virtual ~Port();


+ 4
- 0
include/context.hpp View File

@@ -47,6 +47,10 @@ void contextInit();
void contextDestroy(); void contextDestroy();
/** Returns the global Context pointer */ /** Returns the global Context pointer */
Context* contextGet(); Context* contextGet();
/** Sets the context for this thread.
You must call this every thread if you want to use the APP macro in that thread.
*/
void contextSet(Context* context);


/** Accesses the global Context pointer */ /** Accesses the global Context pointer */
#define APP rack::contextGet() #define APP rack::contextGet()


+ 2
- 0
include/midi.hpp View File

@@ -1,5 +1,6 @@
#pragma once #pragma once
#include <common.hpp> #include <common.hpp>
#include <context.hpp>
#include <vector> #include <vector>
#include <queue> #include <queue>
#include <set> #include <set>
@@ -154,6 +155,7 @@ struct Port {
/** Not owned */ /** Not owned */
Driver* driver = NULL; Driver* driver = NULL;
Device* device = NULL; Device* device = NULL;
Context* context;


Port(); Port();
virtual ~Port(); virtual ~Port();


+ 7
- 0
src/audio.cpp View File

@@ -54,24 +54,30 @@ std::string Device::getDetail(int offset, int maxChannels) {


void Device::processBuffer(const float* input, int inputStride, float* output, int outputStride, int frames) { void Device::processBuffer(const float* input, int inputStride, float* output, int outputStride, int frames) {
for (Port* port : subscribed) { for (Port* port : subscribed) {
// Setting the thread context should probably be the responsibility of Port, but because processInput() etc are overridden, this is the only good place for it.
contextSet(port->context);
port->processInput(input + port->offset, inputStride, frames); port->processInput(input + port->offset, inputStride, frames);
} }
for (Port* port : subscribed) { for (Port* port : subscribed) {
contextSet(port->context);
port->processBuffer(input + port->offset, inputStride, output + port->offset, outputStride, frames); port->processBuffer(input + port->offset, inputStride, output + port->offset, outputStride, frames);
} }
for (Port* port : subscribed) { for (Port* port : subscribed) {
contextSet(port->context);
port->processOutput(output + port->offset, outputStride, frames); port->processOutput(output + port->offset, outputStride, frames);
} }
} }


void Device::onOpenStream() { void Device::onOpenStream() {
for (Port* port : subscribed) { for (Port* port : subscribed) {
contextSet(port->context);
port->onOpenStream(); port->onOpenStream();
} }
} }


void Device::onCloseStream() { void Device::onCloseStream() {
for (Port* port : subscribed) { for (Port* port : subscribed) {
contextSet(port->context);
port->onCloseStream(); port->onCloseStream();
} }
} }
@@ -82,6 +88,7 @@ void Device::onCloseStream() {


Port::Port() { Port::Port() {
reset(); reset();
context = contextGet();
} }


Port::~Port() { Port::~Port() {


+ 6
- 1
src/context.cpp View File

@@ -45,7 +45,7 @@ Context::~Context() {
} }




static Context* context = NULL;
static thread_local Context* context = NULL;


void contextInit() { void contextInit() {
assert(!context); assert(!context);
@@ -60,8 +60,13 @@ void contextDestroy() {
} }


Context* contextGet() { Context* contextGet() {
assert(context);
return context; return context;
} }


void contextSet(Context* context) {
rack::context = context;
}



} // namespace rack } // namespace rack

+ 3
- 0
src/engine/Engine.cpp View File

@@ -172,6 +172,7 @@ struct Engine::Internal {
HybridBarrier engineBarrier; HybridBarrier engineBarrier;
HybridBarrier workerBarrier; HybridBarrier workerBarrier;
std::atomic<int> workerModuleIndex; std::atomic<int> workerModuleIndex;
Context* context;
}; };




@@ -386,6 +387,7 @@ static void Engine_relaunchWorkers(Engine* that, int threadCount) {
Engine::Engine() { Engine::Engine() {
internal = new Internal; internal = new Internal;


internal->context = contextGet();
internal->sampleRate = 44100.f; internal->sampleRate = 44100.f;
internal->sampleTime = 1 / internal->sampleRate; internal->sampleTime = 1 / internal->sampleRate;
} }
@@ -1036,6 +1038,7 @@ void Engine::fromJson(json_t* rootJ) {


void EngineWorker::run() { void EngineWorker::run() {
// Configure thread // Configure thread
contextSet(engine->internal->context);
system::setThreadName(string::f("Worker %d", id)); system::setThreadName(string::f("Worker %d", id));
initMXCSR(); initMXCSR();
random::init(); random::init();


+ 4
- 4
src/main.cpp View File

@@ -170,8 +170,8 @@ int main(int argc, char* argv[]) {
windowInit(); windowInit();
} }


// Initialize app
INFO("Initializing app");
// Initialize context
INFO("Initializing context");
contextInit(); contextInit();


// On Mac, use a hacked-in GLFW addition to get the launched path. // On Mac, use a hacked-in GLFW addition to get the launched path.
@@ -201,11 +201,11 @@ int main(int argc, char* argv[]) {
INFO("Stopped window"); INFO("Stopped window");
} }


// Destroy app
// Destroy context
if (!settings::headless) { if (!settings::headless) {
APP->patch->save(asset::autosavePath); APP->patch->save(asset::autosavePath);
} }
INFO("Destroying app");
INFO("Destroying context");
contextDestroy(); contextDestroy();
if (!settings::headless) { if (!settings::headless) {
settings::save(asset::settingsPath); settings::save(asset::settingsPath);


+ 2
- 0
src/midi.cpp View File

@@ -33,6 +33,7 @@ void InputDevice::onMessage(const Message &message) {
msg.timestamp = system::getNanoseconds(); msg.timestamp = system::getNanoseconds();


for (Input* input : subscribed) { for (Input* input : subscribed) {
contextSet(input->context);
// Filter channel // Filter channel
if (input->channel < 0 || msg.getStatus() == 0xf || msg.getChannel() == input->channel) { if (input->channel < 0 || msg.getStatus() == 0xf || msg.getChannel() == input->channel) {
input->onMessage(msg); input->onMessage(msg);
@@ -55,6 +56,7 @@ void OutputDevice::unsubscribe(Output* output) {
//////////////////// ////////////////////


Port::Port() { Port::Port() {
context = contextGet();
} }


Port::~Port() { Port::~Port() {


Loading…
Cancel
Save