From 1cb7a8813783e017c5ab6fe7764d64209e625720 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 26 Jan 2013 10:44:04 -0800 Subject: [PATCH 1/4] Don't use a dynamic string for wait debugging. Happens in release, and shows up on the profiler. Not huge, but should save ~0.5% of cpu time. --- Core/HLE/__sceAudio.cpp | 2 +- Core/HLE/sceCtrl.cpp | 4 ++-- Core/HLE/sceDisplay.cpp | 12 ++++++------ Core/HLE/sceKernelEventFlag.cpp | 4 ++-- Core/HLE/sceKernelMbx.cpp | 4 ++-- Core/HLE/sceKernelMemory.cpp | 4 ++-- Core/HLE/sceKernelMsgPipe.cpp | 8 ++++---- Core/HLE/sceKernelMutex.cpp | 8 ++++---- Core/HLE/sceKernelSemaphore.cpp | 2 +- Core/HLE/sceKernelThread.cpp | 22 +++++++++++----------- Core/HLE/sceKernelThread.h | 2 +- Core/HLE/sceUmd.cpp | 6 +++--- 12 files changed, 39 insertions(+), 39 deletions(-) diff --git a/Core/HLE/__sceAudio.cpp b/Core/HLE/__sceAudio.cpp index c59567077f..402c0ddd34 100644 --- a/Core/HLE/__sceAudio.cpp +++ b/Core/HLE/__sceAudio.cpp @@ -116,7 +116,7 @@ u32 __AudioEnqueue(AudioChannel &chan, int chanNum, bool blocking) if (blocking) { chan.waitingThread = __KernelGetCurThread(); // WARNING: This changes currentThread so must grab waitingThread before (line above). - __KernelWaitCurThread(WAITTYPE_AUDIOCHANNEL, (SceUID)chanNum, 0, 0, false); + __KernelWaitCurThread(WAITTYPE_AUDIOCHANNEL, (SceUID)chanNum, 0, 0, false, "blocking audio waited"); // Fall through to the sample queueing, don't want to lose the samples even though // we're getting full. } diff --git a/Core/HLE/sceCtrl.cpp b/Core/HLE/sceCtrl.cpp index 145f22d1a5..4f3987cd65 100644 --- a/Core/HLE/sceCtrl.cpp +++ b/Core/HLE/sceCtrl.cpp @@ -408,7 +408,7 @@ void sceCtrlReadBufferPositive(u32 ctrlDataPtr, u32 nBufs) else { waitingThreads.push_back(__KernelGetCurThread()); - __KernelWaitCurThread(WAITTYPE_CTRL, CTRL_WAIT_POSITIVE, ctrlDataPtr, 0, false); + __KernelWaitCurThread(WAITTYPE_CTRL, CTRL_WAIT_POSITIVE, ctrlDataPtr, 0, false, "ctrl buffer waited"); DEBUG_LOG(HLE, "sceCtrlReadBufferPositive(%08x, %i) - waiting", ctrlDataPtr, nBufs); } } @@ -424,7 +424,7 @@ void sceCtrlReadBufferNegative(u32 ctrlDataPtr, u32 nBufs) else { waitingThreads.push_back(__KernelGetCurThread()); - __KernelWaitCurThread(WAITTYPE_CTRL, CTRL_WAIT_NEGATIVE, ctrlDataPtr, 0, false); + __KernelWaitCurThread(WAITTYPE_CTRL, CTRL_WAIT_NEGATIVE, ctrlDataPtr, 0, false, "ctrl buffer waited"); DEBUG_LOG(HLE, "sceCtrlReadBufferNegative(%08x, %i) - waiting", ctrlDataPtr, nBufs); } } diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index 023254403e..74956292a5 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -369,7 +369,7 @@ u32 sceDisplayGetFramebuf(u32 topaddrPtr, u32 linesizePtr, u32 pixelFormatPtr, i u32 sceDisplayWaitVblankStart() { DEBUG_LOG(HLE,"sceDisplayWaitVblankStart()"); vblankWaitingThreads.push_back(WaitVBlankInfo(__KernelGetCurThread())); - __KernelWaitCurThread(WAITTYPE_VBLANK, 0, 0, 0, false); + __KernelWaitCurThread(WAITTYPE_VBLANK, 0, 0, 0, false, "vblank start waited"); return 0; } @@ -377,7 +377,7 @@ u32 sceDisplayWaitVblank() { if (!isVblank) { DEBUG_LOG(HLE,"sceDisplayWaitVblank()"); vblankWaitingThreads.push_back(WaitVBlankInfo(__KernelGetCurThread())); - __KernelWaitCurThread(WAITTYPE_VBLANK, 0, 0, 0, false); + __KernelWaitCurThread(WAITTYPE_VBLANK, 0, 0, 0, false, "vblank waited"); return 0; } else { DEBUG_LOG(HLE,"sceDisplayWaitVblank() - not waiting since in vBlank"); @@ -388,7 +388,7 @@ u32 sceDisplayWaitVblank() { u32 sceDisplayWaitVblankStartMulti() { DEBUG_LOG(HLE,"sceDisplayWaitVblankStartMulti()"); vblankWaitingThreads.push_back(WaitVBlankInfo(__KernelGetCurThread())); - __KernelWaitCurThread(WAITTYPE_VBLANK, 0, 0, 0, false); + __KernelWaitCurThread(WAITTYPE_VBLANK, 0, 0, 0, false, "vblank start multi waited"); return 0; } @@ -396,7 +396,7 @@ u32 sceDisplayWaitVblankCB() { if (!isVblank) { DEBUG_LOG(HLE,"sceDisplayWaitVblankCB()"); vblankWaitingThreads.push_back(WaitVBlankInfo(__KernelGetCurThread())); - __KernelWaitCurThread(WAITTYPE_VBLANK, 0, 0, 0, true); + __KernelWaitCurThread(WAITTYPE_VBLANK, 0, 0, 0, true, "vblank waited"); return 0; } else { DEBUG_LOG(HLE,"sceDisplayWaitVblank() - not waiting since in vBlank"); @@ -407,14 +407,14 @@ u32 sceDisplayWaitVblankCB() { u32 sceDisplayWaitVblankStartCB() { DEBUG_LOG(HLE,"sceDisplayWaitVblankStartCB()"); vblankWaitingThreads.push_back(WaitVBlankInfo(__KernelGetCurThread())); - __KernelWaitCurThread(WAITTYPE_VBLANK, 0, 0, 0, true); + __KernelWaitCurThread(WAITTYPE_VBLANK, 0, 0, 0, true, "vblank start waited"); return 0; } u32 sceDisplayWaitVblankStartMultiCB() { DEBUG_LOG(HLE,"sceDisplayWaitVblankStartMultiCB()"); vblankWaitingThreads.push_back(WaitVBlankInfo(__KernelGetCurThread())); - __KernelWaitCurThread(WAITTYPE_VBLANK, 0, 0, 0, true); + __KernelWaitCurThread(WAITTYPE_VBLANK, 0, 0, 0, true, "vblank start multi waited"); return 0; } diff --git a/Core/HLE/sceKernelEventFlag.cpp b/Core/HLE/sceKernelEventFlag.cpp index 68e182ac2d..0acf655dd5 100644 --- a/Core/HLE/sceKernelEventFlag.cpp +++ b/Core/HLE/sceKernelEventFlag.cpp @@ -417,7 +417,7 @@ int sceKernelWaitEventFlag(SceUID id, u32 bits, u32 wait, u32 outBitsPtr, u32 ti e->waitingThreads.push_back(th); __KernelSetEventFlagTimeout(e, timeoutPtr); - __KernelWaitCurThread(WAITTYPE_EVENTFLAG, id, 0, timeoutPtr, false); + __KernelWaitCurThread(WAITTYPE_EVENTFLAG, id, 0, timeoutPtr, false, "event flag waited"); } return 0; @@ -470,7 +470,7 @@ int sceKernelWaitEventFlagCB(SceUID id, u32 bits, u32 wait, u32 outBitsPtr, u32 e->waitingThreads.push_back(th); __KernelSetEventFlagTimeout(e, timeoutPtr); - __KernelWaitCurThread(WAITTYPE_EVENTFLAG, id, 0, timeoutPtr, true); + __KernelWaitCurThread(WAITTYPE_EVENTFLAG, id, 0, timeoutPtr, true, "event flag waited"); } else hleCheckCurrentCallbacks(); diff --git a/Core/HLE/sceKernelMbx.cpp b/Core/HLE/sceKernelMbx.cpp index a720c710dd..29756f1829 100644 --- a/Core/HLE/sceKernelMbx.cpp +++ b/Core/HLE/sceKernelMbx.cpp @@ -450,7 +450,7 @@ int sceKernelReceiveMbx(SceUID id, u32 packetAddrPtr, u32 timeoutPtr) __KernelMbxRemoveThread(m, __KernelGetCurThread()); m->AddWaitingThread(__KernelGetCurThread(), packetAddrPtr); __KernelWaitMbx(m, timeoutPtr); - __KernelWaitCurThread(WAITTYPE_MBX, id, 0, timeoutPtr, false); + __KernelWaitCurThread(WAITTYPE_MBX, id, 0, timeoutPtr, false, "mbx waited"); return 0; } } @@ -478,7 +478,7 @@ int sceKernelReceiveMbxCB(SceUID id, u32 packetAddrPtr, u32 timeoutPtr) __KernelMbxRemoveThread(m, __KernelGetCurThread()); m->AddWaitingThread(__KernelGetCurThread(), packetAddrPtr); __KernelWaitMbx(m, timeoutPtr); - __KernelWaitCurThread(WAITTYPE_MBX, id, 0, timeoutPtr, true); + __KernelWaitCurThread(WAITTYPE_MBX, id, 0, timeoutPtr, true, "mbx waited"); return 0; } } diff --git a/Core/HLE/sceKernelMemory.cpp b/Core/HLE/sceKernelMemory.cpp index 58f7c7c8a2..b94b27cddf 100644 --- a/Core/HLE/sceKernelMemory.cpp +++ b/Core/HLE/sceKernelMemory.cpp @@ -976,7 +976,7 @@ int sceKernelAllocateVpl(SceUID uid, u32 size, u32 addrPtr, u32 timeoutPtr) } __KernelSetVplTimeout(timeoutPtr); - __KernelWaitCurThread(WAITTYPE_VPL, uid, size, timeoutPtr, false); + __KernelWaitCurThread(WAITTYPE_VPL, uid, size, timeoutPtr, false, "vpl waited"); } } return error; @@ -1002,7 +1002,7 @@ int sceKernelAllocateVplCB(SceUID uid, u32 size, u32 addrPtr, u32 timeoutPtr) } __KernelSetVplTimeout(timeoutPtr); - __KernelWaitCurThread(WAITTYPE_VPL, uid, size, timeoutPtr, true); + __KernelWaitCurThread(WAITTYPE_VPL, uid, size, timeoutPtr, true, "vpl waited"); } } return error; diff --git a/Core/HLE/sceKernelMsgPipe.cpp b/Core/HLE/sceKernelMsgPipe.cpp index 68ef9d6cad..bef7980ef8 100644 --- a/Core/HLE/sceKernelMsgPipe.cpp +++ b/Core/HLE/sceKernelMsgPipe.cpp @@ -289,7 +289,7 @@ void __KernelSendMsgPipe(MsgPipe *m, u32 sendBufAddr, u32 sendSize, int waitMode { m->AddSendWaitingThread(__KernelGetCurThread(), curSendAddr, sendSize, waitMode, resultAddr); RETURN(0); - __KernelWaitCurThread(WAITTYPE_MSGPIPE, 0, 0, 0, cbEnabled); + __KernelWaitCurThread(WAITTYPE_MSGPIPE, 0, 0, 0, cbEnabled, "msgpipe waited"); return; } } @@ -321,7 +321,7 @@ void __KernelSendMsgPipe(MsgPipe *m, u32 sendBufAddr, u32 sendSize, int waitMode { m->AddSendWaitingThread(__KernelGetCurThread(), curSendAddr, sendSize, waitMode, resultAddr); RETURN(0); - __KernelWaitCurThread(WAITTYPE_MSGPIPE, 0, 0, 0, cbEnabled); + __KernelWaitCurThread(WAITTYPE_MSGPIPE, 0, 0, 0, cbEnabled, "msgpipe waited"); return; } } @@ -461,7 +461,7 @@ void __KernelReceiveMsgPipe(MsgPipe *m, u32 receiveBufAddr, u32 receiveSize, int { m->AddReceiveWaitingThread(__KernelGetCurThread(), curReceiveAddr, receiveSize, waitMode, resultAddr); RETURN(0); - __KernelWaitCurThread(WAITTYPE_MSGPIPE, 0, 0, 0, cbEnabled); + __KernelWaitCurThread(WAITTYPE_MSGPIPE, 0, 0, 0, cbEnabled, "msgpipe waited"); return; } } @@ -497,7 +497,7 @@ void __KernelReceiveMsgPipe(MsgPipe *m, u32 receiveBufAddr, u32 receiveSize, int { m->AddReceiveWaitingThread(__KernelGetCurThread(), curReceiveAddr, receiveSize, waitMode, resultAddr); RETURN(0); - __KernelWaitCurThread(WAITTYPE_MSGPIPE, 0, 0, 0, cbEnabled); + __KernelWaitCurThread(WAITTYPE_MSGPIPE, 0, 0, 0, cbEnabled, "msgpipe waited"); return; } } diff --git a/Core/HLE/sceKernelMutex.cpp b/Core/HLE/sceKernelMutex.cpp index 9042fcb58b..b6c18b2f4b 100644 --- a/Core/HLE/sceKernelMutex.cpp +++ b/Core/HLE/sceKernelMutex.cpp @@ -464,7 +464,7 @@ int sceKernelLockMutex(SceUID id, int count, u32 timeoutPtr) if (std::find(mutex->waitingThreads.begin(), mutex->waitingThreads.end(), threadID) == mutex->waitingThreads.end()) mutex->waitingThreads.push_back(threadID); __KernelWaitMutex(mutex, timeoutPtr); - __KernelWaitCurThread(WAITTYPE_MUTEX, id, count, timeoutPtr, false); + __KernelWaitCurThread(WAITTYPE_MUTEX, id, count, timeoutPtr, false, "mutex waited"); // Return value will be overwritten by wait. return 0; @@ -492,7 +492,7 @@ int sceKernelLockMutexCB(SceUID id, int count, u32 timeoutPtr) if (std::find(mutex->waitingThreads.begin(), mutex->waitingThreads.end(), threadID) == mutex->waitingThreads.end()) mutex->waitingThreads.push_back(threadID); __KernelWaitMutex(mutex, timeoutPtr); - __KernelWaitCurThread(WAITTYPE_MUTEX, id, count, timeoutPtr, true); + __KernelWaitCurThread(WAITTYPE_MUTEX, id, count, timeoutPtr, true, "mutex waited"); // Return value will be overwritten by wait. return 0; @@ -846,7 +846,7 @@ int sceKernelLockLwMutex(u32 workareaPtr, int count, u32 timeoutPtr) if (std::find(mutex->waitingThreads.begin(), mutex->waitingThreads.end(), threadID) == mutex->waitingThreads.end()) mutex->waitingThreads.push_back(threadID); __KernelWaitLwMutex(mutex, timeoutPtr); - __KernelWaitCurThread(WAITTYPE_LWMUTEX, workarea.uid, count, timeoutPtr, false); + __KernelWaitCurThread(WAITTYPE_LWMUTEX, workarea.uid, count, timeoutPtr, false, "lwmutex waited"); // Return value will be overwritten by wait. return 0; @@ -882,7 +882,7 @@ int sceKernelLockLwMutexCB(u32 workareaPtr, int count, u32 timeoutPtr) if (std::find(mutex->waitingThreads.begin(), mutex->waitingThreads.end(), threadID) == mutex->waitingThreads.end()) mutex->waitingThreads.push_back(threadID); __KernelWaitLwMutex(mutex, timeoutPtr); - __KernelWaitCurThread(WAITTYPE_LWMUTEX, workarea.uid, count, timeoutPtr, true); + __KernelWaitCurThread(WAITTYPE_LWMUTEX, workarea.uid, count, timeoutPtr, true, "lwmutex waited"); // Return value will be overwritten by wait. return 0; diff --git a/Core/HLE/sceKernelSemaphore.cpp b/Core/HLE/sceKernelSemaphore.cpp index 6c1c8cd1bc..0e11397461 100644 --- a/Core/HLE/sceKernelSemaphore.cpp +++ b/Core/HLE/sceKernelSemaphore.cpp @@ -343,7 +343,7 @@ int __KernelWaitSema(SceUID id, int wantedCount, u32 timeoutPtr, const char *bad if (std::find(s->waitingThreads.begin(), s->waitingThreads.end(), threadID) == s->waitingThreads.end()) s->waitingThreads.push_back(threadID); __KernelSetSemaTimeout(s, timeoutPtr); - __KernelWaitCurThread(WAITTYPE_SEMA, id, wantedCount, timeoutPtr, processCallbacks); + __KernelWaitCurThread(WAITTYPE_SEMA, id, wantedCount, timeoutPtr, processCallbacks, "sema waited"); } return 0; diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index baaefef392..cc38af96d3 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -1031,7 +1031,7 @@ bool __KernelTriggerWait(WaitType type, int id, int retVal, bool dontSwitch) } // makes the current thread wait for an event -void __KernelWaitCurThread(WaitType type, SceUID waitID, u32 waitValue, u32 timeoutPtr, bool processCallbacks) +void __KernelWaitCurThread(WaitType type, SceUID waitID, u32 waitValue, u32 timeoutPtr, bool processCallbacks, const char *reason) { // TODO: Need to defer if in callback? if (g_inCbCount > 0) @@ -1049,10 +1049,10 @@ void __KernelWaitCurThread(WaitType type, SceUID waitID, u32 waitValue, u32 time RETURN(0); //pretend all went OK // TODO: time waster - char temp[256]; - sprintf(temp, "started wait %s", waitTypeStrings[(int)type]); + if (!reason) + reason = "started wait"; - hleReSchedule(processCallbacks, temp); + hleReSchedule(processCallbacks, reason); // TODO: Remove thread from Ready queue? } @@ -1728,7 +1728,7 @@ void sceKernelDelayThreadCB() SceUID curThread = __KernelGetCurThread(); __KernelScheduleWakeup(curThread, usec); - __KernelWaitCurThread(WAITTYPE_DELAY, curThread, 0, 0, true); + __KernelWaitCurThread(WAITTYPE_DELAY, curThread, 0, 0, true, "thread delayed"); } void sceKernelDelayThread() @@ -1739,7 +1739,7 @@ void sceKernelDelayThread() SceUID curThread = __KernelGetCurThread(); __KernelScheduleWakeup(curThread, usec); - __KernelWaitCurThread(WAITTYPE_DELAY, curThread, 0, 0, false); + __KernelWaitCurThread(WAITTYPE_DELAY, curThread, 0, 0, false, "thread delayed"); } void sceKernelDelaySysClockThreadCB() @@ -1760,7 +1760,7 @@ void sceKernelDelaySysClockThreadCB() SceUID curThread = __KernelGetCurThread(); __KernelScheduleWakeup(curThread, usec); - __KernelWaitCurThread(WAITTYPE_DELAY, curThread, 0, 0, true); + __KernelWaitCurThread(WAITTYPE_DELAY, curThread, 0, 0, true, "thread delayed"); } void sceKernelDelaySysClockThread() @@ -1781,7 +1781,7 @@ void sceKernelDelaySysClockThread() SceUID curThread = __KernelGetCurThread(); __KernelScheduleWakeup(curThread, usec); - __KernelWaitCurThread(WAITTYPE_DELAY, curThread, 0, 0, false); + __KernelWaitCurThread(WAITTYPE_DELAY, curThread, 0, 0, false, "thread delayed"); } u32 __KernelGetThreadPrio(SceUID id) @@ -1855,7 +1855,7 @@ static void __KernelSleepThread(bool doCallbacks) { RETURN(0); } else { RETURN(0); - __KernelWaitCurThread(WAITTYPE_SLEEP, 0, 0, 0, doCallbacks); + __KernelWaitCurThread(WAITTYPE_SLEEP, 0, 0, 0, doCallbacks, "thread slept"); } } @@ -1886,7 +1886,7 @@ int sceKernelWaitThreadEnd(SceUID threadID, u32 timeoutPtr) { if (Memory::IsValidAddress(timeoutPtr)) __KernelScheduleThreadEndTimeout(currentThread, threadID, Memory::Read_U32(timeoutPtr)); - __KernelWaitCurThread(WAITTYPE_THREADEND, threadID, 0, timeoutPtr, false); + __KernelWaitCurThread(WAITTYPE_THREADEND, threadID, 0, timeoutPtr, false, "thread wait end"); } return t->nt.exitStatus; @@ -1913,7 +1913,7 @@ int sceKernelWaitThreadEndCB(SceUID threadID, u32 timeoutPtr) { if (Memory::IsValidAddress(timeoutPtr)) __KernelScheduleThreadEndTimeout(currentThread, threadID, Memory::Read_U32(timeoutPtr)); - __KernelWaitCurThread(WAITTYPE_THREADEND, threadID, 0, timeoutPtr, true); + __KernelWaitCurThread(WAITTYPE_THREADEND, threadID, 0, timeoutPtr, true, "thread wait end"); } return t->nt.exitStatus; diff --git a/Core/HLE/sceKernelThread.h b/Core/HLE/sceKernelThread.h index 4d1aca0fa6..12117df1a1 100644 --- a/Core/HLE/sceKernelThread.h +++ b/Core/HLE/sceKernelThread.h @@ -129,7 +129,7 @@ u32 __KernelResumeThreadFromWait(SceUID threadID, int retval); u32 __KernelGetWaitValue(SceUID threadID, u32 &error); u32 __KernelGetWaitTimeoutPtr(SceUID threadID, u32 &error); SceUID __KernelGetWaitID(SceUID threadID, WaitType type, u32 &error); -void __KernelWaitCurThread(WaitType type, SceUID waitId, u32 waitValue, u32 timeoutPtr, bool processCallbacks); +void __KernelWaitCurThread(WaitType type, SceUID waitId, u32 waitValue, u32 timeoutPtr, bool processCallbacks, const char *reason); void __KernelReSchedule(const char *reason = "no reason"); void __KernelReSchedule(bool doCallbacks, const char *reason); diff --git a/Core/HLE/sceUmd.cpp b/Core/HLE/sceUmd.cpp index bbe49ed8ad..1f2f2a072a 100644 --- a/Core/HLE/sceUmd.cpp +++ b/Core/HLE/sceUmd.cpp @@ -249,7 +249,7 @@ int sceUmdWaitDriveStat(u32 stat) DEBUG_LOG(HLE,"0=sceUmdWaitDriveStat(stat = %08x)", stat); if ((stat & __KernelUmdGetState()) == 0) - __KernelWaitCurThread(WAITTYPE_UMD, 1, stat, 0, 0); + __KernelWaitCurThread(WAITTYPE_UMD, 1, stat, 0, 0, "umd stat waited"); return 0; } @@ -261,7 +261,7 @@ int sceUmdWaitDriveStatWithTimer(u32 stat, u32 timeout) if ((stat & __KernelUmdGetState()) == 0) { __UmdWaitStat(timeout); - __KernelWaitCurThread(WAITTYPE_UMD, 1, stat, 0, 0); + __KernelWaitCurThread(WAITTYPE_UMD, 1, stat, 0, 0, "umd stat waited"); } else hleReSchedule("umd stat waited with timer"); @@ -287,7 +287,7 @@ int sceUmdWaitDriveStatCB(u32 stat, u32 timeout) timeout = 8000; __UmdWaitStat(timeout); - __KernelWaitCurThread(WAITTYPE_UMD, 1, stat, 0, true); + __KernelWaitCurThread(WAITTYPE_UMD, 1, stat, 0, true, "umd stat waited"); } else hleReSchedule("umd stat waited"); From a6094e25ff371404f949cdbe08f48193baad060f Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 26 Jan 2013 10:59:17 -0800 Subject: [PATCH 2/4] Get rid of waitTypeStrings and resched reason copy. --- Core/HLE/HLE.cpp | 16 ++++------- Core/HLE/sceKernelThread.cpp | 51 +++++++++++------------------------- Core/HLE/sceKernelThread.h | 5 ++-- Core/HLE/sceUmd.cpp | 2 +- 4 files changed, 23 insertions(+), 51 deletions(-) diff --git a/Core/HLE/HLE.cpp b/Core/HLE/HLE.cpp index 2b9610d9b3..cdd79c7543 100644 --- a/Core/HLE/HLE.cpp +++ b/Core/HLE/HLE.cpp @@ -54,7 +54,7 @@ static std::vector moduleDB; static std::vector unresolvedSyscalls; static std::vector exportedCalls; static int hleAfterSyscall = HLE_AFTER_NOTHING; -static char hleAfterSyscallReschedReason[512]; +static const char *hleAfterSyscallReschedReason; void HLEInit() { @@ -266,15 +266,9 @@ void hleReSchedule(const char *reason) hleAfterSyscall |= HLE_AFTER_RESCHED; if (!reason) - strcpy(hleAfterSyscallReschedReason, "Invalid reason"); - // You can't seriously need a reason that long, can you? - else if (strlen(reason) >= sizeof(hleAfterSyscallReschedReason)) - { - memcpy(hleAfterSyscallReschedReason, reason, sizeof(hleAfterSyscallReschedReason) - 1); - hleAfterSyscallReschedReason[sizeof(hleAfterSyscallReschedReason) - 1] = 0; - } + hleAfterSyscallReschedReason = "Invalid reason"; else - strcpy(hleAfterSyscallReschedReason, reason); + hleAfterSyscallReschedReason = reason; } void hleReSchedule(bool callbacks, const char *reason) @@ -334,13 +328,13 @@ inline void hleFinishSyscall(int modulenum, int funcnum) { // We'll do it next syscall. hleAfterSyscall = HLE_AFTER_DEBUG_BREAK; - hleAfterSyscallReschedReason[0] = 0; + hleAfterSyscallReschedReason = 0; return; } } hleAfterSyscall = HLE_AFTER_NOTHING; - hleAfterSyscallReschedReason[0] = 0; + hleAfterSyscallReschedReason = 0; } inline void updateSyscallStats(int modulenum, int funcnum, double total) diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index cc38af96d3..4dd2025535 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -55,25 +55,6 @@ enum PSP_THREAD_ATTR_CLEAR_STACK = 0x00200000, // TODO: Clear thread stack when deleted }; -const char *waitTypeStrings[] = { - "NONE", - "Sleep", - "Delay", - "Sema", - "EventFlag", - "Mbx", - "Vpl", - "Fpl", - "", - "ThreadEnd", // These are nonstandard wait types - "AudioChannel", - "Umd", - "Vblank", - "Mutex", - "LwMutex", - "Ctrl", -}; - struct NativeCallback { SceUInt size; @@ -989,7 +970,7 @@ u32 __KernelResumeThreadFromWait(SceUID threadID, int retval) // Only run when you can safely accept a context switch // Triggers a waitable event, that is, it wakes up all threads that waits for it // If any changes were made, it will context switch after the syscall -bool __KernelTriggerWait(WaitType type, int id, bool useRetVal, int retVal, bool dontSwitch) +bool __KernelTriggerWait(WaitType type, int id, bool useRetVal, int retVal, const char *reason, bool dontSwitch) { bool doneAnything = false; @@ -1012,22 +993,20 @@ bool __KernelTriggerWait(WaitType type, int id, bool useRetVal, int retVal, bool if (!dontSwitch) { // TODO: time waster - char temp[256]; - sprintf(temp, "resumed from wait %s", waitTypeStrings[(int)type]); - hleReSchedule(temp); + hleReSchedule(reason); } } return true; } -bool __KernelTriggerWait(WaitType type, int id, bool dontSwitch) +bool __KernelTriggerWait(WaitType type, int id, const char *reason, bool dontSwitch) { - return __KernelTriggerWait(type, id, false, 0, dontSwitch); + return __KernelTriggerWait(type, id, false, 0, reason, dontSwitch); } -bool __KernelTriggerWait(WaitType type, int id, int retVal, bool dontSwitch) +bool __KernelTriggerWait(WaitType type, int id, int retVal, const char *reason, bool dontSwitch) { - return __KernelTriggerWait(type, id, true, retVal, dontSwitch); + return __KernelTriggerWait(type, id, true, retVal, reason, dontSwitch); } // makes the current thread wait for an event @@ -1059,7 +1038,7 @@ void __KernelWaitCurThread(WaitType type, SceUID waitID, u32 waitValue, u32 time void hleScheduledWakeup(u64 userdata, int cyclesLate) { SceUID threadID = (SceUID)userdata; - __KernelTriggerWait(WAITTYPE_DELAY, threadID, true); + __KernelTriggerWait(WAITTYPE_DELAY, threadID, "thread delay finished", true); } void __KernelScheduleWakeup(SceUID threadID, s64 usFromNow) @@ -1485,7 +1464,7 @@ void __KernelReturnFromThread() // TODO: Need to remove the thread from any ready queues. - __KernelTriggerWait(WAITTYPE_THREADEND, __KernelGetCurThread(), thread->nt.exitStatus, true); + __KernelTriggerWait(WAITTYPE_THREADEND, __KernelGetCurThread(), thread->nt.exitStatus, "thread returned", true); hleReSchedule("thread returned"); // The stack will be deallocated when the thread is deleted. @@ -1501,7 +1480,7 @@ void sceKernelExitThread() thread->nt.exitStatus = PARAM(0); __KernelFireThreadEnd(thread); - __KernelTriggerWait(WAITTYPE_THREADEND, __KernelGetCurThread(), thread->nt.exitStatus, true); + __KernelTriggerWait(WAITTYPE_THREADEND, __KernelGetCurThread(), thread->nt.exitStatus, "thread exited", true); hleReSchedule("thread exited"); // The stack will be deallocated when the thread is deleted. @@ -1517,7 +1496,7 @@ void _sceKernelExitThread() thread->nt.exitStatus = PARAM(0); __KernelFireThreadEnd(thread); - __KernelTriggerWait(WAITTYPE_THREADEND, __KernelGetCurThread(), thread->nt.exitStatus, true); + __KernelTriggerWait(WAITTYPE_THREADEND, __KernelGetCurThread(), thread->nt.exitStatus, "thread _exited", true); hleReSchedule("thread _exited"); // The stack will be deallocated when the thread is deleted. @@ -1538,7 +1517,7 @@ void sceKernelExitDeleteThread() __KernelRemoveFromThreadQueue(t); currentThread = 0; - __KernelTriggerWait(WAITTYPE_THREADEND, threadHandle, t->nt.exitStatus, true); + __KernelTriggerWait(WAITTYPE_THREADEND, threadHandle, t->nt.exitStatus, "thead exited with delete", true); hleReSchedule("thead exited with delete"); RETURN(kernelObjects.Destroy(threadHandle)); @@ -1587,7 +1566,7 @@ int sceKernelDeleteThread(int threadHandle) __KernelFireThreadEnd(t); // TODO: Should this reschedule ever? Probably no? - __KernelTriggerWait(WAITTYPE_THREADEND, threadHandle, SCE_KERNEL_ERROR_THREAD_TERMINATED, true); + __KernelTriggerWait(WAITTYPE_THREADEND, threadHandle, SCE_KERNEL_ERROR_THREAD_TERMINATED, "thread deleted", true); return kernelObjects.Destroy(threadHandle); } @@ -1617,8 +1596,8 @@ int sceKernelTerminateDeleteThread(int threadno) __KernelFireThreadEnd(t); //TODO: should we really reschedule here? - __KernelTriggerWait(WAITTYPE_THREADEND, threadno, SCE_KERNEL_ERROR_THREAD_TERMINATED, false); - hleReSchedule("termdeletethread"); + __KernelTriggerWait(WAITTYPE_THREADEND, threadno, SCE_KERNEL_ERROR_THREAD_TERMINATED, "thread terminated with delete", false); + hleReSchedule("thread terminated with delete"); return kernelObjects.Destroy(threadno); } @@ -1647,7 +1626,7 @@ int sceKernelTerminateThread(u32 threadID) t->nt.status = THREADSTATUS_DORMANT; __KernelFireThreadEnd(t); // TODO: Should this really reschedule? - __KernelTriggerWait(WAITTYPE_THREADEND, threadID, t->nt.exitStatus, true); + __KernelTriggerWait(WAITTYPE_THREADEND, threadID, t->nt.exitStatus, "thread terminated", true); } // TODO: Return an error if it doesn't exist? return 0; diff --git a/Core/HLE/sceKernelThread.h b/Core/HLE/sceKernelThread.h index 12117df1a1..6925c6f916 100644 --- a/Core/HLE/sceKernelThread.h +++ b/Core/HLE/sceKernelThread.h @@ -82,7 +82,6 @@ enum WaitType //probably not the real values WAITTYPE_MUTEX = 13, WAITTYPE_LWMUTEX = 14, WAITTYPE_CTRL = 15, - // Remember to update sceKernelThread.cpp's waitTypeStrings to match. }; @@ -121,8 +120,8 @@ void __KernelLoadContext(ThreadContext *ctx); // TODO: Replace this with __KernelResumeThreadFromWait over time as it's misguided. // It's better that each subsystem keeps track of the list of waiting threads // and resumes them manually one by one using __KernelResumeThreadFromWait. -bool __KernelTriggerWait(WaitType type, int id, bool dontSwitch = false); -bool __KernelTriggerWait(WaitType type, int id, int retVal, bool dontSwitch); +bool __KernelTriggerWait(WaitType type, int id, const char *reason, bool dontSwitch = false); +bool __KernelTriggerWait(WaitType type, int id, int retVal, const char *reason, bool dontSwitch); u32 __KernelResumeThreadFromWait(SceUID threadID); // can return an error value u32 __KernelResumeThreadFromWait(SceUID threadID, int retval); diff --git a/Core/HLE/sceUmd.cpp b/Core/HLE/sceUmd.cpp index 1f2f2a072a..54d32c99f0 100644 --- a/Core/HLE/sceUmd.cpp +++ b/Core/HLE/sceUmd.cpp @@ -299,7 +299,7 @@ u32 sceUmdCancelWaitDriveStat() { DEBUG_LOG(HLE,"0=sceUmdCancelWaitDriveStat()"); - __KernelTriggerWait(WAITTYPE_UMD, 1, SCE_KERNEL_ERROR_WAIT_CANCEL, true); + __KernelTriggerWait(WAITTYPE_UMD, 1, SCE_KERNEL_ERROR_WAIT_CANCEL, "umd stat ready", true); // TODO: We should call UnscheduleEvent() event here? // But it's not often used anyway, and worst-case it will just do nothing unless it waits again. return 0; From 7f4e322266a0bf4dc801bd34f51305b21a906198 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 26 Jan 2013 11:27:06 -0800 Subject: [PATCH 3/4] Cut thread switching time down. Based on profiling release Windows. Took these funcs from taking 1.6% to 0.5% time. --- Core/HLE/sceKernelThread.cpp | 46 +++++++++++++----------------------- Core/HLE/sceKernelThread.h | 5 ++-- 2 files changed, 19 insertions(+), 32 deletions(-) diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 4dd2025535..367ad727fe 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -887,48 +887,34 @@ u32 sceKernelGetThreadmanIdList(u32 type, u32 readBufPtr, u32 readBufSize, u32 i // Saves the current CPU context void __KernelSaveContext(ThreadContext *ctx) { - for (int i = 0; i < 32; i++) - { - ctx->r[i] = currentMIPS->r[i]; - ctx->f[i] = currentMIPS->f[i]; - } - for (int i=0; i<128; i++) - { - ctx->v[i] = currentMIPS->v[i]; - } - for (int i=0; i<16; i++) - { - ctx->vfpuCtrl[i] = currentMIPS->vfpuCtrl[i]; - } + memcpy(ctx->r, currentMIPS->r, sizeof(ctx->r)); + memcpy(ctx->f, currentMIPS->f, sizeof(ctx->f)); + + // TODO: Make VFPU saving optional/delayed, only necessary between VFPU-attr-marked threads + memcpy(ctx->v, currentMIPS->v, sizeof(ctx->v)); + memcpy(ctx->vfpuCtrl, currentMIPS->vfpuCtrl, sizeof(ctx->vfpuCtrl)); + + ctx->pc = currentMIPS->pc; ctx->hi = currentMIPS->hi; ctx->lo = currentMIPS->lo; - ctx->pc = currentMIPS->pc; ctx->fcr0 = currentMIPS->fcr0; ctx->fcr31 = currentMIPS->fcr31; ctx->fpcond = currentMIPS->fpcond; - - // TODO: Make VFPU saving optional/delayed, only necessary between VFPU-attr-marked threads } // Loads a CPU context void __KernelLoadContext(ThreadContext *ctx) { - for (int i=0; i<32; i++) - { - currentMIPS->r[i] = ctx->r[i]; - currentMIPS->f[i] = ctx->f[i]; - } - for (int i=0; i<128; i++) - { - currentMIPS->v[i] = ctx->v[i]; - } - for (int i=0; i<15; i++) - { - currentMIPS->vfpuCtrl[i] = ctx->vfpuCtrl[i]; - } + memcpy(currentMIPS->r, ctx->r, sizeof(ctx->r)); + memcpy(currentMIPS->f, ctx->f, sizeof(ctx->f)); + + // TODO: Make VFPU saving optional/delayed, only necessary between VFPU-attr-marked threads + memcpy(currentMIPS->v, ctx->v, sizeof(ctx->v)); + memcpy(currentMIPS->vfpuCtrl, ctx->vfpuCtrl, sizeof(ctx->vfpuCtrl)); + + currentMIPS->pc = ctx->pc; currentMIPS->hi = ctx->hi; currentMIPS->lo = ctx->lo; - currentMIPS->pc = ctx->pc; currentMIPS->fcr0 = ctx->fcr0; currentMIPS->fcr31 = ctx->fcr31; currentMIPS->fpcond = ctx->fpcond; diff --git a/Core/HLE/sceKernelThread.h b/Core/HLE/sceKernelThread.h index 6925c6f916..c1af7d70d6 100644 --- a/Core/HLE/sceKernelThread.h +++ b/Core/HLE/sceKernelThread.h @@ -93,13 +93,14 @@ struct ThreadContext float v[128]; u32 vfpuCtrl[16]; + u32 pc; + u32 hi; u32 lo; - u32 pc; - u32 fpcond; u32 fcr0; u32 fcr31; + u32 fpcond; }; // Internal API, used by implementations of kernel functions From 6e403be006c54bc0154336440c1df164c46458fd Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 26 Jan 2013 11:36:45 -0800 Subject: [PATCH 4/4] Skip a double map lookup. Profiler says this was taking extra time. Only saves 0.23%. --- GPU/GLES/TransformPipeline.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GPU/GLES/TransformPipeline.cpp b/GPU/GLES/TransformPipeline.cpp index 374ae6fd47..5bcc6cf71c 100644 --- a/GPU/GLES/TransformPipeline.cpp +++ b/GPU/GLES/TransformPipeline.cpp @@ -850,7 +850,7 @@ void TransformDrawEngine::Flush() { u32 id = ComputeFastDCID(); auto iter = vai_.find(id); VertexArrayInfo *vai; - if (vai_.find(id) != vai_.end()) { + if (iter != vai_.end()) { // We've seen this before. Could have been a cached draw. vai = iter->second; } else {