Cleanup thread start and create logging.

Also report less cases.
This commit is contained in:
Unknown W. Brackets 2015-03-28 14:46:09 -07:00
parent fc3d6ff04a
commit 8d5f843bb8
3 changed files with 28 additions and 54 deletions

View file

@ -1814,7 +1814,7 @@ static void sceKernelStartModule(u32 moduleId, u32 argsize, u32 argAddr, u32 ret
}
SceUID threadID = __KernelCreateThread(module->nm.name, moduleId, entryAddr, priority, stacksize, attribute, 0);
sceKernelStartThread(threadID, argsize, argAddr);
__KernelStartThreadValidate(threadID, argsize, argAddr);
__KernelSetThreadRA(threadID, NID_MODULERETURN);
__KernelWaitCurThread(WAITTYPE_MODULE, moduleId, 1, 0, false, "started module");
@ -1896,7 +1896,7 @@ static u32 sceKernelStopModule(u32 moduleId, u32 argSize, u32 argAddr, u32 retur
if (Memory::IsValidAddress(stopFunc))
{
SceUID threadID = __KernelCreateThread(module->nm.name, moduleId, stopFunc, priority, stacksize, attr, 0);
sceKernelStartThread(threadID, argSize, argAddr);
__KernelStartThreadValidate(threadID, argSize, argAddr);
__KernelSetThreadRA(threadID, NID_MODULERETURN);
__KernelWaitCurThread(WAITTYPE_MODULE, moduleId, 1, 0, false, "stopped module");
@ -1979,7 +1979,7 @@ u32 hleKernelStopUnloadSelfModuleWithOrWithoutStatus(u32 exitCode, u32 argSize,
if (Memory::IsValidAddress(stopFunc)) {
SceUID threadID = __KernelCreateThread(module->nm.name, moduleID, stopFunc, priority, stacksize, attr, 0);
sceKernelStartThread(threadID, argSize, argp);
__KernelStartThreadValidate(threadID, argSize, argp);
__KernelSetThreadRA(threadID, NID_MODULERETURN);
__KernelWaitCurThread(WAITTYPE_MODULE, moduleID, 1, 0, false, "unloadstopped module");

View file

@ -2121,33 +2121,25 @@ SceUID __KernelCreateThreadInternal(const char *threadName, SceUID moduleID, u32
return id;
}
int __KernelCreateThread(const char *threadName, SceUID moduleID, u32 entry, u32 prio, int stacksize, u32 attr, u32 optionAddr)
{
int __KernelCreateThread(const char *threadName, SceUID moduleID, u32 entry, u32 prio, int stacksize, u32 attr, u32 optionAddr) {
if (threadName == nullptr)
return hleReportError(SCEKERNEL, SCE_KERNEL_ERROR_ERROR, "NULL name");
return hleReportError(SCEKERNEL, SCE_KERNEL_ERROR_ERROR, "NULL thread name");
if ((u32)stacksize < 0x200)
return hleReportWarning(SCEKERNEL, SCE_KERNEL_ERROR_ILLEGAL_STACK_SIZE, "bogus stack size %08x", stacksize);
if (prio < 0x08 || prio > 0x77)
{
return hleReportWarning(SCEKERNEL, SCE_KERNEL_ERROR_ILLEGAL_STACK_SIZE, "bogus thread stack size %08x", stacksize);
if (prio < 0x08 || prio > 0x77) {
WARN_LOG_REPORT(SCEKERNEL, "sceKernelCreateThread(name=%s): bogus priority %08x", threadName, prio);
// TODO: Should return this error.
// return SCE_KERNEL_ERROR_ILLEGAL_PRIORITY;
prio = prio < 0x08 ? 0x08 : 0x77;
}
if (!Memory::IsValidAddress(entry))
{
ERROR_LOG_REPORT(SCEKERNEL, "sceKernelCreateThread(name=%s): invalid entry %08x", threadName, entry);
if (!Memory::IsValidAddress(entry)) {
// The PSP firmware seems to allow NULL...?
if (entry != 0)
return SCE_KERNEL_ERROR_ILLEGAL_ADDR;
return hleReportError(SCEKERNEL, SCE_KERNEL_ERROR_ILLEGAL_ADDR, "invalid thread entry %08x", entry);
}
if ((attr & ~PSP_THREAD_ATTR_USER_MASK) != 0)
{
WARN_LOG_REPORT(SCEKERNEL, "sceKernelCreateThread(name=%s): illegal attributes %08x", threadName, attr);
// TODO: Should return this error.
// return SCE_KERNEL_ERROR_ILLEGAL_ATTR;
}
return hleReportWarning(SCEKERNEL, SCE_KERNEL_ERROR_ILLEGAL_ATTR, "illegal thread attributes %08x", attr);
if ((attr & ~PSP_THREAD_ATTR_SUPPORTED) != 0)
WARN_LOG_REPORT(SCEKERNEL, "sceKernelCreateThread(name=%s): unsupported attributes %08x", threadName, attr);
@ -2177,13 +2169,11 @@ int __KernelCreateThread(const char *threadName, SceUID moduleID, u32 entry, u32
return hleLogSuccessInfoI(SCEKERNEL, id);
}
int sceKernelCreateThread(const char *threadName, u32 entry, u32 prio, int stacksize, u32 attr, u32 optionAddr)
{
int sceKernelCreateThread(const char *threadName, u32 entry, u32 prio, int stacksize, u32 attr, u32 optionAddr) {
return __KernelCreateThread(threadName, __KernelGetCurThreadModuleId(), entry, prio, stacksize, attr, optionAddr);
}
int __KernelStartThread(SceUID threadToStartID, int argSize, u32 argBlockPtr, bool forceArgs)
{
int __KernelStartThread(SceUID threadToStartID, int argSize, u32 argBlockPtr, bool forceArgs) {
u32 error;
Thread *startThread = kernelObjects.Get<Thread>(threadToStartID, error);
if (startThread == 0)
@ -2195,16 +2185,13 @@ int __KernelStartThread(SceUID threadToStartID, int argSize, u32 argBlockPtr, bo
u32 &sp = startThread->context.r[MIPS_REG_SP];
// Force args means just use those as a0/a1 without any special treatment.
// This is a hack to avoid allocating memory for helper threads which take args.
if ((argBlockPtr && argSize > 0) || forceArgs)
{
if ((argBlockPtr && argSize > 0) || forceArgs) {
// Make room for the arguments, always 0x10 aligned.
if (!forceArgs)
sp -= (argSize + 0xf) & ~0xf;
startThread->context.r[MIPS_REG_A0] = argSize;
startThread->context.r[MIPS_REG_A1] = sp;
}
else
{
} else {
startThread->context.r[MIPS_REG_A0] = 0;
startThread->context.r[MIPS_REG_A1] = 0;
}
@ -2218,8 +2205,7 @@ int __KernelStartThread(SceUID threadToStartID, int argSize, u32 argBlockPtr, bo
sp -= 64;
// Smaller is better for priority. Only switch if the new thread is better.
if (cur && cur->nt.currentPriority > startThread->nt.currentPriority)
{
if (cur && cur->nt.currentPriority > startThread->nt.currentPriority) {
__KernelChangeReadyState(cur, currentThread, true);
hleReSchedule("thread started");
}
@ -2231,40 +2217,27 @@ int __KernelStartThread(SceUID threadToStartID, int argSize, u32 argBlockPtr, bo
return 0;
}
// int sceKernelStartThread(SceUID threadToStartID, SceSize argSize, void *argBlock)
int sceKernelStartThread(SceUID threadToStartID, int argSize, u32 argBlockPtr)
{
u32 error = 0;
int __KernelStartThreadValidate(SceUID threadToStartID, int argSize, u32 argBlockPtr, bool forceArgs) {
if (threadToStartID == 0)
{
error = SCE_KERNEL_ERROR_ILLEGAL_THID;
ERROR_LOG_REPORT(SCEKERNEL, "%08x=sceKernelStartThread(thread=%i, argSize=%i, argPtr=%08x): NULL thread", error, threadToStartID, argSize, argBlockPtr);
return error;
}
return hleLogError(SCEKERNEL, SCE_KERNEL_ERROR_ILLEGAL_THID, "thread id is 0");
if (argSize < 0 || argBlockPtr & 0x80000000)
{
error = SCE_KERNEL_ERROR_ILLEGAL_ADDR;
ERROR_LOG_REPORT(SCEKERNEL, "%08x=sceKernelStartThread(thread=%i, argSize=%i, argPtr=%08x): bad argument pointer/length", error, threadToStartID, argSize, argBlockPtr);
return error;
}
return hleReportError(SCEKERNEL, SCE_KERNEL_ERROR_ILLEGAL_ADDR, "bad thread argument pointer/length %08x / %08x", argSize, argBlockPtr);
u32 error = 0;
Thread *startThread = kernelObjects.Get<Thread>(threadToStartID, error);
if (startThread == 0)
{
ERROR_LOG_REPORT(SCEKERNEL, "%08x=sceKernelStartThread(thread=%i, argSize=%i, argPtr=%08x): thread does not exist!", error, threadToStartID, argSize, argBlockPtr);
return error;
}
return hleLogError(SCEKERNEL, error, "thread does not exist");
if (startThread->nt.status != THREADSTATUS_DORMANT)
{
error = SCE_KERNEL_ERROR_NOT_DORMANT;
WARN_LOG_REPORT(SCEKERNEL, "%08x=sceKernelStartThread(thread=%i, argSize=%i, argPtr=%08x): thread already running", error, threadToStartID, argSize, argBlockPtr);
return error;
}
return hleLogWarning(SCEKERNEL, SCE_KERNEL_ERROR_NOT_DORMANT, "thread already running");
INFO_LOG(SCEKERNEL, "sceKernelStartThread(thread=%i, argSize=%i, argPtr=%08x)", threadToStartID, argSize, argBlockPtr);
hleEatCycles(3400);
return __KernelStartThread(threadToStartID, argSize, argBlockPtr);
return __KernelStartThread(threadToStartID, argSize, argBlockPtr, forceArgs);
}
// int sceKernelStartThread(SceUID threadToStartID, SceSize argSize, void *argBlock)
int sceKernelStartThread(SceUID threadToStartID, int argSize, u32 argBlockPtr) {
return hleLogSuccessInfoI(SCEKERNEL, __KernelStartThreadValidate(threadToStartID, argSize, argBlockPtr));
}
int sceKernelGetThreadStackFreeSize(SceUID threadID)

View file

@ -45,6 +45,7 @@ void _sceKernelExitThread(int exitStatus);
SceUID sceKernelGetThreadId();
int sceKernelGetThreadCurrentPriority();
int __KernelStartThread(SceUID threadToStartID, int argSize, u32 argBlockPtr, bool forceArgs = false);
int __KernelStartThreadValidate(SceUID threadToStartID, int argSize, u32 argBlockPtr, bool forceArgs = false);
int sceKernelStartThread(SceUID threadToStartID, int argSize, u32 argBlockPtr);
u32 sceKernelSuspendDispatchThread();
u32 sceKernelResumeDispatchThread(u32 suspended);