UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
SharedMutex.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "CoreTypes.h"
7#include <atomic>
8
9#define UE_API CORE_API
10
11namespace UE
12{
13
21class FSharedMutex final
22{
23public:
24 constexpr FSharedMutex() = default;
25
26 FSharedMutex(const FSharedMutex&) = delete;
28
29 [[nodiscard]] inline bool IsLocked() const
30 {
31 return !!(State.load(std::memory_order_relaxed) & IsLockedFlag);
32 }
33
34 [[nodiscard]] inline bool TryLock()
35 {
36 uint32 Expected = State.load(std::memory_order_relaxed);
37 return !(Expected & (IsLockedFlag | SharedLockCountMask)) &&
38 State.compare_exchange_strong(Expected, Expected | IsLockedFlag,
39 std::memory_order_acquire, std::memory_order_relaxed);
40 }
41
42 inline void Lock()
43 {
44 uint32 Expected = 0;
45 if (LIKELY(State.compare_exchange_weak(Expected, IsLockedFlag, std::memory_order_acquire, std::memory_order_relaxed)))
46 {
47 return;
48 }
49 LockSlow();
50 }
51
52 inline void Unlock()
53 {
54 // Unlock immediately to allow other threads to acquire the lock while this thread looks for a thread to wake.
55 uint32 LastState = State.fetch_sub(IsLockedFlag, std::memory_order_release);
56 checkSlow(LastState & IsLockedFlag);
57 if (LIKELY(!(LastState & (MayHaveWaitingLockFlag | MayHaveWaitingSharedLockFlag))))
58 {
59 return;
60 }
61 WakeWaitingThreads(LastState);
62 }
63
64 [[nodiscard]] inline bool IsLockShared() const
65 {
66 return !!(State.load(std::memory_order_relaxed) & SharedLockCountMask);
67 }
68
69 [[nodiscard]] inline bool TryLockShared()
70 {
71 uint32 Expected = State.load(std::memory_order_relaxed);
72 while (LIKELY(!(Expected & (IsLockedFlag | MayHaveWaitingLockFlag))))
73 {
74 if (LIKELY(State.compare_exchange_weak(Expected, Expected + (1 << SharedLockCountShift),
75 std::memory_order_acquire, std::memory_order_relaxed)))
76 {
77 return true;
78 }
79 }
80 return false;
81 }
82
83 inline void LockShared()
84 {
85 uint32 Expected = State.load(std::memory_order_relaxed);
86 if (LIKELY(!(Expected & (IsLockedFlag | MayHaveWaitingLockFlag)) &&
87 State.compare_exchange_weak(Expected, Expected + (1 << SharedLockCountShift),
88 std::memory_order_acquire, std::memory_order_relaxed)))
89 {
90 return;
91 }
92 LockSharedSlow();
93 }
94
95 inline void UnlockShared()
96 {
97 // Unlock immediately to allow other threads to acquire the lock while this thread looks for a thread to wake.
98 const uint32 LastState = State.fetch_sub(1 << SharedLockCountShift, std::memory_order_release);
99 checkSlow(LastState & SharedLockCountMask);
100 constexpr uint32 WakeState = MayHaveWaitingLockFlag | (1 << SharedLockCountShift);
101 if (LIKELY((LastState & ~MayHaveWaitingSharedLockFlag) != WakeState))
102 {
103 return;
104 }
105 WakeWaitingThread();
106 }
107
108private:
109 UE_API void LockSlow();
110 UE_API void LockSharedSlow();
111 UE_API void WakeWaitingThread();
112 UE_API void WakeWaitingThreads(uint32 LastState);
113
114 const void* GetSharedLockAddress() const;
115
116 struct FParams;
117
118 static constexpr uint32 IsLockedFlag = 1 << 0;
119 static constexpr uint32 MayHaveWaitingLockFlag = 1 << 1;
120 static constexpr uint32 MayHaveWaitingSharedLockFlag = 1 << 2;
121 static constexpr uint32 SharedLockCountShift = 3;
122 static constexpr uint32 SharedLockCountMask = 0xffff'fff8;
123
124 std::atomic<uint32> State = 0;
125};
126
127} // UE
128
129#undef UE_API
#define checkSlow(expr)
Definition AssertionMacros.h:332
#define LIKELY(x)
Definition CityHash.cpp:107
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define UE_API
Definition SColorGradingComponentViewer.h:12
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition SharedMutex.h:22
bool IsLockShared() const
Definition SharedMutex.h:64
void LockShared()
Definition SharedMutex.h:83
bool TryLock()
Definition SharedMutex.h:34
bool IsLocked() const
Definition SharedMutex.h:29
FSharedMutex(const FSharedMutex &)=delete
void Lock()
Definition SharedMutex.h:42
void Unlock()
Definition SharedMutex.h:52
constexpr FSharedMutex()=default
void UnlockShared()
Definition SharedMutex.h:95
bool TryLockShared()
Definition SharedMutex.h:69
FSharedMutex & operator=(const FSharedMutex &)=delete
Definition AdvancedWidgetsModule.cpp:13