mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-12 04:14:35 +00: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
@ -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)
|
||||
{
|
||||
// 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 auto slot = slot_get(iptr, &s_hashtable[(iptr) % s_hashtable_size]);
|
||||
|
Loading…
x
Reference in New Issue
Block a user