Jolt Physics
A multi core friendly Game Physics Engine
Loading...
Searching...
No Matches
Mutex.h
Go to the documentation of this file.
1// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
2// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
3// SPDX-License-Identifier: MIT
4
5#pragma once
6
9
11#include <mutex>
12#include <shared_mutex>
13#include <thread>
15
17
18// Things we're using from STL
19using std::mutex;
20using std::shared_mutex;
21using std::thread;
22using std::lock_guard;
23using std::shared_lock;
24using std::unique_lock;
25
26#ifdef JPH_PLATFORM_BLUE
27
28// On Platform Blue the mutex class is not very fast so we implement it using the official APIs
29class MutexBase : public NonCopyable
30{
31public:
32 MutexBase()
33 {
34 JPH_PLATFORM_BLUE_MUTEX_INIT(mMutex);
35 }
36
38 {
39 JPH_PLATFORM_BLUE_MUTEX_DESTROY(mMutex);
40 }
41
42 inline bool try_lock()
43 {
44 return JPH_PLATFORM_BLUE_MUTEX_TRYLOCK(mMutex);
45 }
46
47 inline void lock()
48 {
49 JPH_PLATFORM_BLUE_MUTEX_LOCK(mMutex);
50 }
51
52 inline void unlock()
53 {
54 JPH_PLATFORM_BLUE_MUTEX_UNLOCK(mMutex);
55 }
56
57private:
58 JPH_PLATFORM_BLUE_MUTEX mMutex;
59};
60
61// On Platform Blue the shared_mutex class is not very fast so we implement it using the official APIs
62class SharedMutexBase : public NonCopyable
63{
64public:
66 {
67 JPH_PLATFORM_BLUE_RWLOCK_INIT(mRWLock);
68 }
69
71 {
72 JPH_PLATFORM_BLUE_RWLOCK_DESTROY(mRWLock);
73 }
74
75 inline bool try_lock()
76 {
77 return JPH_PLATFORM_BLUE_RWLOCK_TRYWLOCK(mRWLock);
78 }
79
80 inline bool try_lock_shared()
81 {
82 return JPH_PLATFORM_BLUE_RWLOCK_TRYRLOCK(mRWLock);
83 }
84
85 inline void lock()
86 {
87 JPH_PLATFORM_BLUE_RWLOCK_WLOCK(mRWLock);
88 }
89
90 inline void unlock()
91 {
92 JPH_PLATFORM_BLUE_RWLOCK_WUNLOCK(mRWLock);
93 }
94
95 inline void lock_shared()
96 {
97 JPH_PLATFORM_BLUE_RWLOCK_RLOCK(mRWLock);
98 }
99
100 inline void unlock_shared()
101 {
102 JPH_PLATFORM_BLUE_RWLOCK_RUNLOCK(mRWLock);
103 }
104
105private:
106 JPH_PLATFORM_BLUE_RWLOCK mRWLock;
107};
108
109#else
110
111// On other platforms just use the STL implementation
112using MutexBase = mutex;
113using SharedMutexBase = shared_mutex;
114
115#endif // JPH_PLATFORM_BLUE
116
117#if defined(JPH_ENABLE_ASSERTS) || defined(JPH_PROFILE_ENABLED) || defined(JPH_EXTERNAL_PROFILE)
118
121class Mutex : public MutexBase
122{
123public:
124 inline bool try_lock()
125 {
126 JPH_ASSERT(mLockedThreadID != std::this_thread::get_id());
127 if (MutexBase::try_lock())
128 {
129 JPH_IF_ENABLE_ASSERTS(mLockedThreadID = std::this_thread::get_id();)
130 return true;
131 }
132 return false;
133 }
134
135 inline void lock()
136 {
137 if (!try_lock())
138 {
139 JPH_PROFILE("Lock", 0xff00ffff);
140 MutexBase::lock();
141 JPH_IF_ENABLE_ASSERTS(mLockedThreadID = std::this_thread::get_id();)
142 }
143 }
144
145 inline void unlock()
146 {
147 JPH_ASSERT(mLockedThreadID == std::this_thread::get_id());
148 JPH_IF_ENABLE_ASSERTS(mLockedThreadID = thread::id();)
149 MutexBase::unlock();
150 }
151
152#ifdef JPH_ENABLE_ASSERTS
153 inline bool is_locked()
154 {
155 return mLockedThreadID != thread::id();
156 }
157#endif // JPH_ENABLE_ASSERTS
158
159private:
160 JPH_IF_ENABLE_ASSERTS(thread::id mLockedThreadID;)
161};
162
166{
167public:
168 inline bool try_lock()
169 {
170 JPH_ASSERT(mLockedThreadID != std::this_thread::get_id());
171 if (SharedMutexBase::try_lock())
172 {
173 JPH_IF_ENABLE_ASSERTS(mLockedThreadID = std::this_thread::get_id();)
174 return true;
175 }
176 return false;
177 }
178
179 inline void lock()
180 {
181 if (!try_lock())
182 {
183 JPH_PROFILE("WLock", 0xff00ffff);
184 SharedMutexBase::lock();
185 JPH_IF_ENABLE_ASSERTS(mLockedThreadID = std::this_thread::get_id();)
186 }
187 }
188
189 inline void unlock()
190 {
191 JPH_ASSERT(mLockedThreadID == std::this_thread::get_id());
192 JPH_IF_ENABLE_ASSERTS(mLockedThreadID = thread::id();)
193 SharedMutexBase::unlock();
194 }
195
196#ifdef JPH_ENABLE_ASSERTS
197 inline bool is_locked()
198 {
199 return mLockedThreadID != thread::id();
200 }
201#endif // JPH_ENABLE_ASSERTS
202
203 inline void lock_shared()
204 {
205 if (!try_lock_shared())
206 {
207 JPH_PROFILE("RLock", 0xff00ffff);
208 SharedMutexBase::lock_shared();
209 }
210 }
211
212private:
213 JPH_IF_ENABLE_ASSERTS(thread::id mLockedThreadID;)
214};
215
216#else
217
218using Mutex = MutexBase;
220
221#endif
222
#define JPH_SUPPRESS_WARNINGS_STD_BEGIN
Definition Core.h:383
#define JPH_SUPPRESS_WARNINGS_STD_END
Definition Core.h:395
#define JPH_NAMESPACE_END
Definition Core.h:378
#define JPH_NAMESPACE_BEGIN
Definition Core.h:372
#define JPH_IF_ENABLE_ASSERTS(...)
Definition IssueReporting.h:35
#define JPH_ASSERT(...)
Definition IssueReporting.h:33
shared_mutex SharedMutexBase
Definition Mutex.h:113
mutex MutexBase
Definition Mutex.h:112
#define JPH_PROFILE(...)
Definition Profiler.h:268
Definition Mutex.h:122
void unlock()
Definition Mutex.h:145
bool try_lock()
Definition Mutex.h:124
void lock()
Definition Mutex.h:135
Class that makes another class non-copyable. Usage: Inherit from NonCopyable.
Definition NonCopyable.h:11
Definition Mutex.h:166
void lock_shared()
Definition Mutex.h:203
void unlock()
Definition Mutex.h:189
void lock()
Definition Mutex.h:179
bool try_lock()
Definition Mutex.h:168