mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-08-02 22:30:39 +00:00
atomic.hpp: reimplement USE_FUTEX path for Linux
This commit is contained in:
parent
e0f60c5dce
commit
56b310ebac
1 changed files with 40 additions and 6 deletions
|
@ -1,10 +1,7 @@
|
||||||
#include "atomic.hpp"
|
#include "atomic.hpp"
|
||||||
|
|
||||||
// USE_FUTEX takes precedence over USE_POSIX
|
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
#define USE_FUTEX
|
#define USE_FUTEX
|
||||||
#define USE_POSIX
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Utilities/sync.h"
|
#include "Utilities/sync.h"
|
||||||
|
@ -154,6 +151,14 @@ static constexpr u64 s_sema_mask = (s_sema_gcount * 64 - 1);
|
||||||
|
|
||||||
#ifdef USE_POSIX
|
#ifdef USE_POSIX
|
||||||
using sema_handle = sem_t;
|
using sema_handle = sem_t;
|
||||||
|
#elif defined(USE_FUTEX)
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
struct alignas(64) sema_handle
|
||||||
|
{
|
||||||
|
atomic_t<u32> sema;
|
||||||
|
};
|
||||||
|
}
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
using sema_handle = std::uint16_t;
|
using sema_handle = std::uint16_t;
|
||||||
#else
|
#else
|
||||||
|
@ -214,7 +219,7 @@ static u32 sema_alloc()
|
||||||
#ifdef USE_POSIX
|
#ifdef USE_POSIX
|
||||||
// Initialize semaphore (should be very fast)
|
// Initialize semaphore (should be very fast)
|
||||||
sem_init(&s_sema_list[id], 0, 0);
|
sem_init(&s_sema_list[id], 0, 0);
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32) | defined(USE_FUTEX)
|
||||||
// Do nothing
|
// Do nothing
|
||||||
#else
|
#else
|
||||||
if (!s_sema_list[id])
|
if (!s_sema_list[id])
|
||||||
|
@ -485,7 +490,25 @@ void atomic_storage_futex::wait(const void* data, std::size_t size, u64 old_valu
|
||||||
|
|
||||||
if (sema_id && ptr_cmp(data, size, old_value, mask) && s_tls_wait_cb(data))
|
if (sema_id && ptr_cmp(data, size, old_value, mask) && s_tls_wait_cb(data))
|
||||||
{
|
{
|
||||||
#if defined(_WIN32) && !defined(USE_POSIX)
|
#ifdef USE_FUTEX
|
||||||
|
struct timespec ts;
|
||||||
|
ts.tv_sec = timeout / 1'000'000'000;
|
||||||
|
ts.tv_nsec = timeout % 1'000'000'000;
|
||||||
|
|
||||||
|
if (s_sema_list[sema_id].sema.try_dec(0))
|
||||||
|
{
|
||||||
|
fallback = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
futex(&s_sema_list[sema_id].sema, FUTEX_WAIT_PRIVATE, 0, timeout + 1 ? &ts : nullptr);
|
||||||
|
|
||||||
|
if (s_sema_list[sema_id].sema.try_dec(0))
|
||||||
|
{
|
||||||
|
fallback = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#elif defined(_WIN32) && !defined(USE_POSIX)
|
||||||
LARGE_INTEGER qw;
|
LARGE_INTEGER qw;
|
||||||
qw.QuadPart = -static_cast<s64>(timeout / 100);
|
qw.QuadPart = -static_cast<s64>(timeout / 100);
|
||||||
|
|
||||||
|
@ -591,7 +614,12 @@ void atomic_storage_futex::wait(const void* data, std::size_t size, u64 old_valu
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(_WIN32) && !defined(USE_POSIX)
|
#ifdef USE_FUTEX
|
||||||
|
if (s_sema_list[sema_id].sema.try_dec(0))
|
||||||
|
{
|
||||||
|
fallback = true;
|
||||||
|
}
|
||||||
|
#elif defined(_WIN32) && !defined(USE_POSIX)
|
||||||
static LARGE_INTEGER instant{};
|
static LARGE_INTEGER instant{};
|
||||||
|
|
||||||
if (!NtWaitForKeyedEvent(nullptr, &s_sema_list[sema_id], false, &instant))
|
if (!NtWaitForKeyedEvent(nullptr, &s_sema_list[sema_id], false, &instant))
|
||||||
|
@ -727,6 +755,9 @@ void atomic_storage_futex::notify_one(const void* data)
|
||||||
{
|
{
|
||||||
#ifdef USE_POSIX
|
#ifdef USE_POSIX
|
||||||
sem_post(&s_sema_list[sema_id]);
|
sem_post(&s_sema_list[sema_id]);
|
||||||
|
#elif defined(USE_FUTEX)
|
||||||
|
s_sema_list[sema_id].sema++;
|
||||||
|
futex(&s_sema_list[sema_id].sema, FUTEX_WAKE_PRIVATE, 1);
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
NtReleaseKeyedEvent(nullptr, &s_sema_list[sema_id], 1, nullptr);
|
NtReleaseKeyedEvent(nullptr, &s_sema_list[sema_id], 1, nullptr);
|
||||||
#else
|
#else
|
||||||
|
@ -782,6 +813,9 @@ void atomic_storage_futex::notify_all(const void* data)
|
||||||
{
|
{
|
||||||
sem_post(&s_sema_list[sema_id]);
|
sem_post(&s_sema_list[sema_id]);
|
||||||
}
|
}
|
||||||
|
#elif defined(USE_FUTEX)
|
||||||
|
s_sema_list[sema_id].sema += count;
|
||||||
|
futex(&s_sema_list[sema_id].sema, FUTEX_WAKE_PRIVATE, 0x7fff'ffff);
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
for (u32 i = 0; i < count; i++)
|
for (u32 i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue