mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-07 23:41:26 +12:00
atomic.cpp: experimental optimization (Win7+)
Try non-blocking wake up function first.
This commit is contained in:
parent
8628fc441d
commit
c479d431a4
1 changed files with 57 additions and 1 deletions
|
@ -431,6 +431,7 @@ void atomic_storage_futex::wait(const void* data, std::size_t size, u64 old_valu
|
||||||
if (fallback)
|
if (fallback)
|
||||||
{
|
{
|
||||||
// Restart waiting
|
// Restart waiting
|
||||||
|
verify(HERE), sema->load() == 2;
|
||||||
sema->release(1);
|
sema->release(1);
|
||||||
fallback = false;
|
fallback = false;
|
||||||
}
|
}
|
||||||
|
@ -546,7 +547,62 @@ void atomic_storage_futex::notify_all(const void* data)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u64 bits = slot->sema_bits; bits; bits &= bits - 1)
|
#if defined(_WIN32) && !defined(USE_FUTEX)
|
||||||
|
if (true)
|
||||||
|
{
|
||||||
|
// Make a copy to filter out waiters that fail some checks
|
||||||
|
u64 copy = slot->sema_bits.load();
|
||||||
|
|
||||||
|
// Used for making non-blocking syscall
|
||||||
|
LARGE_INTEGER instant{};
|
||||||
|
|
||||||
|
for (u64 bits = copy; bits; bits &= bits - 1)
|
||||||
|
{
|
||||||
|
const u32 id = std::countr_zero(bits);
|
||||||
|
|
||||||
|
const auto sema = &slot->sema_data[id];
|
||||||
|
|
||||||
|
if (sema->load() == 1 && sema->compare_and_swap_test(1, 2))
|
||||||
|
{
|
||||||
|
// Waiters locked for notification
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the bit from next stage
|
||||||
|
copy &= ~(1ull << id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If only one waiter exists, there is no point in trying to optimize
|
||||||
|
if (copy & (copy - 1))
|
||||||
|
{
|
||||||
|
for (u64 bits = copy; bits; bits &= bits - 1)
|
||||||
|
{
|
||||||
|
const u32 id = std::countr_zero(bits);
|
||||||
|
|
||||||
|
const auto sema = &slot->sema_data[id];
|
||||||
|
|
||||||
|
if (NtReleaseKeyedEvent(nullptr, sema, 1, &instant))
|
||||||
|
{
|
||||||
|
// Failed to notify immediately
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the bit from next stage
|
||||||
|
copy &= ~(1ull << id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Proceed with remaining bits using "normal" blocking waiting
|
||||||
|
for (u64 bits = copy; bits; bits &= bits - 1)
|
||||||
|
{
|
||||||
|
NtReleaseKeyedEvent(nullptr, &slot->sema_data[std::countr_zero(bits)], 1, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (u64 bits = slot->sema_bits.load(); bits; bits &= bits - 1)
|
||||||
{
|
{
|
||||||
const auto sema = &slot->sema_data[std::countr_zero(bits)];
|
const auto sema = &slot->sema_data[std::countr_zero(bits)];
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue