mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 02:32:36 +01:00
Utilities\lockless.h: Flatten recusrion in lf_array
Add assert for sane index access.
This commit is contained in:
parent
4df58494a0
commit
935e83a490
@ -31,22 +31,45 @@ public:
|
|||||||
|
|
||||||
T& operator [](usz index)
|
T& operator [](usz index)
|
||||||
{
|
{
|
||||||
if (index < N) [[likely]]
|
lf_array* _this = this;
|
||||||
|
|
||||||
|
T* result{};
|
||||||
|
bool installed = false;
|
||||||
|
|
||||||
|
for (usz i = 0;; i += N)
|
||||||
{
|
{
|
||||||
return m_data[index];
|
if (index - i < N)
|
||||||
|
{
|
||||||
|
result = std::addressof(m_data[index - i]);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (!m_next) [[unlikely]]
|
|
||||||
|
lf_array* next = m_next;
|
||||||
|
|
||||||
|
if (!next)
|
||||||
{
|
{
|
||||||
// Create new array block. It's not a full-fledged once-synchronization, unlikely needed.
|
// Do not allow access beyond one element more at a time
|
||||||
for (auto _new = new lf_array, ptr = this; ptr;)
|
ensure(!installed && index - i == N);
|
||||||
|
|
||||||
|
installed = true;
|
||||||
|
|
||||||
|
for (auto _new = new lf_array, ptr = _this; ptr;)
|
||||||
{
|
{
|
||||||
// Install the pointer. If failed, go deeper.
|
// Install the pointer. If failed, go deeper.
|
||||||
ptr = ptr->m_next.compare_and_swap(nullptr, _new);
|
ptr = ptr->m_next.compare_and_swap(nullptr, _new);
|
||||||
|
|
||||||
|
if (!next)
|
||||||
|
{
|
||||||
|
// Determine the next pointer (if null then the new memory has been installed)
|
||||||
|
next = ptr ? ptr : _new;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Access recursively
|
_this = next;
|
||||||
return (*m_next)[index - N];
|
}
|
||||||
|
|
||||||
|
return *result;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 size() const
|
u64 size() const
|
||||||
|
Loading…
Reference in New Issue
Block a user