Fix sceKernelCreateMutex() to match tests.

Still have an issue where reusing threads doesn't work.
This commit is contained in:
Unknown W. Brackets 2012-11-17 19:34:39 -08:00
parent a539580195
commit 4bfa24eca8
4 changed files with 40 additions and 18 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, u32)> void WrapI_CUIU() {
int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3));
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, u32)> void WrapV_CUIU() {
func(Memory::GetCharPointer(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));
}

View File

@ -343,7 +343,7 @@ const HLEFunction ThreadManForUser[] =
{0xB011B11F,&WrapV_IIU<sceKernelLockMutex>,"sceKernelLockMutex"},
{0x5bf4dd27,&WrapV_IIU<sceKernelLockMutexCB>,"sceKernelLockMutexCB"},
{0x6b30100f,&WrapV_II<sceKernelUnlockMutex>,"sceKernelUnlockMutex"},
{0xb7d098c6,&WrapI_CUIU<sceKernelCreateMutex>,"sceKernelCreateMutex"},
{0xb7d098c6,&WrapV_CUIU<sceKernelCreateMutex>,"sceKernelCreateMutex"},
{0x0DDCD2C9, 0, "sceKernelTryLockMutex"},
// NOTE: LockLwMutex and UnlockLwMutex are in Kernel_Library, see sceKernelInterrupt.cpp.

View File

@ -47,7 +47,7 @@ struct Mutex : public KernelObject
{
const char *GetName() {return nm.name;}
const char *GetTypeName() {return "Mutex";}
static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_SEMID; } // Not sure?
static u32 GetMissingErrorCode() { return PSP_MUTEX_ERROR_NO_SUCH_MUTEX; } // Not sure?
int GetIDType() const { return SCE_KERNEL_TMID_Mutex; }
NativeMutex nm;
std::vector<SceUID> waitingThreads;
@ -63,21 +63,37 @@ struct LWMutex : public KernelObject
std::vector<SceUID> waitingThreads;
};
SceUID sceKernelCreateMutex(const char *name, u32 attr, int initialCount, u32 optionsPtr)
void sceKernelCreateMutex(const char *name, u32 attr, int initialCount, u32 optionsPtr)
{
u32 error = 0;
if (!error && !name)
error = SCE_KERNEL_ERROR_ERROR;
if (!error && initialCount < 0)
error = SCE_KERNEL_ERROR_ILLEGAL_COUNT;
if (!error && (attr & PSP_MUTEX_ATTR_ALLOW_RECURSIVE) == 0 && initialCount > 1)
error = SCE_KERNEL_ERROR_ILLEGAL_COUNT;
if (error)
{
RETURN(error);
return;
}
DEBUG_LOG(HLE,"sceKernelCreateMutex(%s, %08x, %d, %08x)", name, attr, initialCount, optionsPtr);
Mutex *mutex = new Mutex();
SceUID id = kernelObjects.Create(mutex);
mutex->nm.size = sizeof(mutex);
strncpy(mutex->nm.name, name, 31);
mutex->nm.name[31] = 0;
mutex->nm.attr = attr;
mutex->nm.lockLevel = initialCount;
// TODO: Does initial_count > 0 mean lock automatically by the current thread? Would make sense.
mutex->nm.lockThread = -1;
mutex->nm.lockThread = __KernelGetCurThread();
strncpy(mutex->nm.name, name, 32);
return id;
RETURN(id);
__KernelReSchedule("mutex created");
}
void sceKernelDeleteMutex(SceUID id)
@ -87,13 +103,21 @@ void sceKernelDeleteMutex(SceUID id)
Mutex *mutex = kernelObjects.Get<Mutex>(id, error);
if (mutex)
{
RETURN(0);
std::vector<SceUID>::iterator iter, end;
for (iter = mutex->waitingThreads.begin(), end = mutex->waitingThreads.end(); iter != end; ++iter)
{
SceUID threadID = *iter;
kernelObjects.Destroy<Mutex>(id);
// TODO: Almost certainly need to reschedule (sometimes?)
// TODO: Set returnValue?
__KernelResumeThreadFromWait(threadID);
}
mutex->waitingThreads.empty();
RETURN(kernelObjects.Destroy<Mutex>(id));
__KernelReSchedule("mutex deleted");
}
else
RETURN(PSP_MUTEX_ERROR_NO_SUCH_MUTEX);
RETURN(error);
}
// int sceKernelLockMutex(SceUID id, int count, int *timeout)

View File

@ -17,8 +17,7 @@
#pragma once
// TODO
SceUID sceKernelCreateMutex(const char *name, u32 attr, int initialCount, u32 optionsPtr);
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);