18template <
typename ParamsType>
21template <
typename ParamsType,
typename StateType = TIntrusiveMutexStateType_T<ParamsType>>
37 (!
requires { ParamsType::IsLockedMask; }) ||
43 (!
requires { ParamsType::SpinLimit; }) ||
49 (!
requires { ParamsType::GetWaitAddress; }) ||
50 requires(std::atomic<StateType>& State) { { ParamsType::GetWaitAddress(State) } ->
CDecaysTo<const void*>; };
59template <CIntrusiveMutexParams ParamsType>
66 constexpr static StateType IsLockedFlag = ParamsType::IsLockedFlag;
67 constexpr static StateType MayHaveWaitingLockFlag = ParamsType::MayHaveWaitingLockFlag;
69 constexpr static StateType IsLockedMask = []
71 if constexpr (
requires { ParamsType::IsLockedMask; })
73 return ParamsType::IsLockedMask;
77 return ParamsType::IsLockedFlag;
81 constexpr static int32 SpinLimit = []
83 if constexpr (
requires { ParamsType::SpinLimit; })
85 return ParamsType::SpinLimit;
93 static_assert(IsLockedFlag && (IsLockedFlag & (IsLockedFlag - 1)) == 0,
"IsLockedFlag must be one bit.");
94 static_assert(MayHaveWaitingLockFlag && (MayHaveWaitingLockFlag & (MayHaveWaitingLockFlag - 1)) == 0,
"MayHaveWaitingLockFlag must be one bit.");
95 static_assert(IsLockedFlag != MayHaveWaitingLockFlag,
"IsLockedFlag and MayHaveWaitingLockFlag must be different bits.");
96 static_assert((IsLockedMask & IsLockedFlag) == IsLockedFlag,
"IsLockedMask must contain IsLockedFlag.");
97 static_assert((IsLockedMask & MayHaveWaitingLockFlag) == 0,
"IsLockedMask must not contain MayHaveWaitingLockFlag.");
98 static_assert(SpinLimit >= 0,
"SpinLimit must be non-negative.");
100 FORCEINLINE static const void* GetWaitAddress(
const std::atomic<StateType>& State)
102 if constexpr (
requires { ParamsType::GetWaitAddress; })
104 return ParamsType::GetWaitAddress(State);
115 return !!(State.load(std::memory_order_relaxed) & IsLockedFlag);
120 StateType Expected = State.load(std::memory_order_relaxed);
121 return !(Expected & IsLockedMask) &&
122 State.compare_exchange_strong(Expected, Expected | IsLockedFlag, std::memory_order_acquire, std::memory_order_relaxed);
128 if (
LIKELY(State.compare_exchange_weak(Expected, Expected | IsLockedFlag, std::memory_order_acquire, std::memory_order_relaxed)))
138 for (StateType CurrentState = State.load(std::memory_order_relaxed);;)
142 if (
LIKELY(!(CurrentState & IsLockedMask)))
144 if (
LIKELY(State.compare_exchange_weak(CurrentState, CurrentState | IsLockedFlag, std::memory_order_acquire, std::memory_order_relaxed)))
152 if (
LIKELY(!(CurrentState & MayHaveWaitingLockFlag) && SpinCount < SpinLimit))
156 CurrentState = State.load(std::memory_order_relaxed);
161 if (
LIKELY(!(CurrentState & MayHaveWaitingLockFlag)))
163 if (
UNLIKELY(!State.compare_exchange_weak(CurrentState, CurrentState | MayHaveWaitingLockFlag, std::memory_order_relaxed)))
167 CurrentState |= MayHaveWaitingLockFlag;
177 const StateType NewState = State.load(std::memory_order_relaxed);
178 return (NewState & IsLockedMask) && (NewState & MayHaveWaitingLockFlag);
180 CurrentState = State.load(std::memory_order_relaxed);
187 const StateType
LastState = State.fetch_sub(IsLockedFlag, std::memory_order_release);
203 State.fetch_and(~MayHaveWaitingLockFlag, std::memory_order_relaxed);
211 bool bDidWake =
false;
218 State.fetch_and(~MayHaveWaitingLockFlag, std::memory_order_relaxed);
227 FORCENOINLINE static void LockSlow(std::atomic<StateType>& State)
232 FORCENOINLINE static void UnlockSlow(std::atomic<StateType>& State)
#define LIKELY(x)
Definition CityHash.cpp:107
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
Definition Oversubscription.h:23
Definition IntrusiveMutex.h:61
static FORCEINLINE void Unlock(std::atomic< StateType > &State)
Definition IntrusiveMutex.h:184
static FORCEINLINE bool TryLock(std::atomic< StateType > &State)
Definition IntrusiveMutex.h:118
static FORCEINLINE bool IsLocked(const std::atomic< StateType > &State)
Definition IntrusiveMutex.h:113
static FORCEINLINE bool TryWakeWaitingThread(std::atomic< StateType > &State)
Definition IntrusiveMutex.h:209
static FORCEINLINE void LockLoop(std::atomic< StateType > &State)
Definition IntrusiveMutex.h:135
static FORCEINLINE void Lock(std::atomic< StateType > &State)
Definition IntrusiveMutex.h:125
static FORCEINLINE void WakeWaitingThread(std::atomic< StateType > &State)
Definition IntrusiveMutex.h:195
Definition IntrusiveMutex.h:22
FWaitState Wait(const void *Address, TFunctionWithContext< bool()> CanWait, TFunctionWithContext< void()> BeforeWait)
Definition ParkingLot.h:52
Definition AdvancedWidgetsModule.cpp:13
std::decay_t< decltype(ParamsType::IsLockedFlag)> TIntrusiveMutexStateType_T
Definition IntrusiveMutex.h:19
Definition ParkingLot.h:30