Skip to content

Commit

Permalink
Added Xenomai-powered SC_Lock and SC_SyncCondition. Gives a good 7% s…
Browse files Browse the repository at this point in the history
…ave in CPU.

Closes #62
Closes #52
Closes #16
  • Loading branch information
giuliomoro committed Oct 23, 2020
1 parent 20742ef commit 318423e
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 22 deletions.
11 changes: 9 additions & 2 deletions common/SC_Lock.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,20 @@
#include <mutex>
#include <thread>

#ifdef __COBALT__
# include <XenomaiLock.h>
typedef XenomaiMutex SC_Lock;
#else // __COBALT__
typedef std::mutex SC_Lock;
#endif // __COBALT__
typedef std::thread SC_Thread;
using std::cv_status;
using std::lock_guard;
using std::mutex;
using std::timed_mutex;
using std::unique_lock;
#ifdef __COBALT__
typedef XenomaiConditionVariable condition_variable_any;
#else // __COBALT__
typedef std::condition_variable_any condition_variable_any;

#endif // __COBALT__
typedef SC_Lock mutex;
9 changes: 8 additions & 1 deletion common/SC_SyncCondition.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,14 @@ class SC_SyncCondition {

void Signal() {
++write;
available.notify_one();
#ifdef SC_CONDITION_VARIABLE_ANY_SHOULD_LOCK_BEFORE_NOTIFY
if (mutex.try_lock()) {
#endif // CONDITION_VARIABLE_ANY_SHOULD_LOCK_BEFORE_NOTIFY
available.notify_one();
#ifdef SC_CONDITION_VARIABLE_ANY_SHOULD_LOCK_BEFORE_NOTIFY
mutex.unlock();
}
#endif // CONDITION_VARIABLE_ANY_SHOULD_LOCK_BEFORE_NOTIFY
}

private:
Expand Down
3 changes: 3 additions & 0 deletions server/plugins/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,9 @@ add_library(ML_UGens MODULE
if(NOT NO_LIBSNDFILE)
set(diskio_sources DiskIO_UGens.cpp)

if (XENOMAI_FOUND)
list(APPEND diskio_sources ../../common/XenomaiLock.cpp)
endif()
add_library(DiskIO_UGens MODULE ${diskio_sources})

if(SNDFILE_FOUND)
Expand Down
3 changes: 3 additions & 0 deletions server/scsynth/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ if (FFT_GREEN)
list(APPEND scsynth_sources ../../common/fftlib.c)
endif()

if (XENOMAI_FOUND)
list(APPEND scsynth_sources ../../common/XenomaiLock.cpp)
endif()

include_directories(${CMAKE_SOURCE_DIR}/include/common
${CMAKE_SOURCE_DIR}/common
Expand Down
20 changes: 1 addition & 19 deletions server/scsynth/SC_Bela.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,20 +76,15 @@ class SC_BelaDriver : public SC_AudioDriver {

void BelaAudioCallback(BelaContext* belaContext);
void SignalReceived(int);
static void staticMAudioSyncSignal(void*);
static AuxiliaryTask mAudioSyncSignalTask;
static int countInstances;
static SC_SyncCondition* staticMAudioSync;
Scope* mBelaScope;
uint32 mBelaMaxScopeChannels;

private:
uint32 mSCBufLength;
};

AuxiliaryTask SC_BelaDriver::mAudioSyncSignalTask;
int SC_BelaDriver::countInstances;
SC_SyncCondition* SC_BelaDriver::staticMAudioSync;
SC_BelaDriver* mBelaDriverInstance = 0;

SC_AudioDriver* SC_NewAudioDriver(struct World* inWorld) {
Expand All @@ -105,7 +100,6 @@ SC_BelaDriver::SC_BelaDriver(struct World* inWorld): SC_AudioDriver(inWorld) {
mStartHostSecs = 0;
mSCBufLength = inWorld->mBufLength;

staticMAudioSync = &mAudioSync;
++countInstances;
if (countInstances != 1) {
fprintf(stderr, "Error: there are %d instances of SC_BelaDriver running at the same time. Exiting\n",
Expand Down Expand Up @@ -302,15 +296,9 @@ void SC_BelaDriver::BelaAudioCallback(BelaContext* belaContext) {
scprintf("SC_BelaDriver: unknown exception in real time\n");
}

// this avoids Xenomai mode switches in the audio thread ...
Bela_scheduleAuxiliaryTask(mAudioSyncSignalTask);
mAudioSync.Signal();
}

void SC_BelaDriver::staticMAudioSyncSignal(void*) {
// ... but mode switches are still happening here, in a lower priority thread.
// FIXME: this triggers a mode switch in Xenomai.
staticMAudioSync->Signal();
}
// ====================================================================

typedef struct _BelaHwConfig // HW_DETECT_HACK
Expand Down Expand Up @@ -477,12 +465,6 @@ bool SC_BelaDriver::DriverSetup(int* outNumSamples, double* outSampleRate) {
scprintf("Error in SC_BelaDriver::DriverSetup(): unable to initialise audio\n");
return false;
}
mAudioSyncSignalTask = Bela_createAuxiliaryTask(
staticMAudioSyncSignal, 90, "mAudioSyncSignalTask"); // needs to be created after the call to Bela_initAudio()
if (!mAudioSyncSignalTask) {
fprintf(stderr, "Error: unable to create Bela auxiliary task\n");
exit(1);
}

*outNumSamples = settings->periodSize;
*outSampleRate = gBelaSampleRate;
Expand Down
4 changes: 4 additions & 0 deletions server/scsynth/scsynth_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@
#else
# include <sys/wait.h>
#endif
#ifdef __COBALT__
# include "XenomaiLock.h"
XenomaiInitializer xenomaiInitializer;
#endif // __COBALT__

#ifdef _WIN32

Expand Down

0 comments on commit 318423e

Please sign in to comment.