mirror of
https://github.com/libretro/ppsspp.git
synced 2024-11-30 20:01:00 +00:00
Mutexes and semaphores don't always reschedule.
It's just the normal rescheduling happening. Previous tests weren't correct. Also some minor cleanup.
This commit is contained in:
parent
1189da826c
commit
3ab41e515d
@ -15,8 +15,6 @@
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
// UNFINISHED
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include "HLE.h"
|
||||
@ -203,8 +201,6 @@ void sceKernelCreateMutex(const char *name, u32 attr, int initialCount, u32 opti
|
||||
WARN_LOG(HLE,"sceKernelCreateMutex(%s) unsupported options parameter.", name);
|
||||
|
||||
RETURN(id);
|
||||
|
||||
__KernelReSchedule("mutex created");
|
||||
}
|
||||
|
||||
void sceKernelDeleteMutex(SceUID id)
|
||||
@ -214,6 +210,7 @@ void sceKernelDeleteMutex(SceUID id)
|
||||
Mutex *mutex = kernelObjects.Get<Mutex>(id, error);
|
||||
if (mutex)
|
||||
{
|
||||
bool wokeThreads = false;
|
||||
std::vector<SceUID>::iterator iter, end;
|
||||
for (iter = mutex->waitingThreads.begin(), end = mutex->waitingThreads.end(); iter != end; ++iter)
|
||||
{
|
||||
@ -228,13 +225,16 @@ void sceKernelDeleteMutex(SceUID id)
|
||||
}
|
||||
|
||||
__KernelResumeThreadFromWait(threadID, SCE_KERNEL_ERROR_WAIT_DELETE);
|
||||
wokeThreads = true;
|
||||
}
|
||||
if (mutex->nm.lockThread != -1)
|
||||
__KernelMutexEraseLock(mutex);
|
||||
mutex->waitingThreads.empty();
|
||||
mutex->waitingThreads.clear();
|
||||
|
||||
RETURN(kernelObjects.Destroy<Mutex>(id));
|
||||
__KernelReSchedule("mutex deleted");
|
||||
|
||||
if (wokeThreads)
|
||||
__KernelReSchedule("mutex deleted");
|
||||
}
|
||||
else
|
||||
RETURN(error);
|
||||
@ -386,7 +386,6 @@ void sceKernelLockMutex(SceUID id, int count, u32 timeoutPtr)
|
||||
if (__KernelLockMutex(mutex, count, error))
|
||||
{
|
||||
RETURN(0);
|
||||
__KernelReSchedule("mutex locked");
|
||||
}
|
||||
else if (error)
|
||||
RETURN(error);
|
||||
@ -395,6 +394,7 @@ void sceKernelLockMutex(SceUID id, int count, u32 timeoutPtr)
|
||||
mutex->waitingThreads.push_back(__KernelGetCurThread());
|
||||
__KernelWaitMutex(mutex, timeoutPtr);
|
||||
__KernelWaitCurThread(WAITTYPE_MUTEX, id, count, timeoutPtr, false);
|
||||
__KernelReSchedule("mutex locked");
|
||||
}
|
||||
}
|
||||
|
||||
@ -409,7 +409,6 @@ void sceKernelLockMutexCB(SceUID id, int count, u32 timeoutPtr)
|
||||
if (__KernelLockMutex(mutex, count, error))
|
||||
{
|
||||
RETURN(0);
|
||||
__KernelReSchedule("mutex locked");
|
||||
}
|
||||
else if (error)
|
||||
RETURN(error);
|
||||
@ -419,9 +418,8 @@ void sceKernelLockMutexCB(SceUID id, int count, u32 timeoutPtr)
|
||||
__KernelWaitMutex(mutex, timeoutPtr);
|
||||
__KernelWaitCurThread(WAITTYPE_MUTEX, id, count, timeoutPtr, true);
|
||||
__KernelCheckCallbacks();
|
||||
__KernelReSchedule("mutex locked");
|
||||
}
|
||||
|
||||
__KernelReSchedule("mutex locked");
|
||||
}
|
||||
|
||||
// int sceKernelTryLockMutex(SceUID id, int count)
|
||||
@ -433,10 +431,7 @@ void sceKernelTryLockMutex(SceUID id, int count)
|
||||
Mutex *mutex = kernelObjects.Get<Mutex>(id, error);
|
||||
|
||||
if (__KernelLockMutex(mutex, count, error))
|
||||
{
|
||||
RETURN(0);
|
||||
__KernelReSchedule("mutex trylocked");
|
||||
}
|
||||
else if (error)
|
||||
RETURN(error);
|
||||
else
|
||||
@ -474,8 +469,8 @@ void sceKernelUnlockMutex(SceUID id, int count)
|
||||
|
||||
if (mutex->nm.lockLevel == 0)
|
||||
{
|
||||
__KernelUnlockMutex(mutex, error);
|
||||
__KernelReSchedule("mutex unlocked");
|
||||
if (__KernelUnlockMutex(mutex, error))
|
||||
__KernelReSchedule("mutex locked");
|
||||
}
|
||||
}
|
||||
|
||||
@ -524,8 +519,6 @@ void sceKernelCreateLwMutex(u32 workareaPtr, const char *name, u32 attr, int ini
|
||||
WARN_LOG(HLE,"sceKernelCreateLwMutex(%s) unsupported options parameter.", name);
|
||||
|
||||
RETURN(0);
|
||||
|
||||
__KernelReSchedule("lwmutex created");
|
||||
}
|
||||
|
||||
void sceKernelDeleteLwMutex(u32 workareaPtr)
|
||||
@ -545,6 +538,7 @@ void sceKernelDeleteLwMutex(u32 workareaPtr)
|
||||
LwMutex *mutex = kernelObjects.Get<LwMutex>(workarea.uid, error);
|
||||
if (mutex)
|
||||
{
|
||||
bool wokeThreads = false;
|
||||
std::vector<SceUID>::iterator iter, end;
|
||||
for (iter = mutex->waitingThreads.begin(), end = mutex->waitingThreads.end(); iter != end; ++iter)
|
||||
{
|
||||
@ -559,14 +553,16 @@ void sceKernelDeleteLwMutex(u32 workareaPtr)
|
||||
}
|
||||
|
||||
__KernelResumeThreadFromWait(threadID, SCE_KERNEL_ERROR_WAIT_DELETE);
|
||||
wokeThreads = true;
|
||||
}
|
||||
mutex->waitingThreads.empty();
|
||||
mutex->waitingThreads.clear();
|
||||
|
||||
RETURN(kernelObjects.Destroy<LwMutex>(workarea.uid));
|
||||
workarea.clear();
|
||||
Memory::WriteStruct(workareaPtr, &workarea);
|
||||
|
||||
__KernelReSchedule("mutex deleted");
|
||||
if (wokeThreads)
|
||||
__KernelReSchedule("lwmutex deleted");
|
||||
}
|
||||
else
|
||||
RETURN(error);
|
||||
@ -706,7 +702,6 @@ void sceKernelTryLockLwMutex(u32 workareaPtr, int count)
|
||||
{
|
||||
Memory::WriteStruct(workareaPtr, &workarea);
|
||||
RETURN(0);
|
||||
__KernelReSchedule("lwmutex trylocked");
|
||||
}
|
||||
else if (error)
|
||||
RETURN(PSP_MUTEX_ERROR_TRYLOCK_FAILED);
|
||||
@ -726,7 +721,6 @@ void sceKernelTryLockLwMutex_600(u32 workareaPtr, int count)
|
||||
{
|
||||
Memory::WriteStruct(workareaPtr, &workarea);
|
||||
RETURN(0);
|
||||
__KernelReSchedule("lwmutex trylocked");
|
||||
}
|
||||
else if (error)
|
||||
RETURN(error);
|
||||
@ -746,7 +740,6 @@ void sceKernelLockLwMutex(u32 workareaPtr, int count, u32 timeoutPtr)
|
||||
{
|
||||
Memory::WriteStruct(workareaPtr, &workarea);
|
||||
RETURN(0);
|
||||
__KernelReSchedule("lwmutex locked");
|
||||
}
|
||||
else if (error)
|
||||
RETURN(error);
|
||||
@ -758,6 +751,7 @@ void sceKernelLockLwMutex(u32 workareaPtr, int count, u32 timeoutPtr)
|
||||
mutex->waitingThreads.push_back(__KernelGetCurThread());
|
||||
__KernelWaitLwMutex(mutex, timeoutPtr);
|
||||
__KernelWaitCurThread(WAITTYPE_LWMUTEX, workarea.uid, count, timeoutPtr, false);
|
||||
__KernelReSchedule("lwmutex locked");
|
||||
}
|
||||
else
|
||||
RETURN(error);
|
||||
@ -776,7 +770,6 @@ void sceKernelLockLwMutexCB(u32 workareaPtr, int count, u32 timeoutPtr)
|
||||
{
|
||||
Memory::WriteStruct(workareaPtr, &workarea);
|
||||
RETURN(0);
|
||||
__KernelReSchedule("lwmutex locked");
|
||||
}
|
||||
else if (error)
|
||||
RETURN(error);
|
||||
@ -789,6 +782,7 @@ void sceKernelLockLwMutexCB(u32 workareaPtr, int count, u32 timeoutPtr)
|
||||
__KernelWaitLwMutex(mutex, timeoutPtr);
|
||||
__KernelWaitCurThread(WAITTYPE_LWMUTEX, workarea.uid, count, timeoutPtr, true);
|
||||
__KernelCheckCallbacks();
|
||||
__KernelReSchedule("lwmutex locked");
|
||||
}
|
||||
else
|
||||
RETURN(error);
|
||||
@ -825,9 +819,9 @@ void sceKernelUnlockLwMutex(u32 workareaPtr, int count)
|
||||
|
||||
if (workarea.lockLevel == 0)
|
||||
{
|
||||
__KernelUnlockLwMutex(workarea, error);
|
||||
if (__KernelUnlockLwMutex(workarea, error))
|
||||
__KernelReSchedule("lwmutex unlocked");
|
||||
Memory::WriteStruct(workareaPtr, &workarea);
|
||||
__KernelReSchedule("lwmutex unlocked");
|
||||
}
|
||||
else
|
||||
Memory::WriteStruct(workareaPtr, &workarea);
|
||||
|
@ -78,7 +78,7 @@ bool __KernelClearSemaThreads(Semaphore *s, int reason)
|
||||
|
||||
// TODO: PSP_SEMA_ATTR_PRIORITY
|
||||
std::vector<SceUID>::iterator iter;
|
||||
for (iter = s->waitingThreads.begin(); iter!=s->waitingThreads.end(); iter++)
|
||||
for (iter = s->waitingThreads.begin(); iter != s->waitingThreads.end(); ++iter)
|
||||
{
|
||||
SceUID threadID = *iter;
|
||||
|
||||
@ -94,7 +94,7 @@ bool __KernelClearSemaThreads(Semaphore *s, int reason)
|
||||
__KernelResumeThreadFromWait(threadID, reason);
|
||||
wokeThreads = true;
|
||||
}
|
||||
s->waitingThreads.empty();
|
||||
s->waitingThreads.clear();
|
||||
|
||||
return wokeThreads;
|
||||
}
|
||||
@ -129,8 +129,8 @@ void sceKernelCancelSema(SceUID id, int newCount, u32 numWaitThreadsPtr)
|
||||
// We need to set the return value BEFORE rescheduling threads.
|
||||
RETURN(0);
|
||||
|
||||
__KernelClearSemaThreads(s, SCE_KERNEL_ERROR_WAIT_CANCEL);
|
||||
__KernelReSchedule("semaphore cancelled");
|
||||
if (__KernelClearSemaThreads(s, SCE_KERNEL_ERROR_WAIT_CANCEL))
|
||||
__KernelReSchedule("semaphore canceled");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -170,8 +170,6 @@ void sceKernelCreateSema(const char* name, u32 attr, int initVal, int maxVal, u3
|
||||
WARN_LOG(HLE,"sceKernelCreateSema(%s) unsupported options parameter.", name);
|
||||
|
||||
RETURN(id);
|
||||
|
||||
__KernelReSchedule("semaphore created");
|
||||
}
|
||||
|
||||
//int sceKernelDeleteSema(SceUID semaid);
|
||||
@ -184,9 +182,11 @@ void sceKernelDeleteSema(SceUID id)
|
||||
Semaphore *s = kernelObjects.Get<Semaphore>(id, error);
|
||||
if (s)
|
||||
{
|
||||
__KernelClearSemaThreads(s, SCE_KERNEL_ERROR_WAIT_DELETE);
|
||||
bool wokeThreads = __KernelClearSemaThreads(s, SCE_KERNEL_ERROR_WAIT_DELETE);
|
||||
RETURN(kernelObjects.Destroy<Semaphore>(id));
|
||||
__KernelReSchedule("semaphore deleted");
|
||||
|
||||
if (wokeThreads)
|
||||
__KernelReSchedule("semaphore deleted");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -206,7 +206,6 @@ void sceKernelReferSemaStatus(SceUID id, u32 infoPtr)
|
||||
DEBUG_LOG(HLE,"sceKernelReferSemaStatus(%i, %08x)", id, infoPtr);
|
||||
Memory::WriteStruct(infoPtr, &s->ns);
|
||||
RETURN(0);
|
||||
__KernelReSchedule("semaphore refer status");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -219,7 +218,6 @@ void sceKernelReferSemaStatus(SceUID id, u32 infoPtr)
|
||||
// void because it changes threads.
|
||||
void sceKernelSignalSema(SceUID id, int signal)
|
||||
{
|
||||
//TODO: check that this thing really works :)
|
||||
u32 error;
|
||||
Semaphore *s = kernelObjects.Get<Semaphore>(id, error);
|
||||
if (s)
|
||||
@ -237,11 +235,11 @@ void sceKernelSignalSema(SceUID id, int signal)
|
||||
// We need to set the return value BEFORE processing other threads.
|
||||
RETURN(0);
|
||||
|
||||
bool wokeThreads = false;
|
||||
retry:
|
||||
// TODO: PSP_SEMA_ATTR_PRIORITY
|
||||
bool wokeThreads = false;
|
||||
std::vector<SceUID>::iterator iter;
|
||||
for (iter = s->waitingThreads.begin(); iter!=s->waitingThreads.end(); iter++)
|
||||
retry:
|
||||
for (iter = s->waitingThreads.begin(); iter != s->waitingThreads.end(); ++iter)
|
||||
{
|
||||
SceUID threadID = *iter;
|
||||
|
||||
@ -261,17 +259,14 @@ retry:
|
||||
}
|
||||
|
||||
__KernelResumeThreadFromWait(threadID, 0);
|
||||
wokeThreads = true;
|
||||
s->waitingThreads.erase(iter);
|
||||
wokeThreads = true;
|
||||
goto retry;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
__KernelReSchedule("semaphore signalled");
|
||||
if (wokeThreads)
|
||||
__KernelReSchedule("semaphore signaled");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -336,9 +331,9 @@ void __KernelWaitSema(SceUID id, int wantedCount, u32 timeoutPtr, const char *ba
|
||||
__KernelWaitCurThread(WAITTYPE_SEMA, id, wantedCount, timeoutPtr, processCallbacks);
|
||||
if (processCallbacks)
|
||||
__KernelCheckCallbacks();
|
||||
}
|
||||
|
||||
__KernelReSchedule("semaphore waited");
|
||||
__KernelReSchedule("semaphore waited");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -387,8 +382,6 @@ void sceKernelPollSema(SceUID id, int wantedCount)
|
||||
}
|
||||
else
|
||||
RETURN(SCE_KERNEL_ERROR_SEMA_ZERO);
|
||||
|
||||
__KernelReSchedule("semaphore polled");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user