Cleanup some wrappers now that rescheds defer.

This commit is contained in:
Unknown W. Brackets 2012-12-09 00:09:25 -08:00
parent 5e8aa4c071
commit 3d57a4c838
8 changed files with 229 additions and 249 deletions

View File

@ -83,6 +83,11 @@ template<int func(u32)> void WrapI_U() {
RETURN(retval);
}
template<int func(u32, int)> void WrapI_UI() {
int retval = func(PARAM(0), PARAM(1));
RETURN(retval);
}
template<u32 func(int, u32, int)> void WrapU_IUI() {
u32 retval = func(PARAM(0), PARAM(1), PARAM(2));
RETURN(retval);
@ -130,6 +135,11 @@ template<void func(u32, const char *)> void WrapV_UC() {
func(PARAM(0), Memory::GetCharPointer(PARAM(1)));
}
template<int func(u32, const char *)> void WrapI_UC() {
int retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)));
RETURN(retval);
}
template<u32 func(u32, int , int , int, int, int, int)> void WrapU_UIIIIII() {
u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5), PARAM(6));
RETURN(retval);
@ -264,6 +274,11 @@ template<void func(u32, int, u32)> void WrapV_UIU() {
func(PARAM(0), PARAM(1), PARAM(2));
}
template<int func(u32, int, u32)> void WrapI_UIU() {
int retval = func(PARAM(0), PARAM(1), PARAM(2));
RETURN(retval);
}
template<void func(int, u32, u32, u32, u32)> void WrapV_IUUUU() {
func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4));
}
@ -280,16 +295,33 @@ template<void func(const char *, u32, int, u32)> void WrapV_CUIU() {
func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3));
}
template<int func(const char *, u32, int, u32)> void WrapI_CUIU() {
int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3));
RETURN(retval);
}
template<void func(u32, const char *, u32, int, u32)> void WrapV_UCUIU() {
func(PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2), PARAM(3),
PARAM(4));
}
template<int func(u32, const char *, u32, int, u32)> void WrapI_UCUIU() {
int retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2),
PARAM(3), PARAM(4));
RETURN(retval);
}
template<void func(const char *, u32, int, int, u32)> void WrapV_CUIIU() {
func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3),
PARAM(4));
}
template<int func(const char *, u32, int, int, u32)> void WrapI_CUIIU() {
int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2),
PARAM(3), PARAM(4));
RETURN(retval);
}
template<u32 func(u32, u32, u32, u32)> void WrapU_UUUU() {
u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3));
RETURN(retval);

View File

@ -332,23 +332,23 @@ const HLEFunction ThreadManForUser[] =
{0xCD203292,&WrapU_V<sceKernelCancelEventFlag>, "sceKernelCancelEventFlag"},
{0xA66B0120,&WrapU_IU<sceKernelReferEventFlagStatus>, "sceKernelReferEventFlagStatus"},
{0x8FFDF9A2,&WrapV_IIU<sceKernelCancelSema>, "sceKernelCancelSema"},
{0xD6DA4BA1,&WrapV_CUIIU<sceKernelCreateSema>, "sceKernelCreateSema"},
{0x28b6489c,&WrapV_I<sceKernelDeleteSema>, "sceKernelDeleteSema"},
{0x58b1f937,&WrapV_II<sceKernelPollSema>, "sceKernelPollSema"},
{0xBC6FEBC5,&WrapV_IU<sceKernelReferSemaStatus>, "sceKernelReferSemaStatus"},
{0x3F53E640,&WrapV_II<sceKernelSignalSema>, "sceKernelSignalSema"},
{0x4E3A1105,&WrapV_IIU<sceKernelWaitSema>, "sceKernelWaitSema"},
{0x6d212bac,&WrapV_IIU<sceKernelWaitSemaCB>, "sceKernelWaitSemaCB"},
{0x8FFDF9A2,&WrapI_IIU<sceKernelCancelSema>, "sceKernelCancelSema"},
{0xD6DA4BA1,&WrapI_CUIIU<sceKernelCreateSema>, "sceKernelCreateSema"},
{0x28b6489c,&WrapI_I<sceKernelDeleteSema>, "sceKernelDeleteSema"},
{0x58b1f937,&WrapI_II<sceKernelPollSema>, "sceKernelPollSema"},
{0xBC6FEBC5,&WrapI_IU<sceKernelReferSemaStatus>, "sceKernelReferSemaStatus"},
{0x3F53E640,&WrapI_II<sceKernelSignalSema>, "sceKernelSignalSema"},
{0x4E3A1105,&WrapI_IIU<sceKernelWaitSema>, "sceKernelWaitSema"},
{0x6d212bac,&WrapI_IIU<sceKernelWaitSemaCB>, "sceKernelWaitSemaCB"},
{0x60107536,&WrapV_U<sceKernelDeleteLwMutex>, "sceKernelDeleteLwMutex"},
{0x19CFF145,&WrapV_UCUIU<sceKernelCreateLwMutex>, "sceKernelCreateLwMutex"},
{0xf8170fbe,&WrapV_I<sceKernelDeleteMutex>, "sceKernelDeleteMutex"},
{0xB011B11F,&WrapV_IIU<sceKernelLockMutex>, "sceKernelLockMutex"},
{0x5bf4dd27,&WrapV_IIU<sceKernelLockMutexCB>, "sceKernelLockMutexCB"},
{0x6b30100f,&WrapV_II<sceKernelUnlockMutex>, "sceKernelUnlockMutex"},
{0xb7d098c6,&WrapV_CUIU<sceKernelCreateMutex>, "sceKernelCreateMutex"},
{0x0DDCD2C9,&WrapV_II<sceKernelTryLockMutex>, "sceKernelTryLockMutex"},
{0x60107536,&WrapI_U<sceKernelDeleteLwMutex>, "sceKernelDeleteLwMutex"},
{0x19CFF145,&WrapI_UCUIU<sceKernelCreateLwMutex>, "sceKernelCreateLwMutex"},
{0xf8170fbe,&WrapI_I<sceKernelDeleteMutex>, "sceKernelDeleteMutex"},
{0xB011B11F,&WrapI_IIU<sceKernelLockMutex>, "sceKernelLockMutex"},
{0x5bf4dd27,&WrapI_IIU<sceKernelLockMutexCB>, "sceKernelLockMutexCB"},
{0x6b30100f,&WrapI_II<sceKernelUnlockMutex>, "sceKernelUnlockMutex"},
{0xb7d098c6,&WrapI_CUIU<sceKernelCreateMutex>, "sceKernelCreateMutex"},
{0x0DDCD2C9,&WrapI_II<sceKernelTryLockMutex>, "sceKernelTryLockMutex"},
// NOTE: LockLwMutex and UnlockLwMutex are in Kernel_Library, see sceKernelInterrupt.cpp.
{0xFCCFAD26,sceKernelCancelWakeupThread,"sceKernelCancelWakeupThread"},

View File

@ -439,11 +439,11 @@ const HLEFunction Kernel_Library[] =
{0x47a0b729,sceKernelIsCpuIntrSuspended, "sceKernelIsCpuIntrSuspended"}, //flags
{0xb55249d2,sceKernelIsCpuIntrEnable, "sceKernelIsCpuIntrEnable"},
{0xa089eca4,sceKernelMemset, "sceKernelMemset"},
{0xDC692EE3,&WrapV_UI<sceKernelTryLockLwMutex>, "sceKernelTryLockLwMutex"},
{0x37431849,&WrapV_UI<sceKernelTryLockLwMutex_600>, "sceKernelTryLockLwMutex_600"},
{0xbea46419,&WrapV_UIU<sceKernelLockLwMutex>, "sceKernelLockLwMutex"},
{0x1FC64E09,&WrapV_UIU<sceKernelLockLwMutexCB>, "sceKernelLockLwMutexCB"},
{0x15b6446b,&WrapV_UI<sceKernelUnlockLwMutex>, "sceKernelUnlockLwMutex"},
{0xDC692EE3,&WrapI_UI<sceKernelTryLockLwMutex>, "sceKernelTryLockLwMutex"},
{0x37431849,&WrapI_UI<sceKernelTryLockLwMutex_600>, "sceKernelTryLockLwMutex_600"},
{0xbea46419,&WrapI_UIU<sceKernelLockLwMutex>, "sceKernelLockLwMutex"},
{0x1FC64E09,&WrapI_UIU<sceKernelLockLwMutexCB>, "sceKernelLockLwMutexCB"},
{0x15b6446b,&WrapI_UI<sceKernelUnlockLwMutex>, "sceKernelUnlockLwMutex"},
{0x293b45b8,sceKernelGetThreadId, "sceKernelGetThreadId"},
{0x1839852A,&WrapU_UUU<sceKernelMemcpy>,"sce_paf_private_memcpy"},
};

View File

@ -181,26 +181,19 @@ std::vector<SceUID>::iterator __KernelMutexFindPriority(std::vector<SceUID> &wai
return best;
}
void sceKernelCreateMutex(const char *name, u32 attr, int initialCount, u32 optionsPtr)
int sceKernelCreateMutex(const char *name, u32 attr, int initialCount, u32 optionsPtr)
{
if (!mutexInitComplete)
__KernelMutexInit();
u32 error = 0;
if (!name)
error = SCE_KERNEL_ERROR_ERROR;
else if (initialCount < 0)
error = SCE_KERNEL_ERROR_ILLEGAL_COUNT;
else if ((attr & PSP_MUTEX_ATTR_ALLOW_RECURSIVE) == 0 && initialCount > 1)
error = SCE_KERNEL_ERROR_ILLEGAL_COUNT;
return SCE_KERNEL_ERROR_ERROR;
if (initialCount < 0)
return SCE_KERNEL_ERROR_ILLEGAL_COUNT;
if ((attr & PSP_MUTEX_ATTR_ALLOW_RECURSIVE) == 0 && initialCount > 1)
return SCE_KERNEL_ERROR_ILLEGAL_COUNT;
if (error)
{
RETURN(error);
return;
}
DEBUG_LOG(HLE,"sceKernelCreateMutex(%s, %08x, %d, %08x)", name, attr, initialCount, optionsPtr);
DEBUG_LOG(HLE, "sceKernelCreateMutex(%s, %08x, %d, %08x)", name, attr, initialCount, optionsPtr);
Mutex *mutex = new Mutex();
SceUID id = kernelObjects.Create(mutex);
@ -218,9 +211,9 @@ void sceKernelCreateMutex(const char *name, u32 attr, int initialCount, u32 opti
__KernelMutexAcquireLock(mutex, initialCount);
if (optionsPtr != 0)
WARN_LOG(HLE,"sceKernelCreateMutex(%s) unsupported options parameter.", name);
WARN_LOG(HLE, "sceKernelCreateMutex(%s) unsupported options parameter.", name);
RETURN(id);
return id;
}
bool __KernelUnlockMutexForThread(Mutex *mutex, SceUID threadID, u32 &error, int result)
@ -250,7 +243,7 @@ bool __KernelUnlockMutexForThread(Mutex *mutex, SceUID threadID, u32 &error, int
return true;
}
void sceKernelDeleteMutex(SceUID id)
int sceKernelDeleteMutex(SceUID id)
{
DEBUG_LOG(HLE,"sceKernelDeleteMutex(%i)", id);
u32 error;
@ -266,13 +259,13 @@ void sceKernelDeleteMutex(SceUID id)
__KernelMutexEraseLock(mutex);
mutex->waitingThreads.clear();
RETURN(kernelObjects.Destroy<Mutex>(id));
if (wokeThreads)
hleReSchedule("mutex deleted");
return kernelObjects.Destroy<Mutex>(id);
}
else
RETURN(error);
return error;
}
bool __KernelLockMutex(Mutex *mutex, int count, u32 &error)
@ -356,10 +349,10 @@ void __KernelMutexThreadEnd(SceUID threadID)
u32 error;
// If it was waiting on the mutex, it should finish now.
SceUID mutexID = __KernelGetWaitID(threadID, WAITTYPE_MUTEX, error);
if (mutexID)
SceUID waitingMutexID = __KernelGetWaitID(threadID, WAITTYPE_MUTEX, error);
if (waitingMutexID)
{
Mutex *mutex = kernelObjects.Get<Mutex>(mutexID, error);
Mutex *mutex = kernelObjects.Get<Mutex>(waitingMutexID, error);
if (mutex)
mutex->waitingThreads.erase(std::remove(mutex->waitingThreads.begin(), mutex->waitingThreads.end(), threadID), mutex->waitingThreads.end());
}
@ -398,122 +391,109 @@ void __KernelWaitMutex(Mutex *mutex, u32 timeoutPtr)
}
// int sceKernelLockMutex(SceUID id, int count, int *timeout)
// void because it changes threads.
void sceKernelLockMutex(SceUID id, int count, u32 timeoutPtr)
int sceKernelLockMutex(SceUID id, int count, u32 timeoutPtr)
{
DEBUG_LOG(HLE,"sceKernelLockMutex(%i, %i, %08x)", id, count, timeoutPtr);
DEBUG_LOG(HLE, "sceKernelLockMutex(%i, %i, %08x)", id, count, timeoutPtr);
u32 error;
Mutex *mutex = kernelObjects.Get<Mutex>(id, error);
if (__KernelLockMutex(mutex, count, error))
{
RETURN(0);
}
return 0;
else if (error)
RETURN(error);
return error;
else
{
mutex->waitingThreads.push_back(__KernelGetCurThread());
__KernelWaitMutex(mutex, timeoutPtr);
__KernelWaitCurThread(WAITTYPE_MUTEX, id, count, timeoutPtr, false);
// Return value will be overwritten by wait.
return 0;
}
}
// int sceKernelLockMutexCB(SceUID id, int count, int *timeout)
// void because it changes threads.
void sceKernelLockMutexCB(SceUID id, int count, u32 timeoutPtr)
int sceKernelLockMutexCB(SceUID id, int count, u32 timeoutPtr)
{
DEBUG_LOG(HLE,"sceKernelLockMutexCB(%i, %i, %08x)", id, count, timeoutPtr);
DEBUG_LOG(HLE, "sceKernelLockMutexCB(%i, %i, %08x)", id, count, timeoutPtr);
u32 error;
Mutex *mutex = kernelObjects.Get<Mutex>(id, error);
if (__KernelLockMutex(mutex, count, error))
{
RETURN(0);
hleCheckCurrentCallbacks();
return 0;
}
else if (error)
RETURN(error);
return error;
else
{
mutex->waitingThreads.push_back(__KernelGetCurThread());
__KernelWaitMutex(mutex, timeoutPtr);
__KernelWaitCurThread(WAITTYPE_MUTEX, id, count, timeoutPtr, true);
// Return value will be overwritten by wait.
return 0;
}
}
// int sceKernelTryLockMutex(SceUID id, int count)
// void because it changes threads.
void sceKernelTryLockMutex(SceUID id, int count)
int sceKernelTryLockMutex(SceUID id, int count)
{
DEBUG_LOG(HLE,"sceKernelTryLockMutex(%i, %i)", id, count);
DEBUG_LOG(HLE, "sceKernelTryLockMutex(%i, %i)", id, count);
u32 error;
Mutex *mutex = kernelObjects.Get<Mutex>(id, error);
if (__KernelLockMutex(mutex, count, error))
RETURN(0);
return 0;
else if (error)
RETURN(error);
return error;
else
RETURN(PSP_MUTEX_ERROR_TRYLOCK_FAILED);
return PSP_MUTEX_ERROR_TRYLOCK_FAILED;
}
// int sceKernelUnlockMutex(SceUID id, int count)
// void because it changes threads.
void sceKernelUnlockMutex(SceUID id, int count)
int sceKernelUnlockMutex(SceUID id, int count)
{
DEBUG_LOG(HLE,"sceKernelUnlockMutex(%i, %i)", id, count);
DEBUG_LOG(HLE, "sceKernelUnlockMutex(%i, %i)", id, count);
u32 error;
Mutex *mutex = kernelObjects.Get<Mutex>(id, error);
if (!error)
{
if (count <= 0)
error = SCE_KERNEL_ERROR_ILLEGAL_COUNT;
else if ((mutex->nm.attr & PSP_MUTEX_ATTR_ALLOW_RECURSIVE) == 0 && count > 1)
error = SCE_KERNEL_ERROR_ILLEGAL_COUNT;
else if (mutex->nm.lockLevel == 0 || mutex->nm.lockThread != __KernelGetCurThread())
error = PSP_MUTEX_ERROR_NOT_LOCKED;
else if (mutex->nm.lockLevel < count)
error = PSP_MUTEX_ERROR_UNLOCK_UNDERFLOW;
}
if (error)
{
RETURN(error);
return;
}
return error;
if (count <= 0)
return SCE_KERNEL_ERROR_ILLEGAL_COUNT;
if ((mutex->nm.attr & PSP_MUTEX_ATTR_ALLOW_RECURSIVE) == 0 && count > 1)
return SCE_KERNEL_ERROR_ILLEGAL_COUNT;
if (mutex->nm.lockLevel == 0 || mutex->nm.lockThread != __KernelGetCurThread())
return PSP_MUTEX_ERROR_NOT_LOCKED;
if (mutex->nm.lockLevel < count)
return PSP_MUTEX_ERROR_UNLOCK_UNDERFLOW;
mutex->nm.lockLevel -= count;
RETURN(0);
if (mutex->nm.lockLevel == 0)
{
if (__KernelUnlockMutex(mutex, error))
hleReSchedule("mutex unlocked");
}
return 0;
}
void sceKernelCreateLwMutex(u32 workareaPtr, const char *name, u32 attr, int initialCount, u32 optionsPtr)
int sceKernelCreateLwMutex(u32 workareaPtr, const char *name, u32 attr, int initialCount, u32 optionsPtr)
{
if (!mutexInitComplete)
__KernelMutexInit();
DEBUG_LOG(HLE,"sceKernelCreateLwMutex(%08x, %s, %08x, %d, %08x)", workareaPtr, name, attr, initialCount, optionsPtr);
DEBUG_LOG(HLE, "sceKernelCreateLwMutex(%08x, %s, %08x, %d, %08x)", workareaPtr, name, attr, initialCount, optionsPtr);
u32 error = 0;
if (!name)
error = SCE_KERNEL_ERROR_ERROR;
return SCE_KERNEL_ERROR_ERROR;
else if (initialCount < 0)
error = SCE_KERNEL_ERROR_ILLEGAL_COUNT;
return SCE_KERNEL_ERROR_ILLEGAL_COUNT;
else if ((attr & PSP_MUTEX_ATTR_ALLOW_RECURSIVE) == 0 && initialCount > 1)
error = SCE_KERNEL_ERROR_ILLEGAL_COUNT;
if (error)
{
RETURN(error);
return;
}
return SCE_KERNEL_ERROR_ILLEGAL_COUNT;
LwMutex *mutex = new LwMutex();
SceUID id = kernelObjects.Create(mutex);
@ -536,9 +516,9 @@ void sceKernelCreateLwMutex(u32 workareaPtr, const char *name, u32 attr, int ini
Memory::WriteStruct(workareaPtr, &workarea);
if (optionsPtr != 0)
WARN_LOG(HLE,"sceKernelCreateLwMutex(%s) unsupported options parameter.", name);
WARN_LOG(HLE, "sceKernelCreateLwMutex(%s) unsupported options parameter.", name);
RETURN(0);
return 0;
}
bool __KernelUnlockLwMutexForThread(LwMutex *mutex, NativeLwMutexWorkarea &workarea, SceUID threadID, u32 &error, int result)
@ -568,15 +548,12 @@ bool __KernelUnlockLwMutexForThread(LwMutex *mutex, NativeLwMutexWorkarea &worka
return true;
}
void sceKernelDeleteLwMutex(u32 workareaPtr)
int sceKernelDeleteLwMutex(u32 workareaPtr)
{
DEBUG_LOG(HLE,"sceKernelDeleteLwMutex(%08x)", workareaPtr);
DEBUG_LOG(HLE, "sceKernelDeleteLwMutex(%08x)", workareaPtr);
if (!workareaPtr || !Memory::IsValidAddress(workareaPtr))
{
RETURN(SCE_KERNEL_ERROR_ILLEGAL_ADDR);
return;
}
return SCE_KERNEL_ERROR_ILLEGAL_ADDR;
NativeLwMutexWorkarea workarea;
Memory::ReadStruct(workareaPtr, &workarea);
@ -591,15 +568,16 @@ void sceKernelDeleteLwMutex(u32 workareaPtr)
wokeThreads |= __KernelUnlockLwMutexForThread(mutex, workarea, *iter, error, SCE_KERNEL_ERROR_WAIT_DELETE);
mutex->waitingThreads.clear();
RETURN(kernelObjects.Destroy<LwMutex>(workarea.uid));
workarea.clear();
Memory::WriteStruct(workareaPtr, &workarea);
if (wokeThreads)
hleReSchedule("lwmutex deleted");
return kernelObjects.Destroy<LwMutex>(mutex->GetUID());
}
else
RETURN(error);
return error;
}
bool __KernelLockLwMutex(NativeLwMutexWorkarea &workarea, int count, u32 &error)
@ -710,9 +688,9 @@ void __KernelWaitLwMutex(LwMutex *mutex, u32 timeoutPtr)
CoreTiming::ScheduleEvent(usToCycles(micro), lwMutexWaitTimer, __KernelGetCurThread());
}
void sceKernelTryLockLwMutex(u32 workareaPtr, int count)
int sceKernelTryLockLwMutex(u32 workareaPtr, int count)
{
DEBUG_LOG(HLE,"sceKernelTryLockLwMutex(%08x, %i)", workareaPtr, count);
DEBUG_LOG(HLE, "sceKernelTryLockLwMutex(%08x, %i)", workareaPtr, count);
NativeLwMutexWorkarea workarea;
Memory::ReadStruct(workareaPtr, &workarea);
@ -721,17 +699,18 @@ void sceKernelTryLockLwMutex(u32 workareaPtr, int count)
if (__KernelLockLwMutex(workarea, count, error))
{
Memory::WriteStruct(workareaPtr, &workarea);
RETURN(0);
return 0;
}
// Unlike sceKernelTryLockLwMutex_600, this always returns the same error.
else if (error)
RETURN(PSP_MUTEX_ERROR_TRYLOCK_FAILED);
return PSP_MUTEX_ERROR_TRYLOCK_FAILED;
else
RETURN(PSP_MUTEX_ERROR_TRYLOCK_FAILED);
return PSP_MUTEX_ERROR_TRYLOCK_FAILED;
}
void sceKernelTryLockLwMutex_600(u32 workareaPtr, int count)
int sceKernelTryLockLwMutex_600(u32 workareaPtr, int count)
{
DEBUG_LOG(HLE,"sceKernelTryLockLwMutex_600(%08x, %i)", workareaPtr, count);
DEBUG_LOG(HLE, "sceKernelTryLockLwMutex_600(%08x, %i)", workareaPtr, count);
NativeLwMutexWorkarea workarea;
Memory::ReadStruct(workareaPtr, &workarea);
@ -740,17 +719,17 @@ void sceKernelTryLockLwMutex_600(u32 workareaPtr, int count)
if (__KernelLockLwMutex(workarea, count, error))
{
Memory::WriteStruct(workareaPtr, &workarea);
RETURN(0);
return 0;
}
else if (error)
RETURN(error);
return error;
else
RETURN(PSP_LWMUTEX_ERROR_TRYLOCK_FAILED);
return PSP_LWMUTEX_ERROR_TRYLOCK_FAILED;
}
void sceKernelLockLwMutex(u32 workareaPtr, int count, u32 timeoutPtr)
int sceKernelLockLwMutex(u32 workareaPtr, int count, u32 timeoutPtr)
{
DEBUG_LOG(HLE,"sceKernelLockLwMutex(%08x, %i, %08x)", workareaPtr, count, timeoutPtr);
DEBUG_LOG(HLE, "sceKernelLockLwMutex(%08x, %i, %08x)", workareaPtr, count, timeoutPtr);
NativeLwMutexWorkarea workarea;
Memory::ReadStruct(workareaPtr, &workarea);
@ -759,10 +738,10 @@ void sceKernelLockLwMutex(u32 workareaPtr, int count, u32 timeoutPtr)
if (__KernelLockLwMutex(workarea, count, error))
{
Memory::WriteStruct(workareaPtr, &workarea);
RETURN(0);
return 0;
}
else if (error)
RETURN(error);
return error;
else
{
LwMutex *mutex = kernelObjects.Get<LwMutex>(workarea.uid, error);
@ -771,15 +750,18 @@ void sceKernelLockLwMutex(u32 workareaPtr, int count, u32 timeoutPtr)
mutex->waitingThreads.push_back(__KernelGetCurThread());
__KernelWaitLwMutex(mutex, timeoutPtr);
__KernelWaitCurThread(WAITTYPE_LWMUTEX, workarea.uid, count, timeoutPtr, false);
// Return value will be overwritten by wait.
return 0;
}
else
RETURN(error);
return error;
}
}
void sceKernelLockLwMutexCB(u32 workareaPtr, int count, u32 timeoutPtr)
int sceKernelLockLwMutexCB(u32 workareaPtr, int count, u32 timeoutPtr)
{
DEBUG_LOG(HLE,"sceKernelLockLwMutexCB(%08x, %i, %08x)", workareaPtr, count, timeoutPtr);
DEBUG_LOG(HLE, "sceKernelLockLwMutexCB(%08x, %i, %08x)", workareaPtr, count, timeoutPtr);
NativeLwMutexWorkarea workarea;
Memory::ReadStruct(workareaPtr, &workarea);
@ -788,11 +770,11 @@ void sceKernelLockLwMutexCB(u32 workareaPtr, int count, u32 timeoutPtr)
if (__KernelLockLwMutex(workarea, count, error))
{
Memory::WriteStruct(workareaPtr, &workarea);
RETURN(0);
hleCheckCurrentCallbacks();
return 0;
}
else if (error)
RETURN(error);
return error;
else
{
LwMutex *mutex = kernelObjects.Get<LwMutex>(workarea.uid, error);
@ -801,42 +783,38 @@ void sceKernelLockLwMutexCB(u32 workareaPtr, int count, u32 timeoutPtr)
mutex->waitingThreads.push_back(__KernelGetCurThread());
__KernelWaitLwMutex(mutex, timeoutPtr);
__KernelWaitCurThread(WAITTYPE_LWMUTEX, workarea.uid, count, timeoutPtr, true);
// Return value will be overwritten by wait.
return 0;
}
else
RETURN(error);
return error;
}
}
void sceKernelUnlockLwMutex(u32 workareaPtr, int count)
int sceKernelUnlockLwMutex(u32 workareaPtr, int count)
{
DEBUG_LOG(HLE,"sceKernelUnlockLwMutex(%08x, %i)", workareaPtr, count);
DEBUG_LOG(HLE, "sceKernelUnlockLwMutex(%08x, %i)", workareaPtr, count);
NativeLwMutexWorkarea workarea;
Memory::ReadStruct(workareaPtr, &workarea);
u32 error = 0;
if (workarea.uid == -1)
error = PSP_LWMUTEX_ERROR_NO_SUCH_LWMUTEX;
return PSP_LWMUTEX_ERROR_NO_SUCH_LWMUTEX;
else if (count <= 0)
error = SCE_KERNEL_ERROR_ILLEGAL_COUNT;
return SCE_KERNEL_ERROR_ILLEGAL_COUNT;
else if ((workarea.attr & PSP_MUTEX_ATTR_ALLOW_RECURSIVE) == 0 && count > 1)
error = SCE_KERNEL_ERROR_ILLEGAL_COUNT;
return SCE_KERNEL_ERROR_ILLEGAL_COUNT;
else if (workarea.lockLevel == 0 || workarea.lockThread != __KernelGetCurThread())
error = PSP_LWMUTEX_ERROR_NOT_LOCKED;
return PSP_LWMUTEX_ERROR_NOT_LOCKED;
else if (workarea.lockLevel < count)
error = PSP_LWMUTEX_ERROR_UNLOCK_UNDERFLOW;
if (error)
{
RETURN(error);
return;
}
return PSP_LWMUTEX_ERROR_UNLOCK_UNDERFLOW;
workarea.lockLevel -= count;
RETURN(0);
if (workarea.lockLevel == 0)
{
u32 error;
if (__KernelUnlockLwMutex(workarea, error))
hleReSchedule("lwmutex unlocked");
Memory::WriteStruct(workareaPtr, &workarea);
@ -844,4 +822,5 @@ void sceKernelUnlockLwMutex(u32 workareaPtr, int count)
else
Memory::WriteStruct(workareaPtr, &workarea);
return 0;
}

View File

@ -17,20 +17,20 @@
#pragma once
void sceKernelCreateMutex(const char *name, u32 attr, int initialCount, u32 optionsPtr);
void sceKernelDeleteMutex(SceUID id);
void sceKernelLockMutex(SceUID id, int count, u32 timeoutPtr);
void sceKernelLockMutexCB(SceUID id, int count, u32 timeoutPtr);
void sceKernelTryLockMutex(SceUID id, int count);
void sceKernelUnlockMutex(SceUID id, int count);
int sceKernelCreateMutex(const char *name, u32 attr, int initialCount, u32 optionsPtr);
int sceKernelDeleteMutex(SceUID id);
int sceKernelLockMutex(SceUID id, int count, u32 timeoutPtr);
int sceKernelLockMutexCB(SceUID id, int count, u32 timeoutPtr);
int sceKernelTryLockMutex(SceUID id, int count);
int sceKernelUnlockMutex(SceUID id, int count);
void sceKernelCreateLwMutex(u32 workareaPtr, const char *name, u32 attr, int initialCount, u32 optionsPtr);
void sceKernelDeleteLwMutex(u32 workareaPtr);
void sceKernelTryLockLwMutex(u32 workareaPtr, int count);
void sceKernelTryLockLwMutex_600(u32 workareaPtr, int count);
void sceKernelLockLwMutex(u32 workareaPtr, int count, u32 timeoutPtr);
void sceKernelLockLwMutexCB(u32 workareaPtr, int count, u32 timeoutPtr);
void sceKernelUnlockLwMutex(u32 workareaPtr, int count);
int sceKernelCreateLwMutex(u32 workareaPtr, const char *name, u32 attr, int initialCount, u32 optionsPtr);
int sceKernelDeleteLwMutex(u32 workareaPtr);
int sceKernelTryLockLwMutex(u32 workareaPtr, int count);
int sceKernelTryLockLwMutex_600(u32 workareaPtr, int count);
int sceKernelLockLwMutex(u32 workareaPtr, int count, u32 timeoutPtr);
int sceKernelLockLwMutexCB(u32 workareaPtr, int count, u32 timeoutPtr);
int sceKernelUnlockLwMutex(u32 workareaPtr, int count);
void __KernelMutexTimeout(u64 userdata, int cyclesLate);
void __KernelLwMutexTimeout(u64 userdata, int cyclesLate);

View File

@ -138,25 +138,19 @@ std::vector<SceUID>::iterator __KernelSemaFindPriority(std::vector<SceUID> &wait
}
// int sceKernelCancelSema(SceUID id, int newCount, int *numWaitThreads);
// void because it changes threads.
void sceKernelCancelSema(SceUID id, int newCount, u32 numWaitThreadsPtr)
int sceKernelCancelSema(SceUID id, int newCount, u32 numWaitThreadsPtr)
{
DEBUG_LOG(HLE,"sceKernelCancelSema(%i)", id);
DEBUG_LOG(HLE, "sceKernelCancelSema(%i)", id);
u32 error;
Semaphore *s = kernelObjects.Get<Semaphore>(id, error);
if (s)
{
if (newCount > s->ns.maxCount)
{
RETURN(SCE_KERNEL_ERROR_ILLEGAL_COUNT);
return;
}
return SCE_KERNEL_ERROR_ILLEGAL_COUNT;
if (numWaitThreadsPtr)
{
Memory::Write_U32(s->ns.numWaitThreads, numWaitThreadsPtr);
}
if (newCount < 0)
s->ns.currentCount = s->ns.initCount;
@ -164,31 +158,26 @@ void sceKernelCancelSema(SceUID id, int newCount, u32 numWaitThreadsPtr)
s->ns.currentCount = newCount;
s->ns.numWaitThreads = 0;
// We need to set the return value BEFORE rescheduling threads.
RETURN(0);
if (__KernelClearSemaThreads(s, SCE_KERNEL_ERROR_WAIT_CANCEL))
hleReSchedule("semaphore canceled");
return 0;
}
else
{
ERROR_LOG(HLE, "sceKernelCancelSema : Trying to cancel invalid semaphore %i", id);
RETURN(error);
return error;
}
}
//SceUID sceKernelCreateSema(const char *name, SceUInt attr, int initVal, int maxVal, SceKernelSemaOptParam *option);
// void because it changes threads.
void sceKernelCreateSema(const char* name, u32 attr, int initVal, int maxVal, u32 optionPtr)
int sceKernelCreateSema(const char* name, u32 attr, int initVal, int maxVal, u32 optionPtr)
{
if (!semaInitComplete)
__KernelSemaInit();
if (!name)
{
RETURN(SCE_KERNEL_ERROR_ERROR);
return;
}
return SCE_KERNEL_ERROR_ERROR;
Semaphore *s = new Semaphore;
SceUID id = kernelObjects.Create(s);
@ -202,76 +191,67 @@ void sceKernelCreateSema(const char* name, u32 attr, int initVal, int maxVal, u3
s->ns.maxCount = maxVal;
s->ns.numWaitThreads = 0;
DEBUG_LOG(HLE,"%i=sceKernelCreateSema(%s, %08x, %i, %i, %08x)", id, s->ns.name, s->ns.attr, s->ns.initCount, s->ns.maxCount, optionPtr);
DEBUG_LOG(HLE, "%i=sceKernelCreateSema(%s, %08x, %i, %i, %08x)", id, s->ns.name, s->ns.attr, s->ns.initCount, s->ns.maxCount, optionPtr);
if (optionPtr != 0)
WARN_LOG(HLE,"sceKernelCreateSema(%s) unsupported options parameter.", name);
WARN_LOG(HLE, "sceKernelCreateSema(%s) unsupported options parameter.", name);
RETURN(id);
return id;
}
//int sceKernelDeleteSema(SceUID semaid);
// void because it changes threads.
void sceKernelDeleteSema(SceUID id)
int sceKernelDeleteSema(SceUID id)
{
DEBUG_LOG(HLE,"sceKernelDeleteSema(%i)", id);
DEBUG_LOG(HLE, "sceKernelDeleteSema(%i)", id);
u32 error;
Semaphore *s = kernelObjects.Get<Semaphore>(id, error);
if (s)
{
bool wokeThreads = __KernelClearSemaThreads(s, SCE_KERNEL_ERROR_WAIT_DELETE);
RETURN(kernelObjects.Destroy<Semaphore>(id));
if (wokeThreads)
hleReSchedule("semaphore deleted");
return kernelObjects.Destroy<Semaphore>(id);
}
else
{
ERROR_LOG(HLE, "sceKernelDeleteSema : Trying to delete invalid semaphore %i", id);
RETURN(error);
return error;
}
}
//int sceKernelDeleteSema(SceUID semaid, SceKernelSemaInfo *info);
// void because it changes threads.
void sceKernelReferSemaStatus(SceUID id, u32 infoPtr)
int sceKernelReferSemaStatus(SceUID id, u32 infoPtr)
{
u32 error;
Semaphore *s = kernelObjects.Get<Semaphore>(id, error);
if (s)
{
DEBUG_LOG(HLE,"sceKernelReferSemaStatus(%i, %08x)", id, infoPtr);
DEBUG_LOG(HLE, "sceKernelReferSemaStatus(%i, %08x)", id, infoPtr);
Memory::WriteStruct(infoPtr, &s->ns);
RETURN(0);
return 0;
}
else
{
ERROR_LOG(HLE,"Error %08x", error);
RETURN(error);
ERROR_LOG(HLE, "sceKernelReferSemaStatus: error %08x", error);
return error;
}
}
//int sceKernelSignalSema(SceUID semaid, int signal);
// void because it changes threads.
void sceKernelSignalSema(SceUID id, int signal)
int sceKernelSignalSema(SceUID id, int signal)
{
u32 error;
Semaphore *s = kernelObjects.Get<Semaphore>(id, error);
if (s)
{
if (s->ns.currentCount + signal - s->ns.numWaitThreads > s->ns.maxCount)
{
RETURN(SCE_KERNEL_ERROR_SEMA_OVF);
return;
}
return SCE_KERNEL_ERROR_SEMA_OVF;
int oldval = s->ns.currentCount;
s->ns.currentCount += signal;
DEBUG_LOG(HLE,"sceKernelSignalSema(%i, %i) (old: %i, new: %i)", id, signal, oldval, s->ns.currentCount);
// We need to set the return value BEFORE processing other threads.
RETURN(0);
DEBUG_LOG(HLE, "sceKernelSignalSema(%i, %i) (old: %i, new: %i)", id, signal, oldval, s->ns.currentCount);
bool wokeThreads = false;
std::vector<SceUID>::iterator iter, end, best;
@ -292,11 +272,13 @@ retry:
if (wokeThreads)
hleReSchedule("semaphore signaled");
return 0;
}
else
{
ERROR_LOG(HLE, "sceKernelSignalSema : Trying to signal invalid semaphore %i", id);
RETURN(error);
return error;
}
}
@ -337,20 +319,14 @@ void __KernelSetSemaTimeout(Semaphore *s, u32 timeoutPtr)
CoreTiming::ScheduleEvent(usToCycles(micro), semaWaitTimer, __KernelGetCurThread());
}
void __KernelWaitSema(SceUID id, int wantedCount, u32 timeoutPtr, const char *badSemaMessage, bool processCallbacks)
int __KernelWaitSema(SceUID id, int wantedCount, u32 timeoutPtr, const char *badSemaMessage, bool processCallbacks)
{
u32 error;
Semaphore *s = kernelObjects.Get<Semaphore>(id, error);
if (s)
{
if (wantedCount > s->ns.maxCount || wantedCount <= 0)
{
RETURN(SCE_KERNEL_ERROR_ILLEGAL_COUNT);
return;
}
// We need to set the return value BEFORE processing callbacks / etc.
RETURN(0);
return SCE_KERNEL_ERROR_ILLEGAL_COUNT;
if (s->ns.currentCount >= wantedCount)
{
@ -365,42 +341,39 @@ void __KernelWaitSema(SceUID id, int wantedCount, u32 timeoutPtr, const char *ba
__KernelSetSemaTimeout(s, timeoutPtr);
__KernelWaitCurThread(WAITTYPE_SEMA, id, wantedCount, timeoutPtr, processCallbacks);
}
return 0;
}
else
{
ERROR_LOG(HLE, badSemaMessage, id);
RETURN(error);
return error;
}
}
//int sceKernelWaitSema(SceUID semaid, int signal, SceUInt *timeout);
// void because it changes threads.
void sceKernelWaitSema(SceUID id, int wantedCount, u32 timeoutPtr)
int sceKernelWaitSema(SceUID id, int wantedCount, u32 timeoutPtr)
{
DEBUG_LOG(HLE,"sceKernelWaitSema(%i, %i, %i)", id, wantedCount, timeoutPtr);
DEBUG_LOG(HLE, "sceKernelWaitSema(%i, %i, %i)", id, wantedCount, timeoutPtr);
__KernelWaitSema(id, wantedCount, timeoutPtr, "sceKernelWaitSema: Trying to wait for invalid semaphore %i", false);
return __KernelWaitSema(id, wantedCount, timeoutPtr, "sceKernelWaitSema: Trying to wait for invalid semaphore %i", false);
}
//int sceKernelWaitSemaCB(SceUID semaid, int signal, SceUInt *timeout);
// void because it changes threads.
void sceKernelWaitSemaCB(SceUID id, int wantedCount, u32 timeoutPtr)
int sceKernelWaitSemaCB(SceUID id, int wantedCount, u32 timeoutPtr)
{
DEBUG_LOG(HLE,"sceKernelWaitSemaCB(%i, %i, %i)", id, wantedCount, timeoutPtr);
DEBUG_LOG(HLE, "sceKernelWaitSemaCB(%i, %i, %i)", id, wantedCount, timeoutPtr);
__KernelWaitSema(id, wantedCount, timeoutPtr, "sceKernelWaitSemaCB: Trying to wait for invalid semaphore %i", true);
return __KernelWaitSema(id, wantedCount, timeoutPtr, "sceKernelWaitSemaCB: Trying to wait for invalid semaphore %i", true);
}
// Should be same as WaitSema but without the wait, instead returning SCE_KERNEL_ERROR_SEMA_ZERO
void sceKernelPollSema(SceUID id, int wantedCount)
int sceKernelPollSema(SceUID id, int wantedCount)
{
DEBUG_LOG(HLE,"sceKernelPollSema(%i, %i)", id, wantedCount);
DEBUG_LOG(HLE, "sceKernelPollSema(%i, %i)", id, wantedCount);
if (wantedCount <= 0)
{
RETURN(SCE_KERNEL_ERROR_ILLEGAL_COUNT);
return;
}
return SCE_KERNEL_ERROR_ILLEGAL_COUNT;
u32 error;
Semaphore *s = kernelObjects.Get<Semaphore>(id, error);
@ -409,15 +382,15 @@ void sceKernelPollSema(SceUID id, int wantedCount)
if (s->ns.currentCount >= wantedCount)
{
s->ns.currentCount -= wantedCount;
RETURN(0);
return 0;
}
else
RETURN(SCE_KERNEL_ERROR_SEMA_ZERO);
return SCE_KERNEL_ERROR_SEMA_ZERO;
}
else
{
ERROR_LOG(HLE, "sceKernelPollSema: Trying to poll invalid semaphore %i", id);
RETURN(error);
return error;
}
}

View File

@ -17,13 +17,13 @@
#pragma once
void sceKernelCancelSema(SceUID id, int newCount, u32 numWaitThreadsPtr);
void sceKernelCreateSema(const char* name, u32 attr, int initVal, int maxVal, u32 optionPtr);
void sceKernelDeleteSema(SceUID id);
void sceKernelPollSema(SceUID id, int wantedCount);
void sceKernelReferSemaStatus(SceUID id, u32 infoPtr);
void sceKernelSignalSema(SceUID id, int signal);
void sceKernelWaitSema(SceUID semaid, int signal, u32 timeoutPtr);
void sceKernelWaitSemaCB(SceUID semaid, int signal, u32 timeoutPtr);
int sceKernelCancelSema(SceUID id, int newCount, u32 numWaitThreadsPtr);
int sceKernelCreateSema(const char* name, u32 attr, int initVal, int maxVal, u32 optionPtr);
int sceKernelDeleteSema(SceUID id);
int sceKernelPollSema(SceUID id, int wantedCount);
int sceKernelReferSemaStatus(SceUID id, u32 infoPtr);
int sceKernelSignalSema(SceUID id, int signal);
int sceKernelWaitSema(SceUID semaid, int signal, u32 timeoutPtr);
int sceKernelWaitSemaCB(SceUID semaid, int signal, u32 timeoutPtr);
void __KernelSemaTimeout(u64 userdata, int cycleslate);

View File

@ -107,13 +107,10 @@ u32 sceUmdGetDiscInfo(u32 infoAddr)
return PSP_ERROR_UMD_INVALID_PARAM;
}
void sceUmdActivate(u32 unknown, const char *name)
int sceUmdActivate(u32 unknown, const char *name)
{
if (unknown < 1 || unknown > 2)
{
RETURN(PSP_ERROR_UMD_INVALID_PARAM);
return;
}
return PSP_ERROR_UMD_INVALID_PARAM;
bool changed = umdActivated == 0;
__KernelUmdActivate();
@ -129,20 +126,18 @@ void sceUmdActivate(u32 unknown, const char *name)
u32 notifyArg = UMD_PRESENT | UMD_READABLE;
__KernelNotifyCallbackType(THREAD_CALLBACK_UMD, -1, notifyArg);
RETURN(0);
if (changed)
hleReSchedule("umd activated");
return 0;
}
void sceUmdDeactivate(u32 unknown, const char *name)
int sceUmdDeactivate(u32 unknown, const char *name)
{
// Why 18? No idea.
if (unknown < 0 || unknown > 18)
{
RETURN(PSP_ERROR_UMD_INVALID_PARAM);
return;
}
return PSP_ERROR_UMD_INVALID_PARAM;
bool changed = umdActivated != 0;
__KernelUmdDeactivate();
@ -158,10 +153,11 @@ void sceUmdDeactivate(u32 unknown, const char *name)
u32 notifyArg = UMD_PRESENT | UMD_READY;
__KernelNotifyCallbackType(THREAD_CALLBACK_UMD, -1, notifyArg);
RETURN(0);
if (changed)
hleReSchedule("umd deactivated");
return 0;
}
u32 sceUmdRegisterUMDCallBack(u32 cbId)
@ -260,10 +256,8 @@ void sceUmdWaitDriveStatWithTimer(u32 stat, u32 timeout)
}
void sceUmdWaitDriveStatCB(u32 stat, u32 timeout)
int sceUmdWaitDriveStatCB(u32 stat, u32 timeout)
{
RETURN(0);
if (driveCBId != -1)
{
DEBUG_LOG(HLE,"0=sceUmdWaitDriveStatCB(stat = %08x, timeout = %d)", stat, timeout);
@ -285,6 +279,8 @@ void sceUmdWaitDriveStatCB(u32 stat, u32 timeout)
}
else if (driveCBId != -1)
hleReSchedule("umd stat waited");
return 0;
}
void sceUmdCancelWaitDriveStat()
@ -306,13 +302,13 @@ u32 sceUmdGetErrorStat()
const HLEFunction sceUmdUser[] =
{
{0xC6183D47,WrapV_UC<sceUmdActivate>,"sceUmdActivate"},
{0xC6183D47,WrapI_UC<sceUmdActivate>,"sceUmdActivate"},
{0x6B4A146C,&WrapU_V<sceUmdGetDriveStat>,"sceUmdGetDriveStat"},
{0x46EBB729,WrapI_V<sceUmdCheckMedium>,"sceUmdCheckMedium"},
{0xE83742BA,WrapV_UC<sceUmdDeactivate>,"sceUmdDeactivate"},
{0xE83742BA,WrapI_UC<sceUmdDeactivate>,"sceUmdDeactivate"},
{0x8EF08FCE,WrapV_U<sceUmdWaitDriveStat>,"sceUmdWaitDriveStat"},
{0x56202973,WrapV_UU<sceUmdWaitDriveStatWithTimer>,"sceUmdWaitDriveStatWithTimer"},
{0x4A9E5E29,WrapV_UU<sceUmdWaitDriveStatCB>,"sceUmdWaitDriveStatCB"},
{0x4A9E5E29,WrapI_UU<sceUmdWaitDriveStatCB>,"sceUmdWaitDriveStatCB"},
{0x6af9b50a,sceUmdCancelWaitDriveStat,"sceUmdCancelWaitDriveStat"},
{0x6B4A146C,&WrapU_V<sceUmdGetDriveStat>,"sceUmdGetDriveStat"},
{0x20628E6F,&WrapU_V<sceUmdGetErrorStat>,"sceUmdGetErrorStat"},