12#if AGGRESSIVE_MEMORY_SAVING
13 #define LOCALQUEUEREGISTRYDEFAULTS_MAX_LOCALQUEUES 1024
14 #define LOCALQUEUEREGISTRYDEFAULTS_MAX_ITEMCOUNT 512
16 #define LOCALQUEUEREGISTRYDEFAULTS_MAX_LOCALQUEUES 1024
17 #define LOCALQUEUEREGISTRYDEFAULTS_MAX_ITEMCOUNT 1024
22namespace LocalQueue_Impl
24template<u
int32 NumItems>
40 uint32 Idx = (Head + 1) % NumItems;
41 uintptr_t Slot = ItemSlots[Idx].Value.load(std::memory_order_acquire);
45 ItemSlots[Idx].Value.store(Item, std::memory_order_release);
56 uint32 Idx = Head % NumItems;
57 uintptr_t Slot = ItemSlots[Idx].Value.load(std::memory_order_acquire);
59 if (Slot >
uintptr_t(ESlotState::Taken) && ItemSlots[Idx].
Value.compare_exchange_strong(Slot,
uintptr_t(ESlotState::Free), std::memory_order_acq_rel))
76 uintptr_t Slot = ItemSlots[Idx].Value.load(std::memory_order_acquire);
84 if (
IdxVer != Tail.load(std::memory_order_acquire))
90 else if (Slot !=
uintptr_t(ESlotState::Taken) && ItemSlots[Idx].
Value.compare_exchange_weak(Slot,
uintptr_t(ESlotState::Taken), std::memory_order_acq_rel))
92 if(
IdxVer == Tail.load(std::memory_order_acquire))
94 uint32 Prev = Tail.fetch_add(1, std::memory_order_release); (
void)Prev;
96 ItemSlots[Idx].Value.store(
uintptr_t(ESlotState::Free), std::memory_order_release);
100 ItemSlots[Idx].Value.store(Slot, std::memory_order_release);
106 struct FAlignedElement
116template<
typename Type, u
int32 NumItems>
119 using PointerType = Type*;
122 inline bool Put(PointerType Item)
127 inline bool Get(PointerType& Item)
132 inline bool Steal(PointerType& Item)
155template<u
int32 NumLocalItems = LOCALQUEUEREGISTRYDEFAULTS_MAX_ITEMCOUNT, u
int32 MaxLocalQueues = LOCALQUEUEREGISTRYDEFAULTS_MAX_LOCALQUEUES>
161 State = State * 747796405u + 2891336453u;
162 State = ((State >> ((State >> 28u) + 4u)) ^ State) * 277803737u;
163 return (State >> 22u) ^ State;
172 using DequeueHazard =
typename FOverflowQueueType::DequeueHazard;
177 template<u
int32, u
int32>
190 if (bIsInitialized.exchange(
true, std::memory_order_relaxed))
192 checkf(
false,
TEXT(
"Trying to initialize local queue more than once"));
203 DequeueHazards[PriorityIndex] =
Registry->OverflowQueues[PriorityIndex].getHeadHazard();
210 if (bIsInitialized.exchange(
false, std::memory_order_relaxed))
217 if (!LocalQueues[PriorityIndex].Get(Item))
221 Registry->OverflowQueues[PriorityIndex].enqueue(Item);
235 if (!LocalQueues[PriorityIndex].Put(Item))
237 Registry->OverflowQueues[PriorityIndex].enqueue(Item);
245 for (
int32 PriorityIndex = 0; PriorityIndex < MaxPriority; ++PriorityIndex)
248 if (LocalQueues[PriorityIndex].Steal(Item))
261 for (
int32 PriorityIndex = 0; PriorityIndex < MaxPriority; ++PriorityIndex)
264 if (LocalQueues[PriorityIndex].Get(Item))
269 Item =
Registry->OverflowQueues[PriorityIndex].dequeue(DequeueHazards[PriorityIndex]);
280 if (CachedRandomIndex == InvalidIndex)
282 CachedRandomIndex = Rand();
294 static constexpr uint32 InvalidIndex = ~0u;
298 uint32 CachedRandomIndex = InvalidIndex;
299 uint32 CachedPriorityIndex = 0;
301 std::atomic<bool> bIsInitialized =
false;
312 uint32 Index = NumLocalQueues.fetch_add(1, std::memory_order_relaxed);
323 uint32 NumQueues = NumLocalQueues.load(std::memory_order_relaxed);
325 CachedRandomIndex = CachedRandomIndex % NumQueues;
330 if (TLocalQueue* LocalQueue = LocalQueues[
Index].load(std::memory_order_acquire))
332 for(
uint32 PriorityIndex = 0; PriorityIndex < MaxPriority; PriorityIndex++)
335 if (LocalQueue->LocalQueues[PriorityIndex].Steal(Item))
339 CachedPriorityIndex = ++CachedPriorityIndex < MaxPriority ? CachedPriorityIndex : 0;
341 CachedRandomIndex = ++CachedRandomIndex <
NumQueues ? CachedRandomIndex : 0;
344 CachedPriorityIndex = 0;
345 CachedRandomIndex = TLocalQueue::InvalidIndex;
354 check(Item !=
nullptr);
356 OverflowQueues[PriorityIndex].
enqueue(Item);
364 for (
int32 PriorityIndex = 0; PriorityIndex < MaxPriority; ++PriorityIndex)
366 if (
FTask* Item = OverflowQueues[PriorityIndex].dequeue())
376 uint32 CachedRandomIndex = Rand();
377 uint32 CachedPriorityIndex = 0;
389 uint32 NumQueues = NumLocalQueues.load(std::memory_order_relaxed);
392 LocalQueues[
Index].store(0, std::memory_order_relaxed);
395 NumLocalQueues.store(0, std::memory_order_release);
400 std::atomic<TLocalQueue*> LocalQueues[
MaxLocalQueues] {
nullptr };
401 std::atomic<uint32> NumLocalQueues {0};
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 checkf(expr, format,...)
Definition AssertionMacros.h:315
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
void Init()
Definition LockFreeList.h:4
#define UE_CLOG(Condition, CategoryName, Verbosity, Format,...)
Definition LogMacros.h:298
void enqueue(T *item, EnqueueHazard &Hazard)
Definition FAAArrayQueue.h:209
Definition LocalQueue.h:118
bool Put(PointerType Item)
Definition LocalQueue.h:122
bool Steal(PointerType &Item)
Definition LocalQueue.h:132
bool Get(PointerType &Item)
Definition LocalQueue.h:127
Definition LocalQueue.h:26
bool Steal(uintptr_t &Item)
Definition LocalQueue.h:70
bool Put(uintptr_t Item)
Definition LocalQueue.h:35
bool Get(uintptr_t &Item)
Definition LocalQueue.h:54
Definition LocalQueue.h:176
FTask * StealLocal(bool GetBackGroundTasks)
Definition LocalQueue.h:241
FTask * Dequeue(bool GetBackGroundTasks)
Definition LocalQueue.h:257
void Init(TLocalQueueRegistry &InRegistry, ELocalQueueType InQueueType)
Definition LocalQueue.h:188
void Enqueue(FTask *Item, uint32 PriorityIndex)
Definition LocalQueue.h:229
~TLocalQueue()
Definition LocalQueue.h:208
FTask * DequeueSteal(bool GetBackGroundTasks)
Definition LocalQueue.h:278
TLocalQueue(TLocalQueueRegistry &InRegistry, ELocalQueueType InQueueType)
Definition LocalQueue.h:183
Definition LocalQueue.h:157
FTask * DequeueGlobal(bool GetBackGroundTasks=true)
Definition LocalQueue.h:360
TLocalQueueRegistry()
Definition LocalQueue.h:304
void Enqueue(FTask *Item, uint32 PriorityIndex)
Definition LocalQueue.h:351
FTask * DequeueSteal(bool GetBackGroundTasks)
Definition LocalQueue.h:374
void Reset()
Definition LocalQueue.h:387
@ NumQueues
Definition TaskGraphInterfaces.h:74
ELocalQueueType
Definition LocalQueue.h:142
Definition Scheduler.cpp:25
ETaskPriority
Definition Task.h:18
Definition OverriddenPropertySet.cpp:45
U16 Index
Definition radfft.cpp:71
static uint32 Cycles()
Definition AndroidPlatformTime.h:27