mirror of https://github.com/PCSX2/pcsx2.git
Misc: Replace core usage of Semaphore with KernelSemaphore
i.e. decouple it from the UI.
This commit is contained in:
parent
756cd1ee47
commit
096696bed7
|
@ -73,10 +73,19 @@ void Threading::KernelSemaphore::Post()
|
||||||
|
|
||||||
void Threading::KernelSemaphore::Wait()
|
void Threading::KernelSemaphore::Wait()
|
||||||
{
|
{
|
||||||
pxAssertMsg(!wxThread::IsMain(), "Unyielding semaphore wait issued from the main/gui thread. Use WaitWithYield.");
|
|
||||||
MACH_CHECK(semaphore_wait(m_sema));
|
MACH_CHECK(semaphore_wait(m_sema));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Threading::KernelSemaphore::TryWait()
|
||||||
|
{
|
||||||
|
mach_timespec_t time = {};
|
||||||
|
kern_return_t res = semaphore_timedwait(m_sema, time);
|
||||||
|
if (res == KERN_OPERATION_TIMED_OUT)
|
||||||
|
return false;
|
||||||
|
MACH_CHECK(res);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// Wait up to the given time
|
/// Wait up to the given time
|
||||||
/// Returns true if successful, false if timed out
|
/// Returns true if successful, false if timed out
|
||||||
static bool WaitUpTo(semaphore_t sema, wxTimeSpan wxtime)
|
static bool WaitUpTo(semaphore_t sema, wxTimeSpan wxtime)
|
||||||
|
@ -92,25 +101,6 @@ static bool WaitUpTo(semaphore_t sema, wxTimeSpan wxtime)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Threading::KernelSemaphore::WaitWithYield()
|
|
||||||
{
|
|
||||||
#if wxUSE_GUI
|
|
||||||
if (!wxThread::IsMain() || (wxTheApp == NULL))
|
|
||||||
{
|
|
||||||
Wait();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
while (!WaitUpTo(m_sema, def_yieldgui_interval))
|
|
||||||
{
|
|
||||||
YieldToMain();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
WaitWithoutYield();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
Threading::Semaphore::Semaphore()
|
Threading::Semaphore::Semaphore()
|
||||||
{
|
{
|
||||||
// other platforms explicitly make a thread-private (unshared) semaphore
|
// other platforms explicitly make a thread-private (unshared) semaphore
|
||||||
|
|
|
@ -84,7 +84,7 @@ bool Threading::WorkSema::WaitForEmpty()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pxAssertDev(!(value & STATE_FLAG_WAITING_EMPTY), "Multiple threads attempted to wait for empty (not currently supported)");
|
pxAssertDev(!(value & STATE_FLAG_WAITING_EMPTY), "Multiple threads attempted to wait for empty (not currently supported)");
|
||||||
m_empty_sema.WaitWithYield();
|
m_empty_sema.Wait();
|
||||||
return !IsDead(m_state.load(std::memory_order_relaxed));
|
return !IsDead(m_state.load(std::memory_order_relaxed));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ bool Threading::WorkSema::WaitForEmptyWithSpin()
|
||||||
value = m_state.load(std::memory_order_acquire);
|
value = m_state.load(std::memory_order_acquire);
|
||||||
}
|
}
|
||||||
pxAssertDev(!(value & STATE_FLAG_WAITING_EMPTY), "Multiple threads attempted to wait for empty (not currently supported)");
|
pxAssertDev(!(value & STATE_FLAG_WAITING_EMPTY), "Multiple threads attempted to wait for empty (not currently supported)");
|
||||||
m_empty_sema.WaitWithYield();
|
m_empty_sema.Wait();
|
||||||
return !IsDead(m_state.load(std::memory_order_relaxed));
|
return !IsDead(m_state.load(std::memory_order_relaxed));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,40 +149,19 @@ void Threading::KernelSemaphore::Post()
|
||||||
|
|
||||||
void Threading::KernelSemaphore::Wait()
|
void Threading::KernelSemaphore::Wait()
|
||||||
{
|
{
|
||||||
pxAssertMsg(!wxThread::IsMain(), "Unyielding semaphore wait issued from the main/gui thread. Use WaitWithYield.");
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
pthreadCancelableWait(m_sema);
|
WaitForSingleObject(m_sema, INFINITE);
|
||||||
#else
|
#else
|
||||||
sem_wait(&m_sema);
|
sem_wait(&m_sema);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Threading::KernelSemaphore::WaitWithYield()
|
bool Threading::KernelSemaphore::TryWait()
|
||||||
{
|
{
|
||||||
#if wxUSE_GUI
|
|
||||||
if (!wxThread::IsMain() || (wxTheApp == NULL))
|
|
||||||
{
|
|
||||||
Wait();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
u64 millis = def_yieldgui_interval.GetMilliseconds().GetValue();
|
return WaitForSingleObject(m_sema, 0) == WAIT_OBJECT_0;
|
||||||
while (pthreadCancelableTimedWait(m_sema, millis) == ETIMEDOUT)
|
|
||||||
YieldToMain();
|
|
||||||
#else
|
#else
|
||||||
while (true)
|
return sem_trywait(&m_sema) == 0;
|
||||||
{
|
|
||||||
wxDateTime megafail(wxDateTime::UNow() + def_yieldgui_interval);
|
|
||||||
const timespec fail = {megafail.GetTicks(), megafail.GetMillisecond() * 1000000};
|
|
||||||
if (sem_timedwait(&m_sema, &fail) == 0)
|
|
||||||
break;
|
|
||||||
YieldToMain();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
Wait();
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -295,7 +295,7 @@ namespace Threading
|
||||||
~KernelSemaphore();
|
~KernelSemaphore();
|
||||||
void Post();
|
void Post();
|
||||||
void Wait();
|
void Wait();
|
||||||
void WaitWithYield();
|
bool TryWait();
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A semaphore for notifying a work-processing thread of new work in a (separate) queue
|
/// A semaphore for notifying a work-processing thread of new work in a (separate) queue
|
||||||
|
|
|
@ -336,8 +336,8 @@ public:
|
||||||
Threading::Mutex m_mtx_RingBufferBusy2; // Gets released on semaXGkick waiting...
|
Threading::Mutex m_mtx_RingBufferBusy2; // Gets released on semaXGkick waiting...
|
||||||
Threading::Mutex m_mtx_WaitGS;
|
Threading::Mutex m_mtx_WaitGS;
|
||||||
Threading::WorkSema m_sem_event;
|
Threading::WorkSema m_sem_event;
|
||||||
Threading::Semaphore m_sem_OnRingReset;
|
Threading::KernelSemaphore m_sem_OnRingReset;
|
||||||
Threading::Semaphore m_sem_Vsync;
|
Threading::KernelSemaphore 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)
|
||||||
|
|
|
@ -229,7 +229,7 @@ void SysMtgsThread::PostVsyncStart(bool registers_written)
|
||||||
m_VsyncSignalListener.store(true, std::memory_order_release);
|
m_VsyncSignalListener.store(true, std::memory_order_release);
|
||||||
//Console.WriteLn( Color_Blue, "(EEcore Sleep) Vsync\t\tringpos=0x%06x, writepos=0x%06x", m_ReadPos.load(), m_WritePos.load() );
|
//Console.WriteLn( Color_Blue, "(EEcore Sleep) Vsync\t\tringpos=0x%06x, writepos=0x%06x", m_ReadPos.load(), m_WritePos.load() );
|
||||||
|
|
||||||
m_sem_Vsync.WaitNoCancel();
|
m_sem_Vsync.Wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SysMtgsThread::InitAndReadFIFO(u8* mem, u32 qwc)
|
void SysMtgsThread::InitAndReadFIFO(u8* mem, u32 qwc)
|
||||||
|
@ -415,7 +415,7 @@ void SysMtgsThread::MainLoop()
|
||||||
{
|
{
|
||||||
mtvu_lock.Release();
|
mtvu_lock.Release();
|
||||||
// Wait for MTVU to complete vu1 program
|
// Wait for MTVU to complete vu1 program
|
||||||
vu1Thread.semaXGkick.WaitWithoutYield();
|
vu1Thread.semaXGkick.Wait();
|
||||||
mtvu_lock.Acquire();
|
mtvu_lock.Acquire();
|
||||||
}
|
}
|
||||||
Gif_Path& path = gifUnit.gifPath[GIF_PATH_1];
|
Gif_Path& path = gifUnit.gifPath[GIF_PATH_1];
|
||||||
|
@ -722,7 +722,7 @@ void SysMtgsThread::GenericStall(uint size)
|
||||||
{
|
{
|
||||||
m_SignalRingEnable.store(true, std::memory_order_release);
|
m_SignalRingEnable.store(true, std::memory_order_release);
|
||||||
SetEvent();
|
SetEvent();
|
||||||
m_sem_OnRingReset.WaitWithoutYield();
|
m_sem_OnRingReset.Wait();
|
||||||
readpos = m_ReadPos.load(std::memory_order_acquire);
|
readpos = m_ReadPos.load(std::memory_order_acquire);
|
||||||
//Console.WriteLn( Color_Blue, "(EEcore Awake) Report!\tringpos=0x%06x", readpos );
|
//Console.WriteLn( Color_Blue, "(EEcore Awake) Report!\tringpos=0x%06x", readpos );
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ class VU_Thread final {
|
||||||
public:
|
public:
|
||||||
alignas(16) vifStruct vif;
|
alignas(16) vifStruct vif;
|
||||||
alignas(16) VIFregisters vifRegs;
|
alignas(16) VIFregisters vifRegs;
|
||||||
Threading::Semaphore semaXGkick;
|
Threading::KernelSemaphore 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;
|
||||||
|
|
|
@ -54,7 +54,7 @@ extern DECI2_DBGP_BRK ebrk[32], ibrk[32];
|
||||||
extern s32 ebrk_count, ibrk_count;
|
extern s32 ebrk_count, ibrk_count;
|
||||||
extern s32 runCode, runCount;
|
extern s32 runCode, runCount;
|
||||||
|
|
||||||
extern Threading::Semaphore* runEvent;
|
extern Threading::KernelSemaphore* runEvent;
|
||||||
|
|
||||||
extern s32 connected;
|
extern s32 connected;
|
||||||
//when add linux code this might change
|
//when add linux code this might change
|
||||||
|
|
Loading…
Reference in New Issue