Use variant and optional to implement Maybe*Locks

To avoid calling lock and unlock on the mutex. User-defined destructor is no
more needed.
LTO-timing^2
elsid 3 years ago
parent a1e7622a30
commit 8c3c65fe9f
No known key found for this signature in database
GPG Key ID: 4DE04C198CBA7625

@ -1,4 +1,8 @@
#include <functional>
#include <variant>
#include <optional>
#include <shared_mutex>
#include <mutex>
#include <BulletCollision/BroadphaseCollision/btDbvtBroadphase.h>
#include <BulletCollision/CollisionShapes/btCollisionShape.h>
@ -28,6 +32,15 @@
namespace
{
template <class Mutex>
std::optional<std::unique_lock<Mutex>> makeExclusiveLock(Mutex& mutex, int threadCount)
{
assert(threadCount >= 0);
if (threadCount > 0)
return std::unique_lock(mutex);
return {};
}
/// @brief A scoped lock that is either exclusive or inexistent depending on configuration
template<class Mutex>
class MaybeExclusiveLock
@ -35,24 +48,23 @@ namespace
public:
/// @param mutex a mutex
/// @param threadCount decide wether the excluse lock will be taken
MaybeExclusiveLock(Mutex& mutex, int threadCount) : mMutex(mutex), mThreadCount(threadCount)
{
assert(threadCount >= 0);
if (mThreadCount > 0)
mMutex.lock();
}
~MaybeExclusiveLock()
{
if (mThreadCount > 0)
mMutex.unlock();
}
explicit MaybeExclusiveLock(Mutex& mutex, int threadCount)
: mImpl(makeExclusiveLock(mutex, threadCount))
{}
private:
Mutex& mMutex;
unsigned int mThreadCount;
std::optional<std::unique_lock<Mutex>> mImpl;
};
template <class Mutex>
std::optional<std::shared_lock<Mutex>> makeSharedLock(Mutex& mutex, int threadCount)
{
assert(threadCount >= 0);
if (threadCount > 0)
return std::shared_lock(mutex);
return {};
}
/// @brief A scoped lock that is either shared or inexistent depending on configuration
template<class Mutex>
class MaybeSharedLock
@ -60,24 +72,25 @@ namespace
public:
/// @param mutex a shared mutex
/// @param threadCount decide wether the shared lock will be taken
MaybeSharedLock(Mutex& mutex, int threadCount) : mMutex(mutex), mThreadCount(threadCount)
{
assert(threadCount >= 0);
if (mThreadCount > 0)
mMutex.lock_shared();
}
~MaybeSharedLock()
{
if (mThreadCount > 0)
mMutex.unlock_shared();
}
explicit MaybeSharedLock(Mutex& mutex, int threadCount)
: mImpl(makeSharedLock(mutex, threadCount))
{}
private:
Mutex& mMutex;
unsigned int mThreadCount;
std::optional<std::shared_lock<Mutex>> mImpl;
};
template <class Mutex>
std::variant<std::monostate, std::unique_lock<Mutex>, std::shared_lock<Mutex>> makeLock(Mutex& mutex, int threadCount)
{
assert(threadCount >= 0);
if (threadCount > 1)
return std::shared_lock(mutex);
if (threadCount == 1)
return std::unique_lock(mutex);
return std::monostate {};
}
/// @brief A scoped lock that is either shared, exclusive or inexistent depending on configuration
template<class Mutex>
class MaybeLock
@ -85,25 +98,11 @@ namespace
public:
/// @param mutex a shared mutex
/// @param threadCount decide wether the lock will be shared, exclusive or inexistent
MaybeLock(Mutex& mutex, int threadCount) : mMutex(mutex), mThreadCount(threadCount)
{
assert(threadCount >= 0);
if (mThreadCount > 1)
mMutex.lock_shared();
else if(mThreadCount == 1)
mMutex.lock();
}
explicit MaybeLock(Mutex& mutex, int threadCount)
: mImpl(makeLock(mutex, threadCount)) {}
~MaybeLock()
{
if (mThreadCount > 1)
mMutex.unlock_shared();
else if(mThreadCount == 1)
mMutex.unlock();
}
private:
Mutex& mMutex;
unsigned int mThreadCount;
std::variant<std::monostate, std::unique_lock<Mutex>, std::shared_lock<Mutex>> mImpl;
};
bool isUnderWater(const MWPhysics::ActorFrameData& actorData)

Loading…
Cancel
Save