Skip to content

Commit 836cf38

Browse files
Tests and fixes.
1 parent 9e83fc9 commit 836cf38

6 files changed

Lines changed: 684 additions & 48 deletions

File tree

Engine/Source/CoreUtilities/Public/CoreUtilities/Containers/AtomicHashTable.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,14 @@ class AtomicHashTable
5959
ValueType Exchange(const ValueType& inValue, std::memory_order memoryOrder);
6060

6161
std::atomic<uint64_t> key;
62+
std::atomic_flag valueAvailableFlag;
6263
StoredValueType value;
6364
};
6465

6566
size_t GetStartIndex(uint64_t hash) const;
6667
template<typename KeyType> uint64_t HashKey(const KeyType& key) const;
6768

68-
Vector<Slot> m_slots;
69+
Vector<Slot, typename AllocatorType> m_slots;
6970
std::atomic<uint64_t> m_size;
7071
};
7172

Engine/Source/CoreUtilities/Public/CoreUtilities/Containers/AtomicHashTable.inl

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ inline bool AtomicHashTable<ValueType, AllocatorType>::Insert(const KeyType& key
1919
uint64_t existing = slot.key.load(std::memory_order::acquire);
2020

2121
// Key exists in table, insert new value
22-
if (existing == key)
22+
if (existing == keyHash)
2323
{
2424
slot.Store(value, std::memory_order::release);
2525
return true;
@@ -136,16 +136,7 @@ inline Optional<ValueType> AtomicHashTable<ValueType, AllocatorType>::GetOrInser
136136
// We need to do a brief wait to ensure the value has bee written.
137137
if (claimExpected == keyHash)
138138
{
139-
std::atomic_thread_fence(std::memory_order::acquire);
140-
141-
ValueType v{};
142-
143-
for (int32_t spin = 0; spin < 1024; ++spin)
144-
{
145-
v = claimSlot.Get(std::memory_order::acquire);
146-
}
147-
148-
139+
ValueType v = claimSlot.Get(std::memory_order::acquire);
149140
return v;
150141
}
151142

@@ -186,6 +177,7 @@ inline bool AtomicHashTable<ValueType, AllocatorType>::Erase(const KeyType& key)
186177
{
187178
// Reset value.
188179
slot.Store({}, std::memory_order::release);
180+
slot.valueAvailableFlag.clear(std::memory_order::release);
189181
m_size.fetch_sub(1, std::memory_order::relaxed);
190182
return true;
191183
}
@@ -319,11 +311,17 @@ inline void AtomicHashTable<ValueType, AllocatorType>::Slot::Store(const ValueTy
319311
{
320312
value = inValue;
321313
}
314+
315+
valueAvailableFlag.test_and_set(std::memory_order::acquire);
316+
valueAvailableFlag.notify_all();
322317
}
323318

324319
template<typename ValueType, typename AllocatorType>
325320
inline ValueType AtomicHashTable<ValueType, AllocatorType>::Slot::Get(std::memory_order memoryOrder) const
326321
{
322+
// Ensure that the value has been written
323+
valueAvailableFlag.wait(false, std::memory_order::acquire);
324+
327325
if constexpr (ValueTypeCanBeAtomic)
328326
{
329327
return value.load(memoryOrder);

0 commit comments

Comments
 (0)