diff --git a/doc/MODDEVICES.md b/doc/MODDEVICES.md index d50b6cb..422a95e 100644 --- a/doc/MODDEVICES.md +++ b/doc/MODDEVICES.md @@ -41,4 +41,5 @@ There are a few critical things to take into consideration for this release: you can and should use multiple instances when there is no desktop connection though - The MOD unit must be connected over USB, so that the 192.168.51.1 IP is reachable - The Audio File, Carla and Ildaeil modules are not available in MOD builds +- Lights and meters from the Cardinal MOD side are not transmitted back to the desktop side - Compared to desktop, MOD builds are not as fast, so do not expect to load big patches diff --git a/include/mutex.hpp b/include/mutex.hpp index 49018db..458cd8d 100644 --- a/include/mutex.hpp +++ b/include/mutex.hpp @@ -19,13 +19,26 @@ #include +#ifdef __MOD_DEVICES__ +#include +#include +#include +#include +#include +#endif + /* replace Rack's mutex with our own custom one, which can do priority inversion. */ namespace rack { struct SharedMutex { - pthread_mutex_t readLock, writeLock; + pthread_mutex_t readLock; +#ifdef __MOD_DEVICES__ + int writeLock; +#else + pthread_mutex_t writeLock; +#endif SharedMutex() noexcept { pthread_mutexattr_t attr; @@ -35,27 +48,52 @@ struct SharedMutex { pthread_mutex_init(&readLock, &attr); pthread_mutexattr_destroy(&attr); +#ifdef __MOD_DEVICES__ + writeLock = 1; +#else pthread_mutexattr_t attr2; pthread_mutexattr_init(&attr2); pthread_mutexattr_setprotocol(&attr2, PTHREAD_PRIO_NONE); pthread_mutexattr_settype(&attr2, PTHREAD_MUTEX_NORMAL); pthread_mutex_init(&writeLock, &attr2); pthread_mutexattr_destroy(&attr2); +#endif } ~SharedMutex() noexcept { pthread_mutex_destroy(&readLock); +#ifndef __MOD_DEVICES__ pthread_mutex_destroy(&writeLock); +#endif } // for std::lock_guard usage, writers lock void lock() noexcept { +#ifdef __MOD_DEVICES__ + for (;;) + { + if (__sync_bool_compare_and_swap(&writeLock, 1, 0)) + return; + + if (syscall(__NR_futex, &writeLock, FUTEX_WAIT_PRIVATE, 0, nullptr, nullptr, 0) != 0) + { + if (errno != EAGAIN && errno != EINTR) + return; + } + } +#else pthread_mutex_lock(&writeLock); +#endif pthread_mutex_lock(&readLock); } void unlock() noexcept { pthread_mutex_unlock(&readLock); +#ifdef __MOD_DEVICES__ + if (__sync_bool_compare_and_swap(&writeLock, 0, 1)) + syscall(__NR_futex, &writeLock, FUTEX_WAKE_PRIVATE, 1, nullptr, nullptr, 0); +#else pthread_mutex_unlock(&writeLock); +#endif } // for SharedLock usage, readers lock