mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 11:36:13 +00:00
atomic.hpp: add atomic wait mask support
This commit is contained in:
parent
c59cb1bdd3
commit
2fc8844315
3 changed files with 16 additions and 15 deletions
|
@ -2394,7 +2394,7 @@ s64 spu_thread::get_ch_value(u32 ch)
|
|||
return -1;
|
||||
}
|
||||
|
||||
vm::reservation_notifier(raddr, 128).wait(rtime, atomic_wait_timeout{30000});
|
||||
vm::reservation_notifier(raddr, 128).wait<UINT64_MAX & -128>(rtime, atomic_wait_timeout{30000});
|
||||
}
|
||||
|
||||
check_state();
|
||||
|
|
|
@ -30,14 +30,14 @@ static thread_local bool(*s_tls_wait_cb)(const void* data) = [](const void*)
|
|||
return true;
|
||||
};
|
||||
|
||||
static inline bool ptr_cmp(const void* data, std::size_t size, u64 old_value)
|
||||
static inline bool ptr_cmp(const void* data, std::size_t size, u64 old_value, u64 mask)
|
||||
{
|
||||
switch (size)
|
||||
{
|
||||
case 1: return reinterpret_cast<const atomic_t<u8>*>(data)->load() == old_value;
|
||||
case 2: return reinterpret_cast<const atomic_t<u16>*>(data)->load() == old_value;
|
||||
case 4: return reinterpret_cast<const atomic_t<u32>*>(data)->load() == old_value;
|
||||
case 8: return reinterpret_cast<const atomic_t<u64>*>(data)->load() == old_value;
|
||||
case 1: return (reinterpret_cast<const atomic_t<u8>*>(data)->load() & mask) == (old_value & mask);
|
||||
case 2: return (reinterpret_cast<const atomic_t<u16>*>(data)->load() & mask) == (old_value & mask);
|
||||
case 4: return (reinterpret_cast<const atomic_t<u32>*>(data)->load() & mask) == (old_value & mask);
|
||||
case 8: return (reinterpret_cast<const atomic_t<u64>*>(data)->load() & mask) == (old_value & mask);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -78,7 +78,7 @@ namespace
|
|||
return s_waiter_maps[std::hash<const void*>()(ptr) % std::size(s_waiter_maps)];
|
||||
}
|
||||
|
||||
void fallback_wait(const void* data, std::size_t size, u64 old_value, u64 timeout)
|
||||
void fallback_wait(const void* data, std::size_t size, u64 old_value, u64 timeout, u64 mask)
|
||||
{
|
||||
auto& wmap = get_fallback_map(data);
|
||||
|
||||
|
@ -90,7 +90,7 @@ namespace
|
|||
// Update node key
|
||||
s_tls_waiter.key() = data;
|
||||
|
||||
if (std::unique_lock lock(wmap.mutex); ptr_cmp(data, size, old_value) && s_tls_wait_cb(data))
|
||||
if (std::unique_lock lock(wmap.mutex); ptr_cmp(data, size, old_value, mask) && s_tls_wait_cb(data))
|
||||
{
|
||||
// Add node to the waiter list
|
||||
const auto iter = wmap.list.insert(std::move(s_tls_waiter));
|
||||
|
@ -152,9 +152,9 @@ namespace
|
|||
|
||||
#if !defined(_WIN32) && !defined(__linux__)
|
||||
|
||||
void atomic_storage_futex::wait(const void* data, std::size_t size, u64 old_value, u64 timeout)
|
||||
void atomic_storage_futex::wait(const void* data, std::size_t size, u64 old_value, u64 timeout, u64 mask)
|
||||
{
|
||||
fallback_wait(data, size, old_value, timeout);
|
||||
fallback_wait(data, size, old_value, timeout, mask);
|
||||
}
|
||||
|
||||
void atomic_storage_futex::notify_one(const void* data)
|
||||
|
@ -169,7 +169,7 @@ void atomic_storage_futex::notify_all(const void* data)
|
|||
|
||||
#else
|
||||
|
||||
void atomic_storage_futex::wait(const void* data, std::size_t size, u64 old_value, u64 timeout)
|
||||
void atomic_storage_futex::wait(const void* data, std::size_t size, u64 old_value, u64 timeout, u64 mask)
|
||||
{
|
||||
if (!timeout)
|
||||
{
|
||||
|
@ -222,9 +222,9 @@ void atomic_storage_futex::wait(const void* data, std::size_t size, u64 old_valu
|
|||
|
||||
if (fallback)
|
||||
{
|
||||
fallback_wait(data, size, old_value, timeout);
|
||||
fallback_wait(data, size, old_value, timeout, mask);
|
||||
}
|
||||
else if (ptr_cmp(data, size, old_value) && s_tls_wait_cb(data))
|
||||
else if (ptr_cmp(data, size, old_value, mask) && s_tls_wait_cb(data))
|
||||
{
|
||||
#ifdef _WIN32
|
||||
LARGE_INTEGER qw;
|
||||
|
|
|
@ -20,7 +20,7 @@ private:
|
|||
template <typename T>
|
||||
friend class atomic_t;
|
||||
|
||||
static void wait(const void* data, std::size_t size, u64 old_value, u64 timeout);
|
||||
static void wait(const void* data, std::size_t size, u64 old_value, u64 timeout, u64 mask);
|
||||
static void notify_one(const void* data);
|
||||
static void notify_all(const void* data);
|
||||
|
||||
|
@ -1134,9 +1134,10 @@ public:
|
|||
return atomic_storage<type>::btr(m_data, bit);
|
||||
}
|
||||
|
||||
template <u64 Mask = 0xffff'ffff'ffff'ffff>
|
||||
void wait(type old_value, atomic_wait_timeout timeout = atomic_wait_timeout::inf) const noexcept
|
||||
{
|
||||
atomic_storage_futex::wait(&m_data, sizeof(T), std::bit_cast<get_uint_t<sizeof(T)>>(old_value), static_cast<u64>(timeout));
|
||||
atomic_storage_futex::wait(&m_data, sizeof(T), std::bit_cast<get_uint_t<sizeof(T)>>(old_value), static_cast<u64>(timeout), Mask);
|
||||
}
|
||||
|
||||
void notify_one() noexcept
|
||||
|
|
Loading…
Add table
Reference in a new issue