mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-03 05:21:25 +12:00
Remove shared_cond
and simplify reservation waiting
Use atomic wait for reservations Cleanup some obsolete code
This commit is contained in:
parent
d13ff285d1
commit
0a96497e13
7 changed files with 4 additions and 537 deletions
157
Utilities/sync.h
157
Utilities/sync.h
|
@ -149,160 +149,3 @@ inline int futex(volatile void* uaddr, int futex_op, uint val, const timespec* t
|
|||
return g_futex(uaddr, futex_op, val, timeout, mask);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename T, typename Pred>
|
||||
bool balanced_wait_until(atomic_t<T>& var, u64 usec_timeout, Pred&& pred)
|
||||
{
|
||||
static_assert(sizeof(T) == 4 || sizeof(T) == 8);
|
||||
|
||||
const bool is_inf = usec_timeout > u64{UINT32_MAX / 1000} * 1000000;
|
||||
|
||||
// Optional second argument indicates that the predicate should try to retire
|
||||
auto test_pred = [&](T& _new, auto... args)
|
||||
{
|
||||
T old = var.load();
|
||||
|
||||
while (true)
|
||||
{
|
||||
_new = old;
|
||||
|
||||
// Zero indicates failure without modifying the value
|
||||
// Negative indicates failure but modifies the value
|
||||
auto ret = std::invoke(std::forward<Pred>(pred), _new, args...);
|
||||
|
||||
if (LIKELY(!ret || var.compare_exchange(old, _new)))
|
||||
{
|
||||
return ret > 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
T value;
|
||||
|
||||
#ifdef _WIN32
|
||||
if (OptWaitOnAddress)
|
||||
{
|
||||
while (!test_pred(value))
|
||||
{
|
||||
if (OptWaitOnAddress(&var, &value, sizeof(T), is_inf ? INFINITE : usec_timeout / 1000))
|
||||
{
|
||||
if (!test_pred(value, nullptr))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (GetLastError() == ERROR_TIMEOUT)
|
||||
{
|
||||
// Retire
|
||||
return test_pred(value, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
LARGE_INTEGER timeout;
|
||||
timeout.QuadPart = usec_timeout * -10;
|
||||
|
||||
if (!usec_timeout || NtWaitForKeyedEvent(nullptr, &var, false, is_inf ? nullptr : &timeout))
|
||||
{
|
||||
// Timed out: retire
|
||||
if (!test_pred(value, nullptr))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Signaled in the last moment: restore balance
|
||||
NtWaitForKeyedEvent(nullptr, &var, false, nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!test_pred(value, nullptr))
|
||||
{
|
||||
// Stolen notification: restore balance
|
||||
NtReleaseKeyedEvent(nullptr, &var, false, nullptr);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
#else
|
||||
struct timespec timeout;
|
||||
timeout.tv_sec = usec_timeout / 1000000;
|
||||
timeout.tv_nsec = (usec_timeout % 1000000) * 1000;
|
||||
|
||||
char* ptr = reinterpret_cast<char*>(&var);
|
||||
|
||||
if constexpr (sizeof(T) == 8)
|
||||
{
|
||||
ptr += 4 * IS_BE_MACHINE;
|
||||
}
|
||||
|
||||
while (!test_pred(value))
|
||||
{
|
||||
if (futex(ptr, FUTEX_WAIT_PRIVATE, static_cast<u32>(value), is_inf ? nullptr : &timeout) == 0)
|
||||
{
|
||||
if (!test_pred(value, nullptr))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
switch (errno)
|
||||
{
|
||||
case EAGAIN: break;
|
||||
case ETIMEDOUT: return test_pred(value, nullptr);
|
||||
default: verify("Unknown futex error" HERE), 0;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
template <bool All = false, typename T>
|
||||
void balanced_awaken(atomic_t<T>& var, u32 weight)
|
||||
{
|
||||
static_assert(sizeof(T) == 4 || sizeof(T) == 8);
|
||||
|
||||
#ifdef _WIN32
|
||||
if (OptWaitOnAddress)
|
||||
{
|
||||
if (All || weight > 3)
|
||||
{
|
||||
OptWakeByAddressAll(&var);
|
||||
return;
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < weight; i++)
|
||||
{
|
||||
OptWakeByAddressSingle(&var);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < weight; i++)
|
||||
{
|
||||
NtReleaseKeyedEvent(nullptr, &var, false, nullptr);
|
||||
}
|
||||
#else
|
||||
char* ptr = reinterpret_cast<char*>(&var);
|
||||
|
||||
if constexpr (sizeof(T) == 8)
|
||||
{
|
||||
ptr += 4 * IS_BE_MACHINE;
|
||||
}
|
||||
|
||||
if (All || weight)
|
||||
{
|
||||
futex(ptr, FUTEX_WAKE_PRIVATE, All ? INT_MAX : std::min<u32>(INT_MAX, weight));
|
||||
}
|
||||
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue