mirror of https://github.com/PCSX2/pcsx2.git
GS: Use semaphores with a fast userspace path
This commit is contained in:
parent
ab7105ffa0
commit
faf750a544
|
@ -230,4 +230,35 @@ namespace Threading
|
||||||
/// Should be called by the worker thread if it restarts after dying
|
/// Should be called by the worker thread if it restarts after dying
|
||||||
void Reset();
|
void Reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// A semaphore that definitely has a fast userspace path
|
||||||
|
class UserspaceSemaphore
|
||||||
|
{
|
||||||
|
KernelSemaphore m_sema;
|
||||||
|
std::atomic<uint32_t> m_counter{0};
|
||||||
|
|
||||||
|
public:
|
||||||
|
UserspaceSemaphore() = default;
|
||||||
|
~UserspaceSemaphore() = default;
|
||||||
|
|
||||||
|
void Post()
|
||||||
|
{
|
||||||
|
if (m_counter.fetch_add(1, std::memory_order_release) < 0)
|
||||||
|
m_sema.Post();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Wait()
|
||||||
|
{
|
||||||
|
if (m_counter.fetch_sub(1, std::memory_order_acquire) <= 0)
|
||||||
|
m_sema.Wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TryWait()
|
||||||
|
{
|
||||||
|
int32_t counter = m_counter.load(std::memory_order_relaxed);
|
||||||
|
while (counter > 0 && !m_counter.compare_exchange_weak(counter, counter - 1, std::memory_order_acquire, std::memory_order_relaxed))
|
||||||
|
;
|
||||||
|
return counter > 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
} // namespace Threading
|
} // namespace Threading
|
||||||
|
|
|
@ -342,8 +342,8 @@ public:
|
||||||
std::mutex m_mtx_RingBufferBusy2; // Gets released on semaXGkick waiting...
|
std::mutex m_mtx_RingBufferBusy2; // Gets released on semaXGkick waiting...
|
||||||
std::mutex m_mtx_WaitGS;
|
std::mutex m_mtx_WaitGS;
|
||||||
Threading::WorkSema m_sem_event;
|
Threading::WorkSema m_sem_event;
|
||||||
Threading::KernelSemaphore m_sem_OnRingReset;
|
Threading::UserspaceSemaphore m_sem_OnRingReset;
|
||||||
Threading::KernelSemaphore m_sem_Vsync;
|
Threading::UserspaceSemaphore m_sem_Vsync;
|
||||||
|
|
||||||
// used to keep multiple threads from sending packets to the ringbuffer concurrently.
|
// used to keep multiple threads from sending packets to the ringbuffer concurrently.
|
||||||
// (currently not used or implemented -- is a planned feature for a future threaded VU1)
|
// (currently not used or implemented -- is a planned feature for a future threaded VU1)
|
||||||
|
@ -369,7 +369,7 @@ public:
|
||||||
std::atomic_bool m_open_flag{false};
|
std::atomic_bool m_open_flag{false};
|
||||||
std::atomic_bool m_shutdown_flag{false};
|
std::atomic_bool m_shutdown_flag{false};
|
||||||
std::atomic_bool m_run_idle_flag{false};
|
std::atomic_bool m_run_idle_flag{false};
|
||||||
Threading::KernelSemaphore m_open_or_close_done;
|
Threading::UserspaceSemaphore m_open_or_close_done;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SysMtgsThread();
|
SysMtgsThread();
|
||||||
|
|
|
@ -45,7 +45,7 @@ class VU_Thread final {
|
||||||
public:
|
public:
|
||||||
alignas(16) vifStruct vif;
|
alignas(16) vifStruct vif;
|
||||||
alignas(16) VIFregisters vifRegs;
|
alignas(16) VIFregisters vifRegs;
|
||||||
Threading::KernelSemaphore semaXGkick;
|
Threading::UserspaceSemaphore semaXGkick;
|
||||||
std::atomic<unsigned int> vuCycles[4]; // Used for VU cycle stealing hack
|
std::atomic<unsigned int> vuCycles[4]; // Used for VU cycle stealing hack
|
||||||
u32 vuCycleIdx; // Used for VU cycle stealing hack
|
u32 vuCycleIdx; // Used for VU cycle stealing hack
|
||||||
u32 vuFBRST;
|
u32 vuFBRST;
|
||||||
|
|
Loading…
Reference in New Issue