atomic_t<>: extend fetch_op to support cancellation

Use std::invoke inside atomic_op/fetch_op
Remove op_fetch because it's easily replaced
Add fetch_dec_sat algorithm (conditional decrement)
This commit is contained in:
Nekotekina 2018-09-05 22:28:37 +03:00
parent ed9fb8405b
commit fb5cdf9769
10 changed files with 80 additions and 60 deletions

View file

@ -1012,15 +1012,18 @@ void lv2_obj::sleep_timeout(named_thread& thread, u64 timeout)
{
LOG_TRACE(PPU, "sleep() - waiting (%zu)", g_pending.size());
auto state = ppu->state.fetch_op([&](auto& val)
const auto [_, ok] = ppu->state.fetch_op([&](bs_t<cpu_flag>& val)
{
if (!(val & cpu_flag::signal))
{
val += cpu_flag::suspend;
return true;
}
return false;
});
if (state & cpu_flag::signal)
if (!ok)
{
LOG_TRACE(PPU, "sleep() failed (signaled)");
return;

View file

@ -290,7 +290,7 @@ error_code _sys_lwcond_queue_wait(ppu_thread& ppu, u32 lwcond_id, u32 lwmutex_id
cond->waiters--;
if (mutex->signaled.fetch_op([](u32& v) { if (v) v--; }))
if (mutex->signaled.fetch_dec_sat())
{
ppu.gpr[3] = CELL_EDEADLK;
break;

View file

@ -66,20 +66,18 @@ struct lv2_memory_container
// Try to get specified amount of "physical" memory
u32 take(u32 amount)
{
const u32 old_value = used.fetch_op([&](u32& value)
auto [_, result] = used.fetch_op([&](u32& value) -> u32
{
if (size - value >= amount)
{
value += amount;
return amount;
}
return 0;
});
if (size - old_value >= amount)
{
return amount;
}
return 0;
return result;
}
};