mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-03 13:31:27 +12:00
atomic.hpp: fix signal saturation logic
Make sure to notify_all at max signal count.
This commit is contained in:
parent
92a75cfa80
commit
67f31c17d1
1 changed files with 21 additions and 8 deletions
|
@ -284,6 +284,8 @@ void atomic_storage_futex::notify_one(const void* data)
|
||||||
|
|
||||||
atomic_t<u64>& entry = s_hashtable[iptr % s_hashtable_size];
|
atomic_t<u64>& entry = s_hashtable[iptr % s_hashtable_size];
|
||||||
|
|
||||||
|
bool fallback = false;
|
||||||
|
|
||||||
const auto [prev, ok] = entry.fetch_op([&](u64& value)
|
const auto [prev, ok] = entry.fetch_op([&](u64& value)
|
||||||
{
|
{
|
||||||
if (value & s_waiter_mask && (value & s_pointer_mask) == (iptr & s_pointer_mask))
|
if (value & s_waiter_mask && (value & s_pointer_mask) == (iptr & s_pointer_mask))
|
||||||
|
@ -305,30 +307,41 @@ void atomic_storage_futex::notify_one(const void* data)
|
||||||
}
|
}
|
||||||
|
|
||||||
value += s_signal_mask & -s_signal_mask;
|
value += s_signal_mask & -s_signal_mask;
|
||||||
|
|
||||||
|
if ((value & s_signal_mask) == s_signal_mask)
|
||||||
|
{
|
||||||
|
// Signal will overflow, fallback
|
||||||
|
fallback = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (value & s_waiter_mask && (value & s_pointer_mask) == s_pointer_mask)
|
||||||
|
{
|
||||||
|
// Collision, notify everything
|
||||||
|
fallback = true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (fallback)
|
||||||
|
{
|
||||||
|
notify_all(data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (ok)
|
if (ok)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
NtReleaseKeyedEvent(nullptr, &entry, false, nullptr);
|
NtReleaseKeyedEvent(nullptr, &entry, false, nullptr);
|
||||||
return;
|
|
||||||
#else
|
#else
|
||||||
futex(reinterpret_cast<char*>(&entry) + 4 * IS_BE_MACHINE, FUTEX_WAKE_PRIVATE, 1);
|
futex(reinterpret_cast<char*>(&entry) + 4 * IS_BE_MACHINE, FUTEX_WAKE_PRIVATE, 1);
|
||||||
return;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((prev & s_pointer_mask) == s_pointer_mask)
|
|
||||||
{
|
|
||||||
// Collision, notify everything
|
|
||||||
notify_all(data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void atomic_storage_futex::notify_all(const void* data)
|
void atomic_storage_futex::notify_all(const void* data)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue