mirror of
https://github.com/cemu-project/Cemu.git
synced 2024-12-01 21:44:17 +01:00
coreinit: Dont yield uninterruptible threads in spinlock
This commit is contained in:
parent
387b712959
commit
859dc78e90
@ -128,11 +128,25 @@ namespace coreinit
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// loop until lock acquired
|
// loop until lock acquired
|
||||||
|
if (coreinit::__CemuIsMulticoreMode())
|
||||||
|
{
|
||||||
|
while (!spinlock->ownerThread.atomic_compare_exchange(nullptr, currentThread))
|
||||||
|
{
|
||||||
|
_mm_pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// we are in single-core mode and the lock will never be released unless we let other threads resume work
|
||||||
|
// to avoid an infinite loop we have no choice but to yield the thread even it is in an uninterruptible state
|
||||||
|
if( !OSIsInterruptEnabled() )
|
||||||
|
cemuLog_log(LogType::APIErrors, "OSUninterruptibleSpinLock_Acquire(): Lock is occupied which requires a wait but current thread is already in an uninterruptible state (Avoid cascaded OSDisableInterrupts and/or OSUninterruptibleSpinLock)");
|
||||||
while (!spinlock->ownerThread.atomic_compare_exchange(nullptr, currentThread))
|
while (!spinlock->ownerThread.atomic_compare_exchange(nullptr, currentThread))
|
||||||
{
|
{
|
||||||
OSYieldThread();
|
OSYieldThread();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
__OSBoostThread(currentThread);
|
__OSBoostThread(currentThread);
|
||||||
spinlock->interruptMask = OSDisableInterrupts();
|
spinlock->interruptMask = OSDisableInterrupts();
|
||||||
cemu_assert_debug(spinlock->ownerThread == currentThread);
|
cemu_assert_debug(spinlock->ownerThread == currentThread);
|
||||||
|
@ -66,6 +66,11 @@ namespace coreinit
|
|||||||
|
|
||||||
std::unordered_map<OSThread_t*, OSHostThread*> s_threadToFiber;
|
std::unordered_map<OSThread_t*, OSHostThread*> s_threadToFiber;
|
||||||
|
|
||||||
|
bool __CemuIsMulticoreMode()
|
||||||
|
{
|
||||||
|
return g_isMulticoreMode;
|
||||||
|
}
|
||||||
|
|
||||||
// create host thread (fiber) that will be used to run the PPC instance
|
// create host thread (fiber) that will be used to run the PPC instance
|
||||||
// note that host threads are fibers and not actual threads
|
// note that host threads are fibers and not actual threads
|
||||||
void __OSCreateHostThread(OSThread_t* thread)
|
void __OSCreateHostThread(OSThread_t* thread)
|
||||||
|
@ -488,6 +488,8 @@ namespace coreinit
|
|||||||
void InitializeThread();
|
void InitializeThread();
|
||||||
void InitializeConcurrency();
|
void InitializeConcurrency();
|
||||||
|
|
||||||
|
bool __CemuIsMulticoreMode();
|
||||||
|
|
||||||
OSThread_t* OSGetDefaultThread(sint32 coreIndex);
|
OSThread_t* OSGetDefaultThread(sint32 coreIndex);
|
||||||
void* OSGetDefaultThreadStack(sint32 coreIndex, uint32& size);
|
void* OSGetDefaultThreadStack(sint32 coreIndex, uint32& size);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user