@@ -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 <math.hpp> | ||||
#include <string.hpp> | #include <string.hpp> | ||||
#include <system.hpp> | #include <system.hpp> | ||||
#include <mutex.hpp> | |||||
#include <random.hpp> | #include <random.hpp> | ||||
#include <network.hpp> | #include <network.hpp> | ||||
#include <asset.hpp> | #include <asset.hpp> | ||||
@@ -6,7 +6,6 @@ | |||||
#include <atomic> | #include <atomic> | ||||
#include <tuple> | #include <tuple> | ||||
#include <pmmintrin.h> | #include <pmmintrin.h> | ||||
#include <pthread.h> | |||||
#include <engine/Engine.hpp> | #include <engine/Engine.hpp> | ||||
#include <settings.hpp> | #include <settings.hpp> | ||||
@@ -15,6 +14,7 @@ | |||||
#include <context.hpp> | #include <context.hpp> | ||||
#include <patch.hpp> | #include <patch.hpp> | ||||
#include <plugin.hpp> | #include <plugin.hpp> | ||||
#include <mutex.hpp> | |||||
namespace rack { | 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. | /** Barrier based on mutexes. | ||||
Not finished or tested, do not use. | Not finished or tested, do not use. | ||||
*/ | */ | ||||