mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Verify msgpipe threads are waiting before waking.
This commit is contained in:
parent
b9a71640eb
commit
b06de35536
1 changed files with 32 additions and 23 deletions
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue