19#ifndef PHYSICS_THREAD_CONTEXT
20 #if (!UE_BUILD_SHIPPING && !UE_BUILD_TEST)
21 #define PHYSICS_THREAD_CONTEXT 1
23 #define PHYSICS_THREAD_CONTEXT 0
33#define CHAOS_SCENE_LOCK_SCENE_GUARD 0
34#define CHAOS_SCENE_LOCK_RWFIFO_SPINLOCK 1
35#define CHAOS_SCENE_LOCK_RWFIFO_CRITICALSECTION 2
36#define CHAOS_SCENE_LOCK_FRWLOCK 3
37#define CHAOS_SCENE_LOCK_SIMPLE_MUTEX 4
41 #ifndef CHAOS_SCENE_LOCK_TYPE
42 #define CHAOS_SCENE_LOCK_TYPE CHAOS_SCENE_LOCK_RWFIFO_CRITICALSECTION
45 #ifndef CHAOS_SCENE_LOCK_TYPE
46 #define CHAOS_SCENE_LOCK_TYPE CHAOS_SCENE_LOCK_FRWLOCK
57#ifndef CHAOS_SCENE_LOCK_CHECKS
58 #if (!UE_BUILD_SHIPPING && !UE_BUILD_TEST)
59 #define CHAOS_SCENE_LOCK_CHECKS 0
61 #define CHAOS_SCENE_LOCK_CHECKS 0
65#if PHYSICS_THREAD_CONTEXT
66namespace Chaos {
class FPhysicsThreadContext; }
74 namespace ThreadingPrivate
86#if CHAOS_SCENE_LOCK_CHECKS
89 namespace ThreadingPrivate
97 #define CHAOS_CHECK_READ_ASSUMPTION Chaos::ThreadingPrivate::CheckLockReadAssumption(ANSI_TO_TCHAR(__FUNCTION__))
100 #define CHAOS_CHECK_WRITE_ASSUMPTION Chaos::ThreadingPrivate::CheckLockWriteAssumption(ANSI_TO_TCHAR(__FUNCTION__))
109 #define CHAOS_CHECK_READ_ASSUMPTION_ACTOR(Actor) if(Actor && Actor->GetSolverBase()) {Chaos::ThreadingPrivate::CheckLockReadAssumption(ANSI_TO_TCHAR(__FUNCTION__));}
118 #define CHAOS_CHECK_WRITE_ASSUMPTION_ACTOR(Actor) if(Actor && Actor->GetSolverBase()) {Chaos::ThreadingPrivate::CheckLockWriteAssumption(ANSI_TO_TCHAR(__FUNCTION__));}
125 #define CHAOS_CHECK_READ_ASSUMPTION_CONSTRAINT(Handle) \
126 if(Handle.Constraint && \
127 ((Handle.Constraint->GetParticleProxies()[0] && Handle.Constraint->GetParticleProxies()[0]->GetSolverBase()) || \
128 (Handle.Constraint->GetParticleProxies()[1] && Handle.Constraint->GetParticleProxies()[1]->GetSolverBase()))) \
129 {Chaos::ThreadingPrivate::CheckLockReadAssumption(ANSI_TO_TCHAR(__FUNCTION__));}
136 #define CHAOS_CHECK_WRITE_ASSUMPTION_CONSTRAINT(Handle) \
137 if(Handle.Constraint && \
138 ((Handle.Constraint->GetParticleProxies()[0] && Handle.Constraint->GetParticleProxies()[0]->GetSolverBase()) || \
139 (Handle.Constraint->GetParticleProxies()[1] && Handle.Constraint->GetParticleProxies()[1]->GetSolverBase()))) \
140 {Chaos::ThreadingPrivate::CheckLockWriteAssumption(ANSI_TO_TCHAR(__FUNCTION__));}
145 #define CHAOS_CHECK_READ_ASSUMPTION
146 #define CHAOS_CHECK_WRITE_ASSUMPTION
147 #define CHAOS_CHECK_READ_ASSUMPTION_ACTOR
148 #define CHAOS_CHECK_WRITE_ASSUMPTION_ACTOR
149 #define CHAOS_CHECK_READ_ASSUMPTION_CONSTRAINT
150 #define CHAOS_CHECK_WRITE_ASSUMPTION_CONSTRAINT
155#define CHAOS_RECORD_ENTER_READ_LOCK Chaos::ThreadingPrivate::IncReadDepth(this);
158#define CHAOS_RECORD_ENTER_WRITE_LOCK Chaos::ThreadingPrivate::IncWriteDepth(this);
161#define CHAOS_RECORD_LEAVE_READ_LOCK Chaos::ThreadingPrivate::DecReadDepth(this);
164#define CHAOS_RECORD_LEAVE_WRITE_LOCK Chaos::ThreadingPrivate::DecWriteDepth(this);
166#if PHYSICS_THREAD_CONTEXT
174 return PhysicsSimContext > 0;
179 return (
IsInGameThread() || GameThreadContext > 0) && !bFrozenGameThread;
189 check(PhysicsSimContext > 0);
200 check(GameThreadContext > 0);
206 ensure(!bFrozenGameThread);
207 bFrozenGameThread =
true;
212 ensure(bFrozenGameThread);
213 bFrozenGameThread =
false;
217 int32 PhysicsSimContext = 0;
218 int32 GameThreadContext = 0;
219 bool bFrozenGameThread =
false;
329 CurrentWriterThreadId.Store(0);
338 ensureMsgf(CurrentWriterThreadId.Load() == 0,
TEXT(
"Shutting down a physics scene guard but thread %u still holds a write lock"), CurrentWriterThreadId.Load());
361#if PHYSICS_THREAD_CONTEXT
379#if PHYSICS_THREAD_CONTEXT
391 ThreadDataInner.ReadDepth--;
396 ensureMsgf(false, TEXT(
"ReadUnlock called on physics scene guard when the thread does not hold the lock"));
398 UE_LOG(LogChaos, Warning, TEXT(
"ReadUnlock called on physics scene guard when the thread does not hold the lock"))
411#if PHYSICS_THREAD_CONTEXT
427 CurrentWriterThreadId.Store(0);
434 ensureMsgf(
false,
TEXT(
"WriteUnlock called on physics scene guard when the thread does not hold the lock"));
440#if PHYSICS_THREAD_CONTEXT
473 template<
typename CallableType>
498 template<
typename MutexType>
535 template<
typename MutexType>
554 if(ThreadingPrivate::GetThreadReadDepth(
this) == 0)
570#if PHYSICS_THREAD_CONTEXT
584#if CHAOS_SCENE_LOCK_CHECKS
585 if(ThreadingPrivate::GetThreadReadDepth(
this) > 0)
587 ensureMsgf(
false,
TEXT(
"A thread holding a read lock on the physics scene attempted to upgrade to a write lock - this is not supported, performing an unsafe write."));
590#if PHYSICS_THREAD_CONTEXT
604 if(NumReaders.load() == 0)
618#if PHYSICS_THREAD_CONTEXT
632#if PHYSICS_THREAD_CONTEXT
645#if PHYSICS_THREAD_CONTEXT
655 std::atomic<uint32> NumReaders;
685 uint32 WaitFor = Next.fetch_add(1, std::memory_order_acquire);
688 if(WaitFor == Current.load())
707 checkf(Count > 0,
TEXT(
"A thread unlocked a lock that had no outstanding lock scopes"));
722 std::atomic<uint32> Next;
723 std::atomic<uint32> Current;
724 std::atomic<uint32> WriterId;
741 void* GetTlsSlotValue()
747 uint32 ThreadReadDepth = 0;
748 uint32 ThreadWriteDepth = 0;
778#if PHYSICS_THREAD_CONTEXT
792#if CHAOS_SCENE_LOCK_CHECKS
795 UE_LOG(
LogChaos,
Warning,
TEXT(
"Attempt to upgrade a read lock to a write lock. This is not supported. Writes will be unsafe"))
802#if PHYSICS_THREAD_CONTEXT
819#if PHYSICS_THREAD_CONTEXT
835#if PHYSICS_THREAD_CONTEXT
865#if PHYSICS_THREAD_CONTEXT
873#if PHYSICS_THREAD_CONTEXT
882#if PHYSICS_THREAD_CONTEXT
891#if PHYSICS_THREAD_CONTEXT
905 template<
typename MutexType>
934 template<
typename MutexType>
960#if CHAOS_SCENE_LOCK_TYPE == CHAOS_SCENE_LOCK_SCENE_GUARD
962#elif CHAOS_SCENE_LOCK_TYPE == CHAOS_SCENE_LOCK_RWFIFO_SPINLOCK
964#elif CHAOS_SCENE_LOCK_TYPE == CHAOS_SCENE_LOCK_RWFIFO_CRITICALSECTION
966#elif CHAOS_SCENE_LOCK_TYPE == CHAOS_SCENE_LOCK_FRWLOCK
968#elif CHAOS_SCENE_LOCK_TYPE == CHAOS_SCENE_LOCK_SIMPLE_MUTEX
1007 if (AutoRTFM::IsTransactional())
1009 const AutoRTFM::EContextStatus Status = AutoRTFM::Close([
this]
1011 AutoRTFM::PushOnAbortHandler(
this, [
this]
1017 ensure(AutoRTFM::EContextStatus::OnTrack == Status);
1023 if (AutoRTFM::IsTransactional())
1025 const AutoRTFM::EContextStatus Status = AutoRTFM::Close([
this]
1027 AutoRTFM::PopOnAbortHandler(
this);
1033 ensure(0 == State.Object->TransactionalLockCount);
1037 ensure(AutoRTFM::EContextStatus::OnTrack == Status);
1041 AutoRTFM::Open([&] { State =
nullptr; });
1046 if (AutoRTFM::IsTransactional() || AutoRTFM::IsCommittingOrAborting())
1053 State->Lock.ReadLock();
1054 ensure(0 == State->TransactionalLockCount);
1060 if (AutoRTFM::IsTransactional() || AutoRTFM::IsCommittingOrAborting())
1067 ensure(0 == State->TransactionalLockCount);
1068 State->Lock.ReadUnlock();
1074 if (AutoRTFM::IsTransactional() || AutoRTFM::IsCommittingOrAborting())
1080 if (0 == State->TransactionalLockCount)
1082 State->Lock.WriteLock();
1085 State->TransactionalLockCount += 1;
1092 ensure(0 != State.Object->TransactionalLockCount);
1094 State.Object->TransactionalLockCount -= 1;
1096 if (0 == State.Object->TransactionalLockCount)
1098 State.Object->Lock.WriteUnlock();
1104 State->Lock.WriteLock();
1105 ensure(0 == State->TransactionalLockCount);
1111 if (AutoRTFM::IsTransactional() || AutoRTFM::IsCommittingOrAborting())
1117 ensure(0 != State.Object->TransactionalLockCount);
1119 State.Object->TransactionalLockCount -= 1;
1121 if (0 == State.Object->TransactionalLockCount)
1123 State.Object->Lock.WriteUnlock();
1129 ensure(0 == State->TransactionalLockCount);
1130 State->Lock.WriteUnlock();
1146#if UE_WITH_REMOTE_OBJECT_HANDLE
OODEFFUNC typedef void(OODLE_CALLBACK t_fp_OodleCore_Plugin_Free)(void *ptr)
#define checkSlow(expr)
Definition AssertionMacros.h:332
#define check(expr)
Definition AssertionMacros.h:314
#define ensureMsgf( InExpression, InFormat,...)
Definition AssertionMacros.h:465
#define ensure( InExpression)
Definition AssertionMacros.h:464
#define checkf(expr, format,...)
Definition AssertionMacros.h:315
#define UE_AUTORTFM_ALWAYS_OPEN
Definition AutoRTFMDefines.h:114
#define TRACE_CHAOS_ACQUIRE_LOCK(...)
Definition ChaosInsightsMacros.h:30
#define TRACE_CHAOS_BEGIN_LOCK(...)
Definition ChaosInsightsMacros.h:29
#define TRACE_CHAOS_END_LOCK(...)
Definition ChaosInsightsMacros.h:31
#define UE_NONCOPYABLE(TypeName)
Definition CoreMiscDefines.h:457
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
UE::FPlatformRecursiveMutex FCriticalSection
Definition CriticalSection.h:53
#define CSV_SCOPED_TIMING_STAT(Category, StatName)
Definition CsvProfiler.h:150
#define CHAOS_RECORD_ENTER_WRITE_LOCK
Definition Threading.h:158
#define CHAOS_RECORD_ENTER_READ_LOCK
Definition Threading.h:155
#define CHAOS_RECORD_LEAVE_WRITE_LOCK
Definition Threading.h:164
#define CHAOS_RECORD_LEAVE_READ_LOCK
Definition Threading.h:161
#define UE_LOG(CategoryName, Verbosity, Format,...)
Definition LogMacros.h:270
EChaosThreadingMode
Definition PhysicsCoreTypes.h:21
#define UE_DECLARE_THREAD_SINGLETON_TLS(Type, Api)
Definition ThreadSingleton.h:35
CORE_API bool IsInGameThread()
Definition ThreadingBase.cpp:185
FRWLock Lock
Definition UnversionedPropertySerialization.cpp:921
Definition OpenWrapper.h:28
Definition Threading.h:666
FPhysSpinLock()
Definition Threading.h:668
void Unlock()
Definition Threading.h:704
void Lock()
Definition Threading.h:675
Definition Threading.h:733
void WriteUnlock()
Definition Threading.h:825
void ReadUnlock()
Definition Threading.h:808
void ReadLock()
Definition Threading.h:765
FPhysicsRwLock()
Definition Threading.h:753
~FPhysicsRwLock()
Definition Threading.h:759
void WriteLock()
Definition Threading.h:784
Definition Threading.h:324
void WriteLock()
Definition Threading.h:367
~FPhysicsSceneGuard()
Definition Threading.h:332
FPhysicsSceneGuard(FPhysicsSceneGuard &&InOther)=delete
void WriteUnlock()
Definition Threading.h:417
FPhysicsSceneGuard(const FPhysicsSceneGuard &InOther)=delete
FPhysicsSceneGuard & operator=(const FPhysicsSceneGuard &InOther)=delete
void ReadUnlock()
Definition Threading.h:385
FPhysicsSceneGuard & operator=(FPhysicsSceneGuard &&InOther)=delete
void ReadLock()
Definition Threading.h:349
FPhysicsSceneGuard()
Definition Threading.h:326
Definition Threading.h:852
void ReadUnlock()
Definition Threading.h:878
void WriteLock()
Definition Threading.h:870
FPhysicsSimpleMutexLock()
Definition Threading.h:854
void WriteUnlock()
Definition Threading.h:887
~FPhysicsSimpleMutexLock()
Definition Threading.h:858
void ReadLock()
Definition Threading.h:862
Definition Threading.h:170
void DecGameThreadContext()
Definition Threading.h:198
void FreezeGameThreadContext()
Definition Threading.h:204
bool IsInPhysicsSimContext() const
Definition Threading.h:172
void IncGameThreadContext()
Definition Threading.h:193
void IncPhysicsSimContext()
Definition Threading.h:182
bool IsInGameThreadContext() const
Definition Threading.h:177
void DecPhysicsSimContext()
Definition Threading.h:187
void UnFreezeGameThreadContext()
Definition Threading.h:210
Definition Threading.h:500
~TMutexScopeLock()
Definition Threading.h:508
TMutexScopeLock(MutexType &InMutex)
Definition Threading.h:502
Definition Threading.h:936
TPhysicsSceneGuardScopedRead(MutexType &InMutex)
Definition Threading.h:938
~TPhysicsSceneGuardScopedRead()
Definition Threading.h:945
Definition Threading.h:907
TPhysicsSceneGuardScopedWrite(MutexType &InMutex)
Definition Threading.h:909
~TPhysicsSceneGuardScopedWrite()
Definition Threading.h:916
Definition Threading.h:537
TRwFifoLock()
Definition Threading.h:540
void WriteUnlock()
Definition Threading.h:640
void WriteLock()
Definition Threading.h:580
~TRwFifoLock()
Definition Threading.h:546
void ReadLock()
Definition Threading.h:551
void ReadUnlock()
Definition Threading.h:625
Definition SharedPointer.h:692
Definition ThreadSingleton.h:44
static FORCEINLINE FPhysicsThreadContext & Get()
Definition ThreadSingleton.h:101
Definition SkeletalMeshComponent.h:307
FORCEINLINE bool IsInPhysicsThreadContext()
Definition Threading.h:280
FORCEINLINE void EnsureIsInPhysicsThreadContext()
Definition Threading.h:290
FORCEINLINE void EnsureIsInGameThreadContext()
Definition Threading.h:295
FPhysicsRwLock FPhysSceneLockNonTransactional
Definition Threading.h:967
FPhysSceneLockNonTransactional FPhysSceneLock
Definition Threading.h:1204
FORCEINLINE bool IsInGameThreadContext()
Definition Threading.h:285
Definition Threading.h:267
~FFrozenGameThreadContextScope()
Definition Threading.h:273
FFrozenGameThreadContextScope()
Definition Threading.h:268
Definition Threading.h:245
bool bParentIsGameThreadContext
Definition Threading.h:263
FGameThreadContextScope(bool InParentIsGameThreadContext)
Definition Threading.h:246
~FGameThreadContextScope()
Definition Threading.h:255
Definition Threading.h:223
FPhysicsThreadContextScope(bool InParentIsPhysicsSimContext)
Definition Threading.h:224
bool bParentIsPhysicsSimContext
Definition Threading.h:241
~FPhysicsThreadContextScope()
Definition Threading.h:233
static uint32 GetCurrentThreadId(void)
Definition AndroidPlatformTLS.h:20
static uint32 AllocTlsSlot(void)
Definition AndroidPlatformTLS.h:30
static UE_FORCEINLINE_HINT void FreeTlsSlot(uint32 SlotIndex)
Definition AndroidPlatformTLS.h:67
static UE_FORCEINLINE_HINT void * GetTlsValue(uint32 SlotIndex)
Definition AndroidPlatformTLS.h:57
static UE_FORCEINLINE_HINT void SetTlsValue(uint32 SlotIndex, void *Value)
Definition AndroidPlatformTLS.h:47