Verify msgpipe threads are waiting before waking.

This commit is contained in:
Unknown W. Brackets 2013-08-18 09:48:43 -07:00
parent b9a71640eb
commit b06de35536

View file

@ -57,11 +57,17 @@ struct MsgPipeWaitingThread
s32 waitMode; s32 waitMode;
PSPPointer<u32_le> transferredBytes; PSPPointer<u32_le> transferredBytes;
void Cancel(SceUID waitID, int result) bool IsStillWaiting(SceUID waitID) const
{ {
u32 error; u32 error;
int actualWaitID = __KernelGetWaitID(id, WAITTYPE_MSGPIPE, error); int actualWaitID = __KernelGetWaitID(id, WAITTYPE_MSGPIPE, error);
if (actualWaitID == waitID) return actualWaitID == waitID;
}
void WriteCurrentTimeout(SceUID waitID) const
{
u32 error;
if (IsStillWaiting(waitID))
{ {
u32 timeoutPtr = __KernelGetWaitTimeoutPtr(id, error); u32 timeoutPtr = __KernelGetWaitTimeoutPtr(id, error);
if (timeoutPtr != 0 && waitTimer != -1) if (timeoutPtr != 0 && waitTimer != -1)
@ -70,11 +76,24 @@ struct MsgPipeWaitingThread
s64 cyclesLeft = CoreTiming::UnscheduleEvent(waitTimer, id); s64 cyclesLeft = CoreTiming::UnscheduleEvent(waitTimer, id);
Memory::Write_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr); Memory::Write_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr);
} }
}
}
*transferredBytes = 0; void Complete(SceUID waitID, int result, u32 transferred = (u32)-1) const
{
if (IsStillWaiting(waitID))
{
WriteCurrentTimeout(waitID);
if (transferred != (u32)-1)
*transferredBytes = transferred;
__KernelResumeThreadFromWait(id, result); __KernelResumeThreadFromWait(id, result);
} }
} }
void Cancel(SceUID waitID, int result) const
{
Complete(waitID, result, 0);
}
}; };
struct MsgPipe : public KernelObject struct MsgPipe : public KernelObject
@ -135,9 +154,8 @@ struct MsgPipe : public KernelObject
{ {
// Put all the data to the buffer // Put all the data to the buffer
Memory::Memcpy(buffer + (nmp.bufSize - nmp.freeSize), Memory::GetPointer(thread->bufAddr), thread->bufSize); Memory::Memcpy(buffer + (nmp.bufSize - nmp.freeSize), Memory::GetPointer(thread->bufAddr), thread->bufSize);
*thread->transferredBytes = thread->bufSize;
nmp.freeSize -= thread->bufSize; nmp.freeSize -= thread->bufSize;
__KernelResumeThreadFromWait(thread->id, 0); thread->Complete(GetUID(), 0, thread->bufSize);
sendWaitingThreads.erase(sendWaitingThreads.begin()); sendWaitingThreads.erase(sendWaitingThreads.begin());
CheckReceiveThreads(); CheckReceiveThreads();
} }
@ -145,9 +163,8 @@ struct MsgPipe : public KernelObject
{ {
// Put as much data as possible into the buffer // Put as much data as possible into the buffer
Memory::Memcpy(buffer + (nmp.bufSize - nmp.freeSize), Memory::GetPointer(thread->bufAddr), nmp.freeSize); Memory::Memcpy(buffer + (nmp.bufSize - nmp.freeSize), Memory::GetPointer(thread->bufAddr), nmp.freeSize);
*thread->transferredBytes = nmp.freeSize;
nmp.freeSize = 0; nmp.freeSize = 0;
__KernelResumeThreadFromWait(thread->id, 0); thread->Complete(GetUID(), 0, nmp.freeSize);
receiveWaitingThreads.erase(receiveWaitingThreads.begin()); receiveWaitingThreads.erase(receiveWaitingThreads.begin());
CheckReceiveThreads(); CheckReceiveThreads();
} }
@ -165,9 +182,8 @@ struct MsgPipe : public KernelObject
Memory::Memcpy(thread->bufAddr, Memory::GetPointer(buffer), thread->bufSize); Memory::Memcpy(thread->bufAddr, Memory::GetPointer(buffer), thread->bufSize);
// Put the unused data at the start of the buffer // Put the unused data at the start of the buffer
memmove(Memory::GetPointer(buffer), Memory::GetPointer(buffer) + thread->bufSize, nmp.bufSize - nmp.freeSize); memmove(Memory::GetPointer(buffer), Memory::GetPointer(buffer) + thread->bufSize, nmp.bufSize - nmp.freeSize);
*thread->transferredBytes = thread->bufSize;
nmp.freeSize += thread->bufSize; nmp.freeSize += thread->bufSize;
__KernelResumeThreadFromWait(thread->id, 0); thread->Complete(GetUID(), 0, thread->bufSize);
receiveWaitingThreads.erase(receiveWaitingThreads.begin()); receiveWaitingThreads.erase(receiveWaitingThreads.begin());
CheckSendThreads(); CheckSendThreads();
} }
@ -175,9 +191,8 @@ struct MsgPipe : public KernelObject
{ {
// Get all the data from the buffer // Get all the data from the buffer
Memory::Memcpy(thread->bufAddr, Memory::GetPointer(buffer), nmp.bufSize - nmp.freeSize); Memory::Memcpy(thread->bufAddr, Memory::GetPointer(buffer), nmp.bufSize - nmp.freeSize);
*thread->transferredBytes = nmp.bufSize - nmp.freeSize;
nmp.freeSize = nmp.bufSize; nmp.freeSize = nmp.bufSize;
__KernelResumeThreadFromWait(thread->id, 0); thread->Complete(GetUID(), 0, nmp.bufSize - nmp.freeSize);
receiveWaitingThreads.erase(receiveWaitingThreads.begin()); receiveWaitingThreads.erase(receiveWaitingThreads.begin());
CheckSendThreads(); CheckSendThreads();
} }
@ -353,8 +368,7 @@ void __KernelSendMsgPipe(MsgPipe *m, u32 sendBufAddr, u32 sendSize, int waitMode
sendSize = 0; sendSize = 0;
if (thread->waitMode == SCE_KERNEL_MPW_ASAP) if (thread->waitMode == SCE_KERNEL_MPW_ASAP)
{ {
*thread->transferredBytes = thread->bufSize - thread->freeSize; thread->Complete(m->GetUID(), 0, thread->bufSize - thread->freeSize);
__KernelResumeThreadFromWait(thread->id, 0);
m->receiveWaitingThreads.erase(m->receiveWaitingThreads.begin()); m->receiveWaitingThreads.erase(m->receiveWaitingThreads.begin());
} }
break; break;
@ -362,8 +376,7 @@ void __KernelSendMsgPipe(MsgPipe *m, u32 sendBufAddr, u32 sendSize, int waitMode
else if (thread->freeSize == sendSize) else if (thread->freeSize == sendSize)
{ {
Memory::Memcpy(thread->bufAddr + (thread->bufSize - thread->freeSize), Memory::GetPointer(curSendAddr), sendSize); Memory::Memcpy(thread->bufAddr + (thread->bufSize - thread->freeSize), Memory::GetPointer(curSendAddr), sendSize);
*thread->transferredBytes = thread->bufSize; thread->Complete(m->GetUID(), 0, thread->bufSize);
__KernelResumeThreadFromWait(thread->id, 0);
m->receiveWaitingThreads.erase(m->receiveWaitingThreads.begin()); m->receiveWaitingThreads.erase(m->receiveWaitingThreads.begin());
curSendAddr += sendSize; curSendAddr += sendSize;
sendSize = 0; sendSize = 0;
@ -374,8 +387,7 @@ void __KernelSendMsgPipe(MsgPipe *m, u32 sendBufAddr, u32 sendSize, int waitMode
Memory::Memcpy(thread->bufAddr + (thread->bufSize - thread->freeSize), Memory::GetPointer(curSendAddr), thread->freeSize); Memory::Memcpy(thread->bufAddr + (thread->bufSize - thread->freeSize), Memory::GetPointer(curSendAddr), thread->freeSize);
sendSize -= thread->freeSize; sendSize -= thread->freeSize;
curSendAddr += thread->freeSize; curSendAddr += thread->freeSize;
*thread->transferredBytes = thread->bufSize; thread->Complete(m->GetUID(), 0, thread->bufSize);
__KernelResumeThreadFromWait(thread->id, 0);
m->receiveWaitingThreads.erase(m->receiveWaitingThreads.begin()); m->receiveWaitingThreads.erase(m->receiveWaitingThreads.begin());
} }
} }
@ -525,8 +537,7 @@ void __KernelReceiveMsgPipe(MsgPipe *m, u32 receiveBufAddr, u32 receiveSize, int
// The sending thread mode is ASAP: we have sent some data so restart it even though its buffer isn't empty // The sending thread mode is ASAP: we have sent some data so restart it even though its buffer isn't empty
if (thread->waitMode == SCE_KERNEL_MPW_ASAP) if (thread->waitMode == SCE_KERNEL_MPW_ASAP)
{ {
*thread->transferredBytes = thread->bufSize - thread->freeSize; thread->Complete(m->GetUID(), 0, thread->bufSize - thread->freeSize);
__KernelResumeThreadFromWait(thread->id, 0);
m->sendWaitingThreads.erase(m->sendWaitingThreads.begin()); m->sendWaitingThreads.erase(m->sendWaitingThreads.begin());
} }
break; break;
@ -535,8 +546,7 @@ void __KernelReceiveMsgPipe(MsgPipe *m, u32 receiveBufAddr, u32 receiveSize, int
else if (thread->bufSize - thread->freeSize == receiveSize) else if (thread->bufSize - thread->freeSize == receiveSize)
{ {
Memory::Memcpy(curReceiveAddr, Memory::GetPointer(thread->bufAddr), receiveSize); Memory::Memcpy(curReceiveAddr, Memory::GetPointer(thread->bufAddr), receiveSize);
*thread->transferredBytes = thread->bufSize; thread->Complete(m->GetUID(), 0, thread->bufSize);
__KernelResumeThreadFromWait(thread->id, 0);
m->sendWaitingThreads.erase(m->sendWaitingThreads.begin()); m->sendWaitingThreads.erase(m->sendWaitingThreads.begin());
curReceiveAddr += receiveSize; curReceiveAddr += receiveSize;
receiveSize = 0; receiveSize = 0;
@ -548,8 +558,7 @@ void __KernelReceiveMsgPipe(MsgPipe *m, u32 receiveBufAddr, u32 receiveSize, int
Memory::Memcpy(curReceiveAddr, Memory::GetPointer(thread->bufAddr), thread->bufSize - thread->freeSize); Memory::Memcpy(curReceiveAddr, Memory::GetPointer(thread->bufAddr), thread->bufSize - thread->freeSize);
receiveSize -= thread->bufSize - thread->freeSize; receiveSize -= thread->bufSize - thread->freeSize;
curReceiveAddr += thread->bufSize - thread->freeSize; curReceiveAddr += thread->bufSize - thread->freeSize;
*thread->transferredBytes = thread->bufSize; thread->Complete(m->GetUID(), 0, thread->bufSize);
__KernelResumeThreadFromWait(thread->id, 0);
m->sendWaitingThreads.erase(m->sendWaitingThreads.begin()); m->sendWaitingThreads.erase(m->sendWaitingThreads.begin());
} }
} }