mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-03 21:41:26 +12:00
Remove dumb overloads of atomic_op, fetch_op
And lf_queue::apply. Fix inlining problem by passing F by value.
This commit is contained in:
parent
cf16ee5eb5
commit
4f22559ff0
3 changed files with 28 additions and 104 deletions
|
@ -388,27 +388,13 @@ public:
|
||||||
|
|
||||||
// Apply func(data) to each element, return the total length
|
// Apply func(data) to each element, return the total length
|
||||||
template <typename F>
|
template <typename F>
|
||||||
std::size_t apply(F&& func)
|
std::size_t apply(F func)
|
||||||
{
|
{
|
||||||
std::size_t count = 0;
|
std::size_t count = 0;
|
||||||
|
|
||||||
for (auto slice = pop_all(); slice; slice.pop_front())
|
for (auto slice = pop_all(); slice; slice.pop_front())
|
||||||
{
|
{
|
||||||
std::invoke(std::forward<F>(func), *slice);
|
std::invoke(func, *slice);
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
// apply() overload for callable template argument
|
|
||||||
template <auto F>
|
|
||||||
std::size_t apply()
|
|
||||||
{
|
|
||||||
std::size_t count = 0;
|
|
||||||
|
|
||||||
for (auto slice = pop_all(); slice; slice.pop_front())
|
|
||||||
{
|
|
||||||
std::invoke(F, *slice);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
|
|
|
@ -76,7 +76,7 @@ error_code cellSyncMutexLock(ppu_thread& ppu, vm::ptr<CellSyncMutex> mutex)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Increase acq value and remember its old value
|
// Increase acq value and remember its old value
|
||||||
const auto order = mutex->ctrl.atomic_op<&CellSyncMutex::Counter::lock_begin>();
|
const auto order = mutex->ctrl.atomic_op(&CellSyncMutex::Counter::lock_begin);
|
||||||
|
|
||||||
// Wait until rel value is equal to old acq value
|
// Wait until rel value is equal to old acq value
|
||||||
while (mutex->ctrl.load().rel != order)
|
while (mutex->ctrl.load().rel != order)
|
||||||
|
@ -105,7 +105,7 @@ error_code cellSyncMutexTryLock(vm::ptr<CellSyncMutex> mutex)
|
||||||
return CELL_SYNC_ERROR_ALIGN;
|
return CELL_SYNC_ERROR_ALIGN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mutex->ctrl.atomic_op<&CellSyncMutex::Counter::try_lock>())
|
if (!mutex->ctrl.atomic_op(&CellSyncMutex::Counter::try_lock))
|
||||||
{
|
{
|
||||||
return not_an_error(CELL_SYNC_ERROR_BUSY);
|
return not_an_error(CELL_SYNC_ERROR_BUSY);
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,7 @@ error_code cellSyncMutexUnlock(vm::ptr<CellSyncMutex> mutex)
|
||||||
return CELL_SYNC_ERROR_ALIGN;
|
return CELL_SYNC_ERROR_ALIGN;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex->ctrl.atomic_op<&CellSyncMutex::Counter::unlock>();
|
mutex->ctrl.atomic_op(&CellSyncMutex::Counter::unlock);
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
@ -171,7 +171,7 @@ error_code cellSyncBarrierNotify(ppu_thread& ppu, vm::ptr<CellSyncBarrier> barri
|
||||||
return CELL_SYNC_ERROR_ALIGN;
|
return CELL_SYNC_ERROR_ALIGN;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!barrier->ctrl.atomic_op<&CellSyncBarrier::try_notify>())
|
while (!barrier->ctrl.atomic_op(&CellSyncBarrier::try_notify))
|
||||||
{
|
{
|
||||||
if (ppu.test_stopped())
|
if (ppu.test_stopped())
|
||||||
{
|
{
|
||||||
|
@ -198,7 +198,7 @@ error_code cellSyncBarrierTryNotify(vm::ptr<CellSyncBarrier> barrier)
|
||||||
|
|
||||||
std::atomic_thread_fence(std::memory_order_acq_rel);
|
std::atomic_thread_fence(std::memory_order_acq_rel);
|
||||||
|
|
||||||
if (!barrier->ctrl.atomic_op<&CellSyncBarrier::try_notify>())
|
if (!barrier->ctrl.atomic_op(&CellSyncBarrier::try_notify))
|
||||||
{
|
{
|
||||||
return not_an_error(CELL_SYNC_ERROR_BUSY);
|
return not_an_error(CELL_SYNC_ERROR_BUSY);
|
||||||
}
|
}
|
||||||
|
@ -222,7 +222,7 @@ error_code cellSyncBarrierWait(ppu_thread& ppu, vm::ptr<CellSyncBarrier> barrier
|
||||||
|
|
||||||
std::atomic_thread_fence(std::memory_order_acq_rel);
|
std::atomic_thread_fence(std::memory_order_acq_rel);
|
||||||
|
|
||||||
while (!barrier->ctrl.atomic_op<&CellSyncBarrier::try_wait>())
|
while (!barrier->ctrl.atomic_op(&CellSyncBarrier::try_wait))
|
||||||
{
|
{
|
||||||
if (ppu.test_stopped())
|
if (ppu.test_stopped())
|
||||||
{
|
{
|
||||||
|
@ -249,7 +249,7 @@ error_code cellSyncBarrierTryWait(vm::ptr<CellSyncBarrier> barrier)
|
||||||
|
|
||||||
std::atomic_thread_fence(std::memory_order_acq_rel);
|
std::atomic_thread_fence(std::memory_order_acq_rel);
|
||||||
|
|
||||||
if (!barrier->ctrl.atomic_op<&CellSyncBarrier::try_wait>())
|
if (!barrier->ctrl.atomic_op(&CellSyncBarrier::try_wait))
|
||||||
{
|
{
|
||||||
return not_an_error(CELL_SYNC_ERROR_BUSY);
|
return not_an_error(CELL_SYNC_ERROR_BUSY);
|
||||||
}
|
}
|
||||||
|
@ -301,7 +301,7 @@ error_code cellSyncRwmRead(ppu_thread& ppu, vm::ptr<CellSyncRwm> rwm, vm::ptr<vo
|
||||||
}
|
}
|
||||||
|
|
||||||
// wait until `writers` is zero, increase `readers`
|
// wait until `writers` is zero, increase `readers`
|
||||||
while (!rwm->ctrl.atomic_op<&CellSyncRwm::try_read_begin>())
|
while (!rwm->ctrl.atomic_op(&CellSyncRwm::try_read_begin))
|
||||||
{
|
{
|
||||||
if (ppu.test_stopped())
|
if (ppu.test_stopped())
|
||||||
{
|
{
|
||||||
|
@ -313,7 +313,7 @@ error_code cellSyncRwmRead(ppu_thread& ppu, vm::ptr<CellSyncRwm> rwm, vm::ptr<vo
|
||||||
std::memcpy(buffer.get_ptr(), rwm->buffer.get_ptr(), rwm->size);
|
std::memcpy(buffer.get_ptr(), rwm->buffer.get_ptr(), rwm->size);
|
||||||
|
|
||||||
// decrease `readers`, return error if already zero
|
// decrease `readers`, return error if already zero
|
||||||
if (!rwm->ctrl.atomic_op<&CellSyncRwm::try_read_end>())
|
if (!rwm->ctrl.atomic_op(&CellSyncRwm::try_read_end))
|
||||||
{
|
{
|
||||||
return CELL_SYNC_ERROR_ABORT;
|
return CELL_SYNC_ERROR_ABORT;
|
||||||
}
|
}
|
||||||
|
@ -336,7 +336,7 @@ error_code cellSyncRwmTryRead(vm::ptr<CellSyncRwm> rwm, vm::ptr<void> buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
// increase `readers` if `writers` is zero
|
// increase `readers` if `writers` is zero
|
||||||
if (!rwm->ctrl.atomic_op<&CellSyncRwm::try_read_begin>())
|
if (!rwm->ctrl.atomic_op(&CellSyncRwm::try_read_begin))
|
||||||
{
|
{
|
||||||
return not_an_error(CELL_SYNC_ERROR_BUSY);
|
return not_an_error(CELL_SYNC_ERROR_BUSY);
|
||||||
}
|
}
|
||||||
|
@ -345,7 +345,7 @@ error_code cellSyncRwmTryRead(vm::ptr<CellSyncRwm> rwm, vm::ptr<void> buffer)
|
||||||
std::memcpy(buffer.get_ptr(), rwm->buffer.get_ptr(), rwm->size);
|
std::memcpy(buffer.get_ptr(), rwm->buffer.get_ptr(), rwm->size);
|
||||||
|
|
||||||
// decrease `readers`, return error if already zero
|
// decrease `readers`, return error if already zero
|
||||||
if (!rwm->ctrl.atomic_op<&CellSyncRwm::try_read_end>())
|
if (!rwm->ctrl.atomic_op(&CellSyncRwm::try_read_end))
|
||||||
{
|
{
|
||||||
return CELL_SYNC_ERROR_ABORT;
|
return CELL_SYNC_ERROR_ABORT;
|
||||||
}
|
}
|
||||||
|
@ -368,7 +368,7 @@ error_code cellSyncRwmWrite(ppu_thread& ppu, vm::ptr<CellSyncRwm> rwm, vm::cptr<
|
||||||
}
|
}
|
||||||
|
|
||||||
// wait until `writers` is zero, set to 1
|
// wait until `writers` is zero, set to 1
|
||||||
while (!rwm->ctrl.atomic_op<&CellSyncRwm::try_write_begin>())
|
while (!rwm->ctrl.atomic_op(&CellSyncRwm::try_write_begin))
|
||||||
{
|
{
|
||||||
if (ppu.test_stopped())
|
if (ppu.test_stopped())
|
||||||
{
|
{
|
||||||
|
@ -490,7 +490,7 @@ error_code cellSyncQueuePush(ppu_thread& ppu, vm::ptr<CellSyncQueue> queue, vm::
|
||||||
// copy data from the buffer at the position
|
// copy data from the buffer at the position
|
||||||
std::memcpy(&queue->buffer[position * queue->size], buffer.get_ptr(), queue->size);
|
std::memcpy(&queue->buffer[position * queue->size], buffer.get_ptr(), queue->size);
|
||||||
|
|
||||||
queue->ctrl.atomic_op<&CellSyncQueue::push_end>();
|
queue->ctrl.atomic_op(&CellSyncQueue::push_end);
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
@ -524,7 +524,7 @@ error_code cellSyncQueueTryPush(vm::ptr<CellSyncQueue> queue, vm::cptr<void> buf
|
||||||
// copy data from the buffer at the position
|
// copy data from the buffer at the position
|
||||||
std::memcpy(&queue->buffer[position * queue->size], buffer.get_ptr(), queue->size);
|
std::memcpy(&queue->buffer[position * queue->size], buffer.get_ptr(), queue->size);
|
||||||
|
|
||||||
queue->ctrl.atomic_op<&CellSyncQueue::push_end>();
|
queue->ctrl.atomic_op(&CellSyncQueue::push_end);
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
@ -561,7 +561,7 @@ error_code cellSyncQueuePop(ppu_thread& ppu, vm::ptr<CellSyncQueue> queue, vm::p
|
||||||
// copy data at the position to the buffer
|
// copy data at the position to the buffer
|
||||||
std::memcpy(buffer.get_ptr(), &queue->buffer[position % depth * queue->size], queue->size);
|
std::memcpy(buffer.get_ptr(), &queue->buffer[position % depth * queue->size], queue->size);
|
||||||
|
|
||||||
queue->ctrl.atomic_op<&CellSyncQueue::pop_end>();
|
queue->ctrl.atomic_op(&CellSyncQueue::pop_end);
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
@ -595,7 +595,7 @@ error_code cellSyncQueueTryPop(vm::ptr<CellSyncQueue> queue, vm::ptr<void> buffe
|
||||||
// copy data at the position to the buffer
|
// copy data at the position to the buffer
|
||||||
std::memcpy(buffer.get_ptr(), &queue->buffer[position % depth * queue->size], queue->size);
|
std::memcpy(buffer.get_ptr(), &queue->buffer[position % depth * queue->size], queue->size);
|
||||||
|
|
||||||
queue->ctrl.atomic_op<&CellSyncQueue::pop_end>();
|
queue->ctrl.atomic_op(&CellSyncQueue::pop_end);
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
@ -632,7 +632,7 @@ error_code cellSyncQueuePeek(ppu_thread& ppu, vm::ptr<CellSyncQueue> queue, vm::
|
||||||
// copy data at the position to the buffer
|
// copy data at the position to the buffer
|
||||||
std::memcpy(buffer.get_ptr(), &queue->buffer[position % depth * queue->size], queue->size);
|
std::memcpy(buffer.get_ptr(), &queue->buffer[position % depth * queue->size], queue->size);
|
||||||
|
|
||||||
queue->ctrl.atomic_op<&CellSyncQueue::pop_end>();
|
queue->ctrl.atomic_op(&CellSyncQueue::pop_end);
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
@ -666,7 +666,7 @@ error_code cellSyncQueueTryPeek(vm::ptr<CellSyncQueue> queue, vm::ptr<void> buff
|
||||||
// copy data at the position to the buffer
|
// copy data at the position to the buffer
|
||||||
std::memcpy(buffer.get_ptr(), &queue->buffer[position % depth * queue->size], queue->size);
|
std::memcpy(buffer.get_ptr(), &queue->buffer[position % depth * queue->size], queue->size);
|
||||||
|
|
||||||
queue->ctrl.atomic_op<&CellSyncQueue::pop_end>();
|
queue->ctrl.atomic_op(&CellSyncQueue::pop_end);
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
@ -706,7 +706,7 @@ error_code cellSyncQueueClear(ppu_thread& ppu, vm::ptr<CellSyncQueue> queue)
|
||||||
|
|
||||||
const u32 depth = queue->check_depth();
|
const u32 depth = queue->check_depth();
|
||||||
|
|
||||||
while (!queue->ctrl.atomic_op<&CellSyncQueue::try_clear_begin_1>())
|
while (!queue->ctrl.atomic_op(&CellSyncQueue::try_clear_begin_1))
|
||||||
{
|
{
|
||||||
if (ppu.test_stopped())
|
if (ppu.test_stopped())
|
||||||
{
|
{
|
||||||
|
@ -714,7 +714,7 @@ error_code cellSyncQueueClear(ppu_thread& ppu, vm::ptr<CellSyncQueue> queue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!queue->ctrl.atomic_op<&CellSyncQueue::try_clear_begin_2>())
|
while (!queue->ctrl.atomic_op(&CellSyncQueue::try_clear_begin_2))
|
||||||
{
|
{
|
||||||
if (ppu.test_stopped())
|
if (ppu.test_stopped())
|
||||||
{
|
{
|
||||||
|
|
|
@ -720,7 +720,7 @@ public:
|
||||||
|
|
||||||
// Atomic operation; returns old value, or pair of old value and return value (cancel op if evaluates to false)
|
// Atomic operation; returns old value, or pair of old value and return value (cancel op if evaluates to false)
|
||||||
template <typename F, typename RT = std::invoke_result_t<F, T&>>
|
template <typename F, typename RT = std::invoke_result_t<F, T&>>
|
||||||
std::conditional_t<std::is_void_v<RT>, type, std::pair<type, RT>> fetch_op(F&& func)
|
std::conditional_t<std::is_void_v<RT>, type, std::pair<type, RT>> fetch_op(F func)
|
||||||
{
|
{
|
||||||
type _new, old = atomic_storage<type>::load(m_data);
|
type _new, old = atomic_storage<type>::load(m_data);
|
||||||
|
|
||||||
|
@ -730,7 +730,7 @@ public:
|
||||||
|
|
||||||
if constexpr (std::is_void_v<RT>)
|
if constexpr (std::is_void_v<RT>)
|
||||||
{
|
{
|
||||||
std::invoke(std::forward<F>(func), _new);
|
std::invoke(func, _new);
|
||||||
|
|
||||||
if (LIKELY(atomic_storage<type>::compare_exchange(m_data, old, _new)))
|
if (LIKELY(atomic_storage<type>::compare_exchange(m_data, old, _new)))
|
||||||
{
|
{
|
||||||
|
@ -739,38 +739,7 @@ public:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RT ret = std::invoke(std::forward<F>(func), _new);
|
RT ret = std::invoke(func, _new);
|
||||||
|
|
||||||
if (LIKELY(!ret || atomic_storage<type>::compare_exchange(m_data, old, _new)))
|
|
||||||
{
|
|
||||||
return {old, std::move(ret)};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// fetch_op overload with function (invokable) provided as a template parameter
|
|
||||||
template <auto F, typename RT = std::invoke_result_t<decltype(F), T&>>
|
|
||||||
std::conditional_t<std::is_void_v<RT>, type, std::pair<type, RT>> fetch_op()
|
|
||||||
{
|
|
||||||
type _new, old = atomic_storage<type>::load(m_data);
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
_new = old;
|
|
||||||
|
|
||||||
if constexpr (std::is_void_v<RT>)
|
|
||||||
{
|
|
||||||
std::invoke(F, _new);
|
|
||||||
|
|
||||||
if (LIKELY(atomic_storage<type>::compare_exchange(m_data, old, _new)))
|
|
||||||
{
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RT ret = std::invoke(F, _new);
|
|
||||||
|
|
||||||
if (LIKELY(!ret || atomic_storage<type>::compare_exchange(m_data, old, _new)))
|
if (LIKELY(!ret || atomic_storage<type>::compare_exchange(m_data, old, _new)))
|
||||||
{
|
{
|
||||||
|
@ -782,7 +751,7 @@ public:
|
||||||
|
|
||||||
// Atomic operation; returns function result value, function is the lambda
|
// Atomic operation; returns function result value, function is the lambda
|
||||||
template <typename F, typename RT = std::invoke_result_t<F, T&>>
|
template <typename F, typename RT = std::invoke_result_t<F, T&>>
|
||||||
RT atomic_op(F&& func)
|
RT atomic_op(F func)
|
||||||
{
|
{
|
||||||
type _new, old = atomic_storage<type>::load(m_data);
|
type _new, old = atomic_storage<type>::load(m_data);
|
||||||
|
|
||||||
|
@ -792,7 +761,7 @@ public:
|
||||||
|
|
||||||
if constexpr (std::is_void_v<RT>)
|
if constexpr (std::is_void_v<RT>)
|
||||||
{
|
{
|
||||||
std::invoke(std::forward<F>(func), _new);
|
std::invoke(func, _new);
|
||||||
|
|
||||||
if (LIKELY(atomic_storage<type>::compare_exchange(m_data, old, _new)))
|
if (LIKELY(atomic_storage<type>::compare_exchange(m_data, old, _new)))
|
||||||
{
|
{
|
||||||
|
@ -801,38 +770,7 @@ public:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RT result = std::invoke(std::forward<F>(func), _new);
|
RT result = std::invoke(func, _new);
|
||||||
|
|
||||||
if (LIKELY(atomic_storage<type>::compare_exchange(m_data, old, _new)))
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// atomic_op overload with function (invokable) provided as a template parameter
|
|
||||||
template <auto F, typename RT = std::invoke_result_t<decltype(F), T&>>
|
|
||||||
RT atomic_op()
|
|
||||||
{
|
|
||||||
type _new, old = atomic_storage<type>::load(m_data);
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
_new = old;
|
|
||||||
|
|
||||||
if constexpr (std::is_void_v<RT>)
|
|
||||||
{
|
|
||||||
std::invoke(F, _new);
|
|
||||||
|
|
||||||
if (LIKELY(atomic_storage<type>::compare_exchange(m_data, old, _new)))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RT result = std::invoke(F, _new);
|
|
||||||
|
|
||||||
if (LIKELY(atomic_storage<type>::compare_exchange(m_data, old, _new)))
|
if (LIKELY(atomic_storage<type>::compare_exchange(m_data, old, _new)))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue