mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-03 13:31:27 +12:00
atomic.cpp: upgrade raw_notify()
Now it searches all semaphores if data arg is nullptr. Also it tries to wake up all threads if thread_id is 0.
This commit is contained in:
parent
ad4df2d946
commit
0a5742587a
1 changed files with 61 additions and 0 deletions
|
@ -977,6 +977,67 @@ void atomic_wait_engine::set_notify_callback(void(*cb)(const void*, u64))
|
||||||
|
|
||||||
bool atomic_wait_engine::raw_notify(const void* data, u64 thread_id)
|
bool atomic_wait_engine::raw_notify(const void* data, u64 thread_id)
|
||||||
{
|
{
|
||||||
|
// Special operation mode. Note that this is not atomic.
|
||||||
|
if (!data)
|
||||||
|
{
|
||||||
|
// Special path: search thread_id without pointer information
|
||||||
|
for (u32 i = 1; i < UINT16_MAX; i++)
|
||||||
|
{
|
||||||
|
const auto [_, ok] = s_cond_refs[i].fetch_op([&](u32& ref)
|
||||||
|
{
|
||||||
|
if (!ref)
|
||||||
|
{
|
||||||
|
// Skip dead semaphores
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thread_id)
|
||||||
|
{
|
||||||
|
u64 tid = 0;
|
||||||
|
std::memcpy(&tid, &cond_get(i)->tid, sizeof(tid));
|
||||||
|
|
||||||
|
if (tid != thread_id)
|
||||||
|
{
|
||||||
|
// Check thread first without locking (memory may be uninitialized)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ref < UINT32_MAX)
|
||||||
|
{
|
||||||
|
// Need to busy loop otherwise (TODO)
|
||||||
|
ref++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (ok) [[unlikely]]
|
||||||
|
{
|
||||||
|
const auto cond = cond_get(i);
|
||||||
|
|
||||||
|
if (!thread_id || cond->tid == thread_id)
|
||||||
|
{
|
||||||
|
if (cond->forced_wakeup())
|
||||||
|
{
|
||||||
|
cond->alert_native();
|
||||||
|
|
||||||
|
if (thread_id)
|
||||||
|
{
|
||||||
|
// Only if thread_id is speficied, stop only it and return true.
|
||||||
|
cond_free(i);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cond_free(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const std::uintptr_t iptr = reinterpret_cast<std::uintptr_t>(data);
|
const std::uintptr_t iptr = reinterpret_cast<std::uintptr_t>(data);
|
||||||
|
|
||||||
const auto slot = slot_get(iptr, &s_hashtable[(iptr) % s_hashtable_size]);
|
const auto slot = slot_get(iptr, &s_hashtable[(iptr) % s_hashtable_size]);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue