8#define ENABLE_MT_DETECTOR DO_CHECK
12#include "Containers/Array.h"
37 friend struct ::FRWAccessDetector;
38 friend class ::FMRSWRecursiveAccessDetector;
39 friend class ::UE::Private::FMTAccessDetectorSuppressCheckFailuresForUnitTests;
58 checkf(
AtomicValue.load(std::memory_order_relaxed) == 0,
TEXT(
"Detector cannot be destroyed while other threads access it"));
63 checkf(
Other.AtomicValue.load(std::memory_order_relaxed) == 0,
TEXT(
"Detector cannot be \"moved out\" while other threads access it"));
68 checkf(
AtomicValue.load(std::memory_order_relaxed) == 0,
TEXT(
"Detector cannot be modified while other threads access it"));
69 checkf(
Other.AtomicValue.load(std::memory_order_relaxed) == 0,
TEXT(
"Detector cannot be \"moved out\" while other threads access it"));
75 checkf(
Other.AtomicValue.load(std::memory_order_relaxed) == 0,
TEXT(
"Detector cannot be copied while other threads access it"));
80 checkf(
AtomicValue.load(std::memory_order_relaxed) == 0,
TEXT(
"Detector cannot be modified while other threads access it"));
81 checkf(
Other.AtomicValue.load(std::memory_order_relaxed) == 0,
TEXT(
"Detector cannot be copied while other threads access it"));
92 checkf(!
ErrorDetected || UE::Private::FMTAccessDetectorOptions::bSuppressCheckFailure,
TEXT(
"Acquiring a read access while there is already a write access"));
103 checkf(!
ErrorDetected || UE::Private::FMTAccessDetectorOptions::bSuppressCheckFailure,
TEXT(
"Another thread asked to have a write access during this read access"));
114 checkf(!
ErrorDetected || UE::Private::FMTAccessDetectorOptions::bSuppressCheckFailure,
TEXT(
"Acquiring a write access while there are ongoing read or write access"));
125 checkf(!
ErrorDetected || UE::Private::FMTAccessDetectorOptions::bSuppressCheckFailure,
TEXT(
"Another thread asked to have a read or write access during this write access"));
139 checkf(UE::Private::FMTAccessDetectorOptions::bSuppressCheckFailure,
TEXT(
"Upgrading a write access while there are ongoing read or write access"));
178 else if (FRWAccessDetector::AcquireWriteAccess())
180 check(RecursiveDepth == 0);
197 check(RecursiveDepth > 0);
200 if (RecursiveDepth == 0)
203 return FRWAccessDetector::ReleaseWriteAccess();
211 return FRWAccessDetector::ReleaseWriteAccess();
217 mutable int32 RecursiveDepth = 0;
237 return FRWAccessDetector::AcquireReadAccess();
251 return FRWAccessDetector::ReleaseReadAccess();
259template<
typename RWAccessDetector>
278template<
typename RWAccessDetector>
284template<
typename RWAccessDetector>
302template<
typename RWAccessDetector>
317 static constexpr uint32 InvalidThreadId = 0;
333 static_assert(
sizeof(FState) ==
sizeof(
uint64));
360 mutable std::atomic<uint64>
State{ 0 };
364 return FState(
State.load(std::memory_order_relaxed));
369 return FState(
State.exchange(NewState.Value, std::memory_order_relaxed));
375 return FState(
State.fetch_add(
OneReader.Value, std::memory_order_relaxed));
381 return FState(
State.fetch_sub(
OneReader.Value, std::memory_order_relaxed));
386 return L.Value ==
R.Value;
394 if (
InState.GetWriterThreadId() != CurrentThreadId)
396 ensureMsgf(UE::Private::FMTAccessDetectorOptions::bSuppressCheckFailure,
397 TEXT(
"Data race detected! Acquiring read access on thread %u concurrently with %d writers on thread %u:\nCurrent thread %u callstack:\n%s\nWriter thread %u callstack:\n%s"),
410 const SIZE_T StackTraceSize = 65536;
411 ANSICHAR StackTrace[StackTraceSize] = { 0 };
418 if (ThreadId ==
uint32(-1))
420 return TEXT(
"[none]");
429 const SIZE_T StackTraceSize = 65536;
430 ANSICHAR StackTrace[StackTraceSize] = { 0 };
453 bool bDestroyed =
false;
484 TEXT(
"Either invalid usage of the access detector (no matching AcquireReadAccess()) or the access detector was trivially relocated (this instance is not registered): %u readers, %u writers on thread %u:\nCurrent thread %u callstack:\n%s"),
549 ensureMsgf(UE::Private::FMTAccessDetectorOptions::bSuppressCheckFailure,
550 TEXT(
"Race detector destroyed while being accessed on another thread: %d readers, %d writers on thread %u:\nCurrent thread %u callstack:\n%s\nWriter thread %u callstack:\n%s"),
618 if (LocalState.ReaderNum >= 1)
624 ensureMsgf(UE::Private::FMTAccessDetectorOptions::bSuppressCheckFailure,
625 TEXT(
"Either a race detected (%u reader(s) on another thread(s) while acquiring write access on the current thread) or the access detector was trivially relocated:\nCurrent thread %u callstack:\n%s"),
633 ensureMsgf(UE::Private::FMTAccessDetectorOptions::bSuppressCheckFailure,
634 TEXT(
"Data race detected: %d reader(s) on another thread(s) while acquiring write access.\nCurrent thread %u callstack:\n%s"),
642 if (LocalState.WriterNum != 0)
644 if (LocalState.GetWriterThreadId() != CurrentThreadId)
646 ensureMsgf(UE::Private::FMTAccessDetectorOptions::bSuppressCheckFailure,
647 TEXT(
"Data race detected: acquiring write access on thread %u concurrently with %d writers on thread %u:\nCurrent thread %u callstack:\n%s\nWriter thread %u callstack:\n%s"),
648 CurrentThreadId, LocalState.WriterNum, LocalState.GetWriterThreadId(),
656 FState NewState{ LocalState.ReaderNum, LocalState.WriterNum + 1u, CurrentThreadId + 1 };
661 ensureMsgf(UE::Private::FMTAccessDetectorOptions::bSuppressCheckFailure,
662 TEXT(
"Data race detected: other thread(s) activity during acquiring write access on thread %u: %u -> %u readers, %u -> %u writers on thread %u -> %u:\nCurrent thread %u callstack:\n%s\nWriter thread %u callstack:\n%s"),
664 LocalState.ReaderNum,
PrevState.ReaderNum,
665 LocalState.WriterNum,
PrevState.WriterNum,
666 LocalState.GetWriterThreadId(),
PrevState.GetWriterThreadId(),
690 uint32 WriterThreadId = LocalState.WriterNum != 1 ? LocalState.WriterThreadId : InvalidThreadId;
691 FState NewState{ LocalState.ReaderNum, LocalState.WriterNum - 1u,
WriterThreadId };
696 ensureMsgf(UE::Private::FMTAccessDetectorOptions::bSuppressCheckFailure,
697 TEXT(
"Data race detected: other thread(s) activity during releasing write access on thread %d: %u -> %u readers, %u -> %u writers on thread %u -> %u\nCurrent thread %u callstack:\n%s\nWriter thread %u callstack:\n%s"),
699 LocalState.ReaderNum,
PrevState.ReaderNum,
700 LocalState.WriterNum,
PrevState.WriterNum,
701 LocalState.GetWriterThreadId(),
PrevState.GetWriterThreadId(),
730#define UE_MT_DECLARE_RW_ACCESS_DETECTOR(AccessDetector) FRWAccessDetector AccessDetector
731#define UE_MT_DECLARE_RW_RECURSIVE_ACCESS_DETECTOR(AccessDetector) FRWRecursiveAccessDetector AccessDetector
732#define UE_MT_DECLARE_RW_FULLY_RECURSIVE_ACCESS_DETECTOR(AccessDetector) FRWFullyRecursiveAccessDetector AccessDetector
733#define UE_MT_DECLARE_MRSW_RECURSIVE_ACCESS_DETECTOR(AccessDetector) FMRSWRecursiveAccessDetector AccessDetector
735#define UE_MT_SCOPED_READ_ACCESS(AccessDetector) const FBaseScopedAccessDetector& PREPROCESSOR_JOIN(ScopedMTAccessDetector_,__LINE__) = MakeScopedReaderAccessDetector(AccessDetector)
736#define UE_MT_SCOPED_WRITE_ACCESS(AccessDetector) const FBaseScopedAccessDetector& PREPROCESSOR_JOIN(ScopedMTAccessDetector_,__LINE__) = MakeScopedWriterAccessDetector(AccessDetector)
738#define UE_MT_ACQUIRE_READ_ACCESS(AccessDetector) (AccessDetector).AcquireReadAccess()
739#define UE_MT_RELEASE_READ_ACCESS(AccessDetector) (AccessDetector).ReleaseReadAccess()
740#define UE_MT_ACQUIRE_WRITE_ACCESS(AccessDetector) (AccessDetector).AcquireWriteAccess()
741#define UE_MT_RELEASE_WRITE_ACCESS(AccessDetector) (AccessDetector).ReleaseWriteAccess()
745#define UE_MT_DECLARE_RW_ACCESS_DETECTOR(AccessDetector)
746#define UE_MT_DECLARE_RW_RECURSIVE_ACCESS_DETECTOR(AccessDetector)
747#define UE_MT_DECLARE_RW_FULLY_RECURSIVE_ACCESS_DETECTOR(AccessDetector)
748#define UE_MT_DECLARE_MRSW_RECURSIVE_ACCESS_DETECTOR(AccessDetector)
750#define UE_MT_SCOPED_READ_ACCESS(AccessDetector)
751#define UE_MT_SCOPED_WRITE_ACCESS(AccessDetector)
753#define UE_MT_ACQUIRE_READ_ACCESS(AccessDetector)
754#define UE_MT_RELEASE_READ_ACCESS(AccessDetector)
755#define UE_MT_ACQUIRE_WRITE_ACCESS(AccessDetector)
756#define UE_MT_RELEASE_WRITE_ACCESS(AccessDetector)
#define checkSlow(expr)
Definition AssertionMacros.h:332
#define checkfSlow(expr, format,...)
Definition AssertionMacros.h:333
#define check(expr)
Definition AssertionMacros.h:314
#define ensureMsgf( InExpression, InFormat,...)
Definition AssertionMacros.h:465
#define checkf(expr, format,...)
Definition AssertionMacros.h:315
bool bSuccess
Definition ConvexDecomposition3.cpp:819
@ INDEX_NONE
Definition CoreMiscDefines.h:150
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define ANSI_TO_TCHAR(str)
Definition StringConv.h:1020
void LoadState(const FString &IniName)
Definition Scalability.cpp:1172
bool operator==(const FCachedAssetKey &A, const FCachedAssetKey &B)
Definition AssetDataMap.h:501
State
Definition PacketHandler.h:88
Definition PackageReader.cpp:44
static uint32 GetCurrentThreadId(void)
Definition AndroidPlatformTLS.h:20