| @@ -0,0 +1,76 @@ | |||
| #pragma once | |||
| #include <common.hpp> | |||
| #include <pthread.h> | |||
| namespace rack { | |||
| /** Allows multiple "reader" threads to obtain a lock simultaneously, but only one "writer" thread. | |||
| This implementation is currently just a wrapper for pthreads, which works on Linux/Mac/. | |||
| This is available in C++17 as std::shared_mutex, but unfortunately we're using C++11. | |||
| */ | |||
| struct ReadWriteMutex { | |||
| pthread_rwlock_t rwlock; | |||
| ReadWriteMutex() { | |||
| if (pthread_rwlock_init(&rwlock, NULL)) | |||
| throw Exception("pthread_rwlock_init failed"); | |||
| } | |||
| ~ReadWriteMutex() { | |||
| pthread_rwlock_destroy(&rwlock); | |||
| } | |||
| void lockReader() { | |||
| if (pthread_rwlock_rdlock(&rwlock)) | |||
| throw Exception("pthread_rwlock_rdlock failed"); | |||
| } | |||
| /** Returns whether the lock was acquired. */ | |||
| bool tryLockReader() { | |||
| return pthread_rwlock_tryrdlock(&rwlock) == 0; | |||
| } | |||
| void unlockReader() { | |||
| if (pthread_rwlock_unlock(&rwlock)) | |||
| throw Exception("pthread_rwlock_unlock failed"); | |||
| } | |||
| void lockWriter() { | |||
| if (pthread_rwlock_wrlock(&rwlock)) | |||
| throw Exception("pthread_rwlock_wrlock failed"); | |||
| } | |||
| /** Returns whether the lock was acquired. */ | |||
| bool tryLockWriter() { | |||
| return pthread_rwlock_trywrlock(&rwlock) == 0; | |||
| } | |||
| void unlockWriter() { | |||
| if (pthread_rwlock_unlock(&rwlock)) | |||
| throw Exception("pthread_rwlock_unlock failed"); | |||
| } | |||
| }; | |||
| struct ReadLock { | |||
| ReadWriteMutex& m; | |||
| ReadLock(ReadWriteMutex& m) : m(m) { | |||
| m.lockReader(); | |||
| } | |||
| ~ReadLock() { | |||
| m.unlockReader(); | |||
| } | |||
| }; | |||
| struct WriteLock { | |||
| ReadWriteMutex& m; | |||
| WriteLock(ReadWriteMutex& m) : m(m) { | |||
| m.lockWriter(); | |||
| } | |||
| ~WriteLock() { | |||
| m.unlockWriter(); | |||
| } | |||
| }; | |||
| } // namespace rack | |||
| @@ -23,6 +23,7 @@ Directly including Rack headers other than rack.hpp in your plugin is unsupporte | |||
| #include <math.hpp> | |||
| #include <string.hpp> | |||
| #include <system.hpp> | |||
| #include <mutex.hpp> | |||
| #include <random.hpp> | |||
| #include <network.hpp> | |||
| #include <asset.hpp> | |||
| @@ -6,7 +6,6 @@ | |||
| #include <atomic> | |||
| #include <tuple> | |||
| #include <pmmintrin.h> | |||
| #include <pthread.h> | |||
| #include <engine/Engine.hpp> | |||
| #include <settings.hpp> | |||
| @@ -15,6 +14,7 @@ | |||
| #include <context.hpp> | |||
| #include <patch.hpp> | |||
| #include <plugin.hpp> | |||
| #include <mutex.hpp> | |||
| namespace rack { | |||
| @@ -31,59 +31,6 @@ static void initMXCSR() { | |||
| } | |||
| /** Allows multiple "reader" threads to obtain a lock simultaneously, but only one "writer" thread. | |||
| This implementation is currently just a wrapper for pthreads, which works on Linux/Mac/. | |||
| This is available in C++17 as std::shared_mutex, but unfortunately we're using C++11. | |||
| */ | |||
| struct ReadWriteMutex { | |||
| pthread_rwlock_t rwlock; | |||
| ReadWriteMutex() { | |||
| if (pthread_rwlock_init(&rwlock, NULL)) | |||
| throw Exception("pthread_rwlock_init failed"); | |||
| } | |||
| ~ReadWriteMutex() { | |||
| pthread_rwlock_destroy(&rwlock); | |||
| } | |||
| void lockReader() { | |||
| if (pthread_rwlock_rdlock(&rwlock)) | |||
| throw Exception("pthread_rwlock_rdlock failed"); | |||
| } | |||
| void unlockReader() { | |||
| if (pthread_rwlock_unlock(&rwlock)) | |||
| throw Exception("pthread_rwlock_unlock failed"); | |||
| } | |||
| void lockWriter() { | |||
| if (pthread_rwlock_wrlock(&rwlock)) | |||
| throw Exception("pthread_rwlock_wrlock failed"); | |||
| } | |||
| void unlockWriter() { | |||
| if (pthread_rwlock_unlock(&rwlock)) | |||
| throw Exception("pthread_rwlock_unlock failed"); | |||
| } | |||
| }; | |||
| struct ReadLock { | |||
| ReadWriteMutex& m; | |||
| ReadLock(ReadWriteMutex& m) : m(m) { | |||
| m.lockReader(); | |||
| } | |||
| ~ReadLock() { | |||
| m.unlockReader(); | |||
| } | |||
| }; | |||
| struct WriteLock { | |||
| ReadWriteMutex& m; | |||
| WriteLock(ReadWriteMutex& m) : m(m) { | |||
| m.lockWriter(); | |||
| } | |||
| ~WriteLock() { | |||
| m.unlockWriter(); | |||
| } | |||
| }; | |||
| /** Barrier based on mutexes. | |||
| Not finished or tested, do not use. | |||
| */ | |||