Path: blob/master/thirdparty/jolt_physics/Jolt/Core/Mutex.h
9906 views
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)1// SPDX-FileCopyrightText: 2021 Jorrit Rouwe2// SPDX-License-Identifier: MIT34#pragma once56#include <Jolt/Core/Profiler.h>7#include <Jolt/Core/NonCopyable.h>89JPH_SUPPRESS_WARNINGS_STD_BEGIN10#include <mutex>11#include <shared_mutex>12#include <thread>13JPH_SUPPRESS_WARNINGS_STD_END1415JPH_NAMESPACE_BEGIN1617// Things we're using from STL18using std::mutex;19using std::shared_mutex;20using std::thread;21using std::lock_guard;22using std::shared_lock;23using std::unique_lock;2425#ifdef JPH_PLATFORM_BLUE2627// On Platform Blue the mutex class is not very fast so we implement it using the official APIs28class MutexBase : public NonCopyable29{30public:31MutexBase()32{33JPH_PLATFORM_BLUE_MUTEX_INIT(mMutex);34}3536~MutexBase()37{38JPH_PLATFORM_BLUE_MUTEX_DESTROY(mMutex);39}4041inline bool try_lock()42{43return JPH_PLATFORM_BLUE_MUTEX_TRYLOCK(mMutex);44}4546inline void lock()47{48JPH_PLATFORM_BLUE_MUTEX_LOCK(mMutex);49}5051inline void unlock()52{53JPH_PLATFORM_BLUE_MUTEX_UNLOCK(mMutex);54}5556private:57JPH_PLATFORM_BLUE_MUTEX mMutex;58};5960// On Platform Blue the shared_mutex class is not very fast so we implement it using the official APIs61class SharedMutexBase : public NonCopyable62{63public:64SharedMutexBase()65{66JPH_PLATFORM_BLUE_RWLOCK_INIT(mRWLock);67}6869~SharedMutexBase()70{71JPH_PLATFORM_BLUE_RWLOCK_DESTROY(mRWLock);72}7374inline bool try_lock()75{76return JPH_PLATFORM_BLUE_RWLOCK_TRYWLOCK(mRWLock);77}7879inline bool try_lock_shared()80{81return JPH_PLATFORM_BLUE_RWLOCK_TRYRLOCK(mRWLock);82}8384inline void lock()85{86JPH_PLATFORM_BLUE_RWLOCK_WLOCK(mRWLock);87}8889inline void unlock()90{91JPH_PLATFORM_BLUE_RWLOCK_WUNLOCK(mRWLock);92}9394inline void lock_shared()95{96JPH_PLATFORM_BLUE_RWLOCK_RLOCK(mRWLock);97}9899inline void unlock_shared()100{101JPH_PLATFORM_BLUE_RWLOCK_RUNLOCK(mRWLock);102}103104private:105JPH_PLATFORM_BLUE_RWLOCK mRWLock;106};107108#else109110// On other platforms just use the STL implementation111using MutexBase = mutex;112using SharedMutexBase = shared_mutex;113114#endif // JPH_PLATFORM_BLUE115116#if defined(JPH_ENABLE_ASSERTS) || defined(JPH_PROFILE_ENABLED) || defined(JPH_EXTERNAL_PROFILE)117118/// Very simple wrapper around MutexBase which tracks lock contention in the profiler119/// and asserts that locks/unlocks take place on the same thread120class Mutex : public MutexBase121{122public:123inline bool try_lock()124{125JPH_ASSERT(mLockedThreadID != std::this_thread::get_id());126if (MutexBase::try_lock())127{128JPH_IF_ENABLE_ASSERTS(mLockedThreadID = std::this_thread::get_id();)129return true;130}131return false;132}133134inline void lock()135{136if (!try_lock())137{138JPH_PROFILE("Lock", 0xff00ffff);139MutexBase::lock();140JPH_IF_ENABLE_ASSERTS(mLockedThreadID = std::this_thread::get_id();)141}142}143144inline void unlock()145{146JPH_ASSERT(mLockedThreadID == std::this_thread::get_id());147JPH_IF_ENABLE_ASSERTS(mLockedThreadID = thread::id();)148MutexBase::unlock();149}150151#ifdef JPH_ENABLE_ASSERTS152inline bool is_locked()153{154return mLockedThreadID != thread::id();155}156#endif // JPH_ENABLE_ASSERTS157158private:159JPH_IF_ENABLE_ASSERTS(thread::id mLockedThreadID;)160};161162/// Very simple wrapper around SharedMutexBase which tracks lock contention in the profiler163/// and asserts that locks/unlocks take place on the same thread164class SharedMutex : public SharedMutexBase165{166public:167inline bool try_lock()168{169JPH_ASSERT(mLockedThreadID != std::this_thread::get_id());170if (SharedMutexBase::try_lock())171{172JPH_IF_ENABLE_ASSERTS(mLockedThreadID = std::this_thread::get_id();)173return true;174}175return false;176}177178inline void lock()179{180if (!try_lock())181{182JPH_PROFILE("WLock", 0xff00ffff);183SharedMutexBase::lock();184JPH_IF_ENABLE_ASSERTS(mLockedThreadID = std::this_thread::get_id();)185}186}187188inline void unlock()189{190JPH_ASSERT(mLockedThreadID == std::this_thread::get_id());191JPH_IF_ENABLE_ASSERTS(mLockedThreadID = thread::id();)192SharedMutexBase::unlock();193}194195#ifdef JPH_ENABLE_ASSERTS196inline bool is_locked()197{198return mLockedThreadID != thread::id();199}200#endif // JPH_ENABLE_ASSERTS201202inline void lock_shared()203{204if (!try_lock_shared())205{206JPH_PROFILE("RLock", 0xff00ffff);207SharedMutexBase::lock_shared();208}209}210211private:212JPH_IF_ENABLE_ASSERTS(thread::id mLockedThreadID;)213};214215#else216217using Mutex = MutexBase;218using SharedMutex = SharedMutexBase;219220#endif221222JPH_NAMESPACE_END223224225