mirror of
https://github.com/libretro/ppsspp.git
synced 2024-11-30 20:01:00 +00:00
Fix sceKernelCreateMutex() to match tests.
Still have an issue where reusing threads doesn't work.
This commit is contained in:
parent
a539580195
commit
4bfa24eca8
@ -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));
|
||||
}
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user