Browse Source

Improve plugin bridge performance and other tweaks.

Does not yet fix the infamous bug #234,
but some audio passes through now.
Still don't really know what's going on...
tags/1.9.7
falkTX 9 years ago
parent
commit
01053284fa
3 changed files with 74 additions and 53 deletions
  1. +27
    -38
      source/backend/engine/CarlaEngineBridge.cpp
  2. +11
    -8
      source/backend/plugin/CarlaPluginBridge.cpp
  3. +36
    -7
      source/utils/CarlaSemUtils.hpp

+ 27
- 38
source/backend/engine/CarlaEngineBridge.cpp View File

@@ -33,9 +33,10 @@ using juce::File;
using juce::MemoryBlock;
using juce::String;
using juce::Time;
using juce::Thread;

template<typename T>
bool jackbridge_shm_map2(char* shm, T*& value) noexcept
bool jackbridge_shm_map2(void* shm, T*& value) noexcept
{
value = (T*)jackbridge_shm_map(shm, sizeof(T));
return (value != nullptr);
@@ -162,24 +163,28 @@ struct BridgeRtClientControl : public CarlaRingBufferControl<SmallStackBuffer> {
setRingBuffer(nullptr, false);
}

void postClient() noexcept
PluginBridgeRtClientOpcode readOpcode() noexcept
{
CARLA_SAFE_ASSERT_RETURN(data != nullptr,);

jackbridge_sem_post(&data->sem.client);
return static_cast<PluginBridgeRtClientOpcode>(readUInt());
}

bool waitForServer(const uint secs) noexcept
{
CARLA_SAFE_ASSERT_RETURN(data != nullptr, false);
// helper class that automatically posts semaphore on destructor
struct WaitHelper {
BridgeRtClientData* const data;
const bool ok;

return jackbridge_sem_timedwait(&data->sem.server, secs);
}
WaitHelper(BridgeRtClientControl& c) noexcept
: data(c.data),
ok(jackbridge_sem_timedwait(&data->sem.server, 5)) {}

PluginBridgeRtClientOpcode readOpcode() noexcept
{
return static_cast<PluginBridgeRtClientOpcode>(readUInt());
}
~WaitHelper() noexcept
{
if (ok)
jackbridge_sem_post(&data->sem.client);
}

CARLA_DECLARE_NON_COPY_STRUCT(WaitHelper)
};

CARLA_DECLARE_NON_COPY_STRUCT(BridgeRtClientControl)
};
@@ -363,12 +368,12 @@ struct BridgeNonRtServerControl : public CarlaRingBufferControl<HugeStackBuffer>
// -------------------------------------------------------------------

class CarlaEngineBridge : public CarlaEngine,
public CarlaThread
public Thread
{
public:
CarlaEngineBridge(const char* const audioPoolBaseName, const char* const rtClientBaseName, const char* const nonRtClientBaseName, const char* const nonRtServerBaseName)
: CarlaEngine(),
CarlaThread("CarlaEngineBridge"),
Thread("CarlaEngineBridge"),
fShmAudioPool(),
fShmRtClientControl(),
fShmNonRtClientControl(),
@@ -500,7 +505,7 @@ public:
fShmNonRtServerControl.commitWrite();
}

startThread();
startThread(10);

return true;
}
@@ -796,6 +801,7 @@ public:
if (fLastPingTime > 0 && Time::currentTimeMillis() > fLastPingTime + 30000 && ! wasFirstIdle)
{
carla_stderr("Did not receive ping message from server for 30 secs, closing...");
threadShouldExit();
callback(ENGINE_CALLBACK_QUIT, 0, 0, 0, 0.0f, nullptr);
}
}
@@ -1203,29 +1209,14 @@ public:
protected:
void run() override
{
bool timedOut = false;
bool quitReceived = false;

for (; ! shouldThreadExit();)
for (; ! threadShouldExit();)
{
if (! fShmRtClientControl.waitForServer(5))
{
// Give engine 1 more change to catch up.
if (! timedOut)
{
carla_stderr2("Bridge timed-out, giving it one more chance");
timedOut = true;
continue;
}
const BridgeRtClientControl::WaitHelper helper(fShmRtClientControl);

carla_stderr2("Bridge timed-out, final post...");
fShmRtClientControl.postClient();
carla_stderr2("Bridge timed-out, done.");
signalThreadShouldExit();
break;
}

timedOut = false;
if (! helper.ok)
continue;

for (; fShmRtClientControl.isDataAvailableForReading();)
{
@@ -1504,8 +1495,6 @@ protected:
} break;
}
}

fShmRtClientControl.postClient();
}

callback(ENGINE_CALLBACK_ENGINE_STOPPED, 0, 0, 0, 0.0f, nullptr);


+ 11
- 8
source/backend/plugin/CarlaPluginBridge.cpp View File

@@ -120,6 +120,7 @@ struct BridgeAudioPool {
size = sizeof(float);

data = (float*)carla_shm_map(shm, size);
std::memset(data, 0, size);
}

CARLA_DECLARE_NON_COPY_STRUCT(BridgeAudioPool)
@@ -221,9 +222,7 @@ struct BridgeRtClientControl : public CarlaRingBufferControl<SmallStackBuffer> {

if (carla_shm_map<BridgeRtClientData>(shm, data))
{
carla_zeroStruct(data->sem);
carla_zeroStruct(data->timeInfo);
carla_zeroBytes(data->midiOut, kBridgeRtClientDataMidiOutSize);
std::memset(data, 0, sizeof(BridgeRtClientData));
setRingBuffer(&data->ringBuffer, true);
return true;
}
@@ -548,7 +547,12 @@ protected:
#ifndef CARLA_OS_WIN
// start with "wine" if needed
if (fBinary.endsWithIgnoreCase(".exe"))
arguments.add("wine");
{
if (File("/usr/bin/wine-rt").existsAsFile())
arguments.add("wine-rt");
else
arguments.add("wine");
}
#endif

// binary
@@ -2644,13 +2648,12 @@ private:

fShmRtClientControl.writeOpcode(kPluginBridgeRtClientSetAudioPool);
fShmRtClientControl.writeULong(static_cast<uint64_t>(fShmAudioPool.size));

fShmRtClientControl.commitWrite();

waitForClient("resize-pool");
waitForClient("resize-pool", 5);
}

void waitForClient(const char* const action, const uint secs = 5)
void waitForClient(const char* const action, const uint secs)
{
CARLA_SAFE_ASSERT_RETURN(! fTimedOut,);
CARLA_SAFE_ASSERT_RETURN(! fTimedError,);
@@ -2659,7 +2662,7 @@ private:
return;

fTimedOut = true;
carla_stderr("waitForClient(%s) timeout here", action);
carla_stderr("waitForClient(%s) timed out", action);
}

CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPluginBridge)


+ 36
- 7
source/utils/CarlaSemUtils.hpp View File

@@ -128,20 +128,49 @@ bool carla_sem_timedwait(carla_sem_t& sem, const uint secs) noexcept
#elif defined(CARLA_OS_MAC)
// TODO
#else
timespec timeout;
# ifdef CARLA_OS_LINUX
if (::sem_trywait(&sem.sem) == 0)
return true;

# if 1
/* NOTE:
* This is very ugly!
* While trying to fix 32bit-on-64bit issues I noticed this somehow gets a signal,
* while that timedwait does not.
* I'll keep this code for the time being, but only for TESTING!
* It should revert to the proper code (below) when we know more info about the bug.
*/
timespec timeout, now, step;
step.tv_sec = 0;
step.tv_nsec = 2;

::clock_gettime(CLOCK_REALTIME, &timeout);
timeout.tv_sec += static_cast<time_t>(secs);

for (;;)
{
::nanosleep(&step, NULL);
::clock_gettime(CLOCK_REALTIME, &now);

if (now.tv_sec >= timeout.tv_sec)
return false;

if (::sem_trywait(&sem.sem) == 0)
return true;
}

//timeval now;
//::gettimeofday(&now, nullptr);
//timeout.tv_sec = now.tv_sec;
//timeout.tv_nsec = now.tv_usec * 1000;
# else
timeval now;
::gettimeofday(&now, nullptr);
timeout.tv_sec = now.tv_sec;
timeout.tv_nsec = now.tv_usec * 1000;
# endif
timespec timeout;
::clock_gettime(CLOCK_REALTIME, &timeout);
timeout.tv_sec += static_cast<time_t>(secs);

try {
return (::sem_timedwait(&sem.sem, &timeout) == 0);
} CARLA_SAFE_EXCEPTION_RETURN("sem_timedwait", false);
# endif
#endif
}



Loading…
Cancel
Save