mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-02-08 06:47:19 +00:00
Refactor wait timeouts.
Also, make them not write the timeout ptr if the thread stopped waiting. Feels safer.
This commit is contained in:
parent
2a7e9a5afc
commit
543df7ca7a
@ -25,6 +25,26 @@
|
||||
namespace HLEKernel
|
||||
{
|
||||
|
||||
// Should be called from the CoreTiming handler for the wait func.
|
||||
template <typename KO, WaitType waitType>
|
||||
inline void WaitExecTimeout(SceUID threadID) {
|
||||
u32 error;
|
||||
SceUID uid = __KernelGetWaitID(threadID, waitType, error);
|
||||
u32 timeoutPtr = __KernelGetWaitTimeoutPtr(threadID, error);
|
||||
KO *ko = uid == 0 ? NULL : kernelObjects.Get<KO>(uid, error);
|
||||
if (ko)
|
||||
{
|
||||
if (timeoutPtr != 0)
|
||||
Memory::Write_U32(0, timeoutPtr);
|
||||
|
||||
// This thread isn't waiting anymore, but we'll remove it from waitingThreads later.
|
||||
// The reason is, if it times out, but what it was waiting on is DELETED prior to it
|
||||
// actually running, it will get a DELETE result instead of a TIMEOUT.
|
||||
// So, we need to remember it or we won't be able to mark it DELETE instead later.
|
||||
__KernelResumeThreadFromWait(threadID, SCE_KERNEL_ERROR_WAIT_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
// Move a thead from the waiting thread list to the paused thread list.
|
||||
// This version is for vectors which contain structs, which must have SceUID threadID and u64 pausedTimeout.
|
||||
// Should not be called directly.
|
||||
|
@ -355,15 +355,16 @@ void __KernelEventFlagTimeout(u64 userdata, int cycleslate)
|
||||
{
|
||||
SceUID threadID = (SceUID)userdata;
|
||||
|
||||
// This still needs to set the result pointer from the wait.
|
||||
u32 error;
|
||||
u32 timeoutPtr = __KernelGetWaitTimeoutPtr(threadID, error);
|
||||
if (timeoutPtr != 0)
|
||||
Memory::Write_U32(0, timeoutPtr);
|
||||
|
||||
SceUID flagID = __KernelGetWaitID(threadID, WAITTYPE_EVENTFLAG, error);
|
||||
u32 timeoutPtr = __KernelGetWaitTimeoutPtr(threadID, error);
|
||||
EventFlag *e = kernelObjects.Get<EventFlag>(flagID, error);
|
||||
if (e)
|
||||
{
|
||||
if (timeoutPtr != 0)
|
||||
Memory::Write_U32(0, timeoutPtr);
|
||||
|
||||
for (size_t i = 0; i < e->waitingThreads.size(); i++)
|
||||
{
|
||||
EventFlagTh *t = &e->waitingThreads[i];
|
||||
|
@ -257,24 +257,7 @@ void __KernelMbxEndCallback(SceUID threadID, SceUID prevCallbackId)
|
||||
void __KernelMbxTimeout(u64 userdata, int cyclesLate)
|
||||
{
|
||||
SceUID threadID = (SceUID)userdata;
|
||||
|
||||
u32 error;
|
||||
u32 timeoutPtr = __KernelGetWaitTimeoutPtr(threadID, error);
|
||||
if (timeoutPtr != 0)
|
||||
Memory::Write_U32(0, timeoutPtr);
|
||||
|
||||
SceUID mbxID = __KernelGetWaitID(threadID, WAITTYPE_MBX, error);
|
||||
Mbx *m = kernelObjects.Get<Mbx>(mbxID, error);
|
||||
if (m)
|
||||
{
|
||||
// This thread isn't waiting anymore, but we'll remove it from waitingThreads later.
|
||||
// The reason is, if it times out, but what it was waiting on is DELETED prior to it
|
||||
// actually running, it will get a DELETE result instead of a TIMEOUT.
|
||||
// So, we need to remember it or we won't be able to mark it DELETE instead later.
|
||||
|
||||
// TODO: Should numWaitThreads be decreased yet?
|
||||
__KernelResumeThreadFromWait(threadID, SCE_KERNEL_ERROR_WAIT_TIMEOUT);
|
||||
}
|
||||
HLEKernel::WaitExecTimeout<Mbx, WAITTYPE_MBX>(threadID);
|
||||
}
|
||||
|
||||
void __KernelWaitMbx(Mbx *m, u32 timeoutPtr)
|
||||
|
@ -457,22 +457,7 @@ int sceKernelDeleteFpl(SceUID uid)
|
||||
void __KernelFplTimeout(u64 userdata, int cyclesLate)
|
||||
{
|
||||
SceUID threadID = (SceUID) userdata;
|
||||
|
||||
u32 error;
|
||||
u32 timeoutPtr = __KernelGetWaitTimeoutPtr(threadID, error);
|
||||
if (timeoutPtr != 0)
|
||||
Memory::Write_U32(0, timeoutPtr);
|
||||
|
||||
SceUID uid = __KernelGetWaitID(threadID, WAITTYPE_FPL, error);
|
||||
FPL *fpl = kernelObjects.Get<FPL>(uid, error);
|
||||
if (fpl)
|
||||
{
|
||||
// This thread isn't waiting anymore, but we'll remove it from waitingThreads later.
|
||||
// The reason is, if it times out, but while it was waiting on is DELETED prior to it
|
||||
// actually running, it will get a DELETE result instead of a TIMEOUT.
|
||||
// So, we need to remember it or we won't be able to mark it DELETE instead later.
|
||||
__KernelResumeThreadFromWait(threadID, SCE_KERNEL_ERROR_WAIT_TIMEOUT);
|
||||
}
|
||||
HLEKernel::WaitExecTimeout<FPL, WAITTYPE_FPL>(threadID);
|
||||
}
|
||||
|
||||
void __KernelSetFplTimeout(u32 timeoutPtr)
|
||||
@ -1383,22 +1368,7 @@ bool __KernelAllocateVpl(SceUID uid, u32 size, u32 addrPtr, u32 &error, const ch
|
||||
void __KernelVplTimeout(u64 userdata, int cyclesLate)
|
||||
{
|
||||
SceUID threadID = (SceUID) userdata;
|
||||
|
||||
u32 error;
|
||||
u32 timeoutPtr = __KernelGetWaitTimeoutPtr(threadID, error);
|
||||
if (timeoutPtr != 0)
|
||||
Memory::Write_U32(0, timeoutPtr);
|
||||
|
||||
SceUID uid = __KernelGetWaitID(threadID, WAITTYPE_VPL, error);
|
||||
VPL *vpl = kernelObjects.Get<VPL>(uid, error);
|
||||
if (vpl)
|
||||
{
|
||||
// This thread isn't waiting anymore, but we'll remove it from waitingThreads later.
|
||||
// The reason is, if it times out, but while it was waiting on is DELETED prior to it
|
||||
// actually running, it will get a DELETE result instead of a TIMEOUT.
|
||||
// So, we need to remember it or we won't be able to mark it DELETE instead later.
|
||||
__KernelResumeThreadFromWait(threadID, SCE_KERNEL_ERROR_WAIT_TIMEOUT);
|
||||
}
|
||||
HLEKernel::WaitExecTimeout<VPL, WAITTYPE_VPL>(threadID);
|
||||
}
|
||||
|
||||
void __KernelSetVplTimeout(u32 timeoutPtr)
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "Core/HLE/sceKernelMemory.h"
|
||||
#include "Core/HLE/sceKernelInterrupt.h"
|
||||
#include "Core/HLE/sceKernelThread.h"
|
||||
#include "Core/HLE/KernelWaitHelpers.h"
|
||||
#include "Common/ChunkFile.h"
|
||||
|
||||
#define SCE_KERNEL_MPA_THFIFO_S 0x0000
|
||||
@ -297,23 +298,8 @@ KernelObject *__KernelMsgPipeObject()
|
||||
|
||||
void __KernelMsgPipeTimeout(u64 userdata, int cyclesLate)
|
||||
{
|
||||
SceUID threadID = (SceUID) (userdata & 0xFFFFFFFF);
|
||||
|
||||
u32 error;
|
||||
u32 timeoutPtr = __KernelGetWaitTimeoutPtr(threadID, error);
|
||||
if (timeoutPtr != 0)
|
||||
Memory::Write_U32(0, timeoutPtr);
|
||||
|
||||
SceUID uid = __KernelGetWaitID(threadID, WAITTYPE_MSGPIPE, error);
|
||||
MsgPipe *m = kernelObjects.Get<MsgPipe>(uid, error);
|
||||
if (m)
|
||||
{
|
||||
// This thread isn't waiting anymore, but we'll remove it from waitingThreads later.
|
||||
// The reason is, if it times out, but whhile it was waiting on is DELETED prior to it
|
||||
// actually running, it will get a DELETE result instead of a TIMEOUT.
|
||||
// So, we need to remember it or we won't be able to mark it DELETE instead later.
|
||||
__KernelResumeThreadFromWait(threadID, SCE_KERNEL_ERROR_WAIT_TIMEOUT);
|
||||
}
|
||||
SceUID threadID = (SceUID) userdata;
|
||||
HLEKernel::WaitExecTimeout<MsgPipe, WAITTYPE_MSGPIPE>(threadID);
|
||||
}
|
||||
|
||||
bool __KernelSetMsgPipeTimeout(u32 timeoutPtr)
|
||||
|
@ -334,22 +334,7 @@ retry:
|
||||
void __KernelSemaTimeout(u64 userdata, int cycleslate)
|
||||
{
|
||||
SceUID threadID = (SceUID)userdata;
|
||||
|
||||
u32 error;
|
||||
u32 timeoutPtr = __KernelGetWaitTimeoutPtr(threadID, error);
|
||||
if (timeoutPtr != 0)
|
||||
Memory::Write_U32(0, timeoutPtr);
|
||||
|
||||
SceUID semaID = __KernelGetWaitID(threadID, WAITTYPE_SEMA, error);
|
||||
Semaphore *s = kernelObjects.Get<Semaphore>(semaID, error);
|
||||
if (s)
|
||||
{
|
||||
// This thread isn't waiting anymore, but we'll remove it from waitingThreads later.
|
||||
// The reason is, if it times out, but what it was waiting on is DELETED prior to it
|
||||
// actually running, it will get a DELETE result instead of a TIMEOUT.
|
||||
// So, we need to remember it or we won't be able to mark it DELETE instead later.
|
||||
__KernelResumeThreadFromWait(threadID, SCE_KERNEL_ERROR_WAIT_TIMEOUT);
|
||||
}
|
||||
HLEKernel::WaitExecTimeout<Semaphore, WAITTYPE_SEMA>(threadID);
|
||||
}
|
||||
|
||||
void __KernelSetSemaTimeout(Semaphore *s, u32 timeoutPtr)
|
||||
|
Loading…
x
Reference in New Issue
Block a user