Additional semaphore fixes with updated tests.

This commit is contained in:
Unknown W. Brackets 2012-11-17 01:43:01 -08:00
parent 2e9e61dfc6
commit 157858819b
6 changed files with 53 additions and 38 deletions

View File

@ -118,11 +118,6 @@ template<int func(const char *, u32, u32, u32)> void WrapI_CUUU() {
RETURN(retval);
}
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(const char *, u32)> void WrapU_CU() {
int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1));
RETURN((u32)retval);
@ -163,6 +158,10 @@ template<void func(u32, u32, u32, u32)> void WrapV_UUUU() {
func(PARAM(0), PARAM(1), PARAM(2), PARAM(3));
}
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<u32 func(u32, u32, u32, u32)> void WrapU_UUUU() {
u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3));
RETURN(retval);

View File

@ -328,10 +328,10 @@ const HLEFunction ThreadManForUser[] =
{0xA66B0120,&WrapU_IU<sceKernelReferEventFlagStatus>, "sceKernelReferEventFlagStatus"},
{0x8FFDF9A2,&WrapV_IIU<sceKernelCancelSema>, "sceKernelCancelSema"},
{0xD6DA4BA1,&WrapI_CUIIU<sceKernelCreateSema>, "sceKernelCreateSema"},
{0xD6DA4BA1,&WrapV_CUIIU<sceKernelCreateSema>, "sceKernelCreateSema"},
{0x28b6489c,&WrapV_I<sceKernelDeleteSema>, "sceKernelDeleteSema"},
{0x58b1f937,&WrapI_II<sceKernelPollSema>, "sceKernelPollSema"},
{0xBC6FEBC5,&WrapI_IU<sceKernelReferSemaStatus>, "sceKernelReferSemaStatus"},
{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"},

View File

@ -112,7 +112,6 @@ void sceKernelCancelSema(SceUID id, int newCount, u32 numWaitThreadsPtr)
// We need to set the return value BEFORE rescheduling threads.
RETURN(0);
// Cancel appears to always reschedule.
__KernelClearSemaThreads(s, SCE_KERNEL_ERROR_WAIT_CANCEL);
__KernelReSchedule("semaphore cancelled");
}
@ -124,10 +123,14 @@ void sceKernelCancelSema(SceUID id, int newCount, u32 numWaitThreadsPtr)
}
//SceUID sceKernelCreateSema(const char *name, SceUInt attr, int initVal, int maxVal, SceKernelSemaOptParam *option);
SceUID sceKernelCreateSema(const char* name, u32 attr, int initVal, int maxVal, u32 optionPtr)
// void because it changes threads.
void sceKernelCreateSema(const char* name, u32 attr, int initVal, int maxVal, u32 optionPtr)
{
if (!name)
return SCE_KERNEL_ERROR_ERROR;
{
RETURN(SCE_KERNEL_ERROR_ERROR);
return;
}
Semaphore *s = new Semaphore;
SceUID id = kernelObjects.Create(s);
@ -143,7 +146,9 @@ SceUID sceKernelCreateSema(const char* name, u32 attr, int initVal, int maxVal,
DEBUG_LOG(HLE,"%i=sceKernelCreateSema(%s, %08x, %i, %i, %08x)", id, s->ns.name, s->ns.attr, s->ns.initCount, s->ns.maxCount, optionPtr);
return id;
RETURN(id);
__KernelReSchedule("semaphore created");
}
//int sceKernelDeleteSema(SceUID semaid);
@ -156,13 +161,9 @@ void sceKernelDeleteSema(SceUID id)
Semaphore *s = kernelObjects.Get<Semaphore>(id, error);
if (s)
{
if (__KernelClearSemaThreads(s, SCE_KERNEL_ERROR_WAIT_DELETE))
{
RETURN(kernelObjects.Destroy<Semaphore>(id));
__KernelReSchedule("semaphore deleted");
}
else
RETURN(kernelObjects.Destroy<Semaphore>(id));
__KernelClearSemaThreads(s, SCE_KERNEL_ERROR_WAIT_DELETE);
RETURN(kernelObjects.Destroy<Semaphore>(id));
__KernelReSchedule("semaphore deleted");
}
else
{
@ -171,7 +172,9 @@ void sceKernelDeleteSema(SceUID id)
}
}
int sceKernelReferSemaStatus(SceUID id, u32 infoPtr)
//int sceKernelDeleteSema(SceUID semaid, SceKernelSemaInfo *info);
// void because it changes threads.
void sceKernelReferSemaStatus(SceUID id, u32 infoPtr)
{
u32 error;
Semaphore *s = kernelObjects.Get<Semaphore>(id, error);
@ -179,12 +182,13 @@ int sceKernelReferSemaStatus(SceUID id, u32 infoPtr)
{
DEBUG_LOG(HLE,"sceKernelReferSemaStatus(%i, %08x)", id, infoPtr);
Memory::WriteStruct(infoPtr, &s->ns);
return 0;
RETURN(0);
__KernelReSchedule("semaphore refer status");
}
else
{
ERROR_LOG(HLE,"Error %08x", error);
return error;
RETURN(error);
}
}
@ -234,9 +238,7 @@ retry:
}
}
// I don't think we should reschedule here
//if (wokeThreads)
// __KernelReSchedule("semaphore signalled");
__KernelReSchedule("semaphore signalled");
}
else
{
@ -254,7 +256,7 @@ void __KernelWaitSema(SceUID id, int wantedCount, u32 timeoutPtr, const char *ba
// We need to set the return value BEFORE processing callbacks / etc.
RETURN(0);
if (s->ns.currentCount >= wantedCount) //TODO fix
if (s->ns.currentCount >= wantedCount)
s->ns.currentCount -= wantedCount;
else
{
@ -265,6 +267,8 @@ void __KernelWaitSema(SceUID id, int wantedCount, u32 timeoutPtr, const char *ba
if (processCallbacks)
__KernelCheckCallbacks();
}
__KernelReSchedule("semaphore waited");
}
else
{
@ -292,30 +296,34 @@ void sceKernelWaitSemaCB(SceUID id, int wantedCount, u32 timeoutPtr)
}
// Should be same as WaitSema but without the wait, instead returning SCE_KERNEL_ERROR_SEMA_ZERO
int sceKernelPollSema(SceUID id, int wantedCount)
void sceKernelPollSema(SceUID id, int wantedCount)
{
DEBUG_LOG(HLE,"sceKernelPollSema(%i, %i)", id, wantedCount);
if (wantedCount <= 0)
return SCE_KERNEL_ERROR_ILLEGAL_COUNT;
{
RETURN(SCE_KERNEL_ERROR_ILLEGAL_COUNT);
return;
}
u32 error;
Semaphore *s = kernelObjects.Get<Semaphore>(id, error);
if (s)
{
if (s->ns.currentCount >= wantedCount) //TODO fix
s->ns.currentCount -= wantedCount;
else
if (s->ns.currentCount >= wantedCount)
{
return SCE_KERNEL_ERROR_SEMA_ZERO;
s->ns.currentCount -= wantedCount;
RETURN(0);
}
else
RETURN(SCE_KERNEL_ERROR_SEMA_ZERO);
return 0;
__KernelReSchedule("semaphore polled");
}
else
{
ERROR_LOG(HLE, "sceKernelPollSema: Trying to poll invalid semaphore %i", id);
return error;
RETURN(error);
}
}

View File

@ -18,10 +18,10 @@
#pragma once
void sceKernelCancelSema(SceUID id, int newCount, u32 numWaitThreadsPtr);
SceUID sceKernelCreateSema(const char* name, u32 attr, int initVal, int maxVal, u32 optionPtr);
void sceKernelCreateSema(const char* name, u32 attr, int initVal, int maxVal, u32 optionPtr);
void sceKernelDeleteSema(SceUID id);
int sceKernelPollSema(SceUID id, int wantedCount);
int sceKernelReferSemaStatus(SceUID id, u32 infoPtr);
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);

@ -1 +1 @@
Subproject commit 871e721dece5acd3c631e0a30226b6482a00362d
Subproject commit 256bc8f62f1fad53f5d510d33033467b56f96a29

View File

@ -33,6 +33,12 @@ tests_good = [
"gpu/callbacks/ge_callbacks",
"threads/mbx/mbx",
"threads/semaphores/semaphores",
"threads/semaphores/cancel/cancel",
"threads/semaphores/create/create",
"threads/semaphores/delete/delete",
"threads/semaphores/poll/poll",
"threads/semaphores/refer/refer",
"threads/semaphores/signal/signal",
"power/power",
"rtc/rtc",
"umd/callbacks/umd",
@ -44,6 +50,8 @@ tests_next = [
"threads/msgpipe/msgpipe",
"threads/mutex/mutex",
"threads/scheduling/scheduling",
"threads/semaphores/priority/priority",
"threads/semaphores/wait/wait",
"threads/threads/threads",
"threads/vpl/vpl",
"threads/vtimers/vtimer",