Clean up sceKernelFreeVpl(), not waking yet.

This commit is contained in:
Unknown W. Brackets 2013-01-16 00:47:06 -08:00
parent c8bb837996
commit 4c510b5649
5 changed files with 50 additions and 15 deletions

View File

@ -627,7 +627,7 @@ const HLEFunction ThreadManForUser[] =
{0xBED27435,WrapI_IUUU<sceKernelAllocateVpl>,"sceKernelAllocateVpl"},
{0xEC0A693F,WrapI_IUUU<sceKernelAllocateVplCB>,"sceKernelAllocateVplCB"},
{0xAF36D708,WrapI_IUU<sceKernelTryAllocateVpl>,"sceKernelTryAllocateVpl"},
{0xB736E9FF,sceKernelFreeVpl,"sceKernelFreeVpl"},
{0xB736E9FF,WrapI_IU<sceKernelFreeVpl>,"sceKernelFreeVpl"},
{0x1D371B8A,sceKernelCancelVpl,"sceKernelCancelVpl"},
{0x39810265,sceKernelReferVplStatus,"sceKernelReferVplStatus"},

View File

@ -15,6 +15,7 @@
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include <algorithm>
#include "HLE.h"
#include "../System.h"
#include "../MIPS/MIPS.h"
@ -130,12 +131,15 @@ struct VPL : public KernelObject
{
p.Do(nv);
p.Do(address);
SceUID dv = 0;
p.Do(waitingThreads, dv);
alloc.DoState(p);
p.DoMarker("VPL");
}
SceKernelVplInfo nv;
u32 address;
std::vector<SceUID> waitingThreads;
BlockAllocator alloc;
};
@ -894,8 +898,14 @@ int sceKernelAllocateVpl(SceUID uid, u32 size, u32 addrPtr, u32 timeoutPtr)
{
VPL *vpl = kernelObjects.Get<VPL>(uid, error);
if (vpl)
{
vpl->nv.numWaitThreads++;
SceUID threadID = __KernelGetCurThread();
if (std::find(vpl->waitingThreads.begin(), vpl->waitingThreads.end(), threadID) == vpl->waitingThreads.end())
vpl->waitingThreads.push_back(threadID);
}
__KernelSetVplTimeout(timeoutPtr);
__KernelWaitCurThread(WAITTYPE_VPL, uid, size, timeoutPtr, false);
}
@ -914,8 +924,14 @@ int sceKernelAllocateVplCB(SceUID uid, u32 size, u32 addrPtr, u32 timeoutPtr)
{
VPL *vpl = kernelObjects.Get<VPL>(uid, error);
if (vpl)
{
vpl->nv.numWaitThreads++;
SceUID threadID = __KernelGetCurThread();
if (std::find(vpl->waitingThreads.begin(), vpl->waitingThreads.end(), threadID) == vpl->waitingThreads.end())
vpl->waitingThreads.push_back(threadID);
}
__KernelSetVplTimeout(timeoutPtr);
__KernelWaitCurThread(WAITTYPE_VPL, uid, size, timeoutPtr, true);
}
@ -930,26 +946,32 @@ int sceKernelTryAllocateVpl(SceUID uid, u32 size, u32 addrPtr)
return error;
}
void sceKernelFreeVpl()
int sceKernelFreeVpl(SceUID uid, u32 addr)
{
SceUID id = PARAM(0);
u32 blockPtr = PARAM(1);
DEBUG_LOG(HLE,"sceKernelFreeVpl(%i, %08x)", id, blockPtr);
if (addr && !Memory::IsValidAddress(addr))
{
WARN_LOG(HLE, "%08x=sceKernelFreeVpl(%i, %08x): Invalid address", SCE_KERNEL_ERROR_ILLEGAL_ADDR, uid, addr);
return SCE_KERNEL_ERROR_ILLEGAL_ADDR;
}
DEBUG_LOG(HLE, "sceKernelFreeVpl(%i, %08x)", uid, addr);
u32 error;
VPL *vpl = kernelObjects.Get<VPL>(id, error);
VPL *vpl = kernelObjects.Get<VPL>(uid, error);
if (vpl)
{
if (vpl->alloc.Free(blockPtr)) {
RETURN(0);
if (vpl->alloc.FreeExact(addr))
{
// Should trigger waiting threads
} else {
ERROR_LOG(HLE, "sceKernelFreeVpl: Error freeing %08x", blockPtr);
RETURN(-1);
return 0;
}
else
{
WARN_LOG(HLE, "%08x=sceKernelFreeVpl(%i, %08x): Unable to free", SCE_KERNEL_ERROR_ILLEGAL_MEMBLOCK, uid, addr);
return SCE_KERNEL_ERROR_ILLEGAL_MEMBLOCK;
}
}
else {
RETURN(error);
}
else
return error;
}
void sceKernelCancelVpl()

View File

@ -41,7 +41,7 @@ void sceKernelDeleteVpl();
int sceKernelAllocateVpl(SceUID uid, u32 size, u32 addrPtr, u32 timeoutPtr);
int sceKernelAllocateVplCB(SceUID uid, u32 size, u32 addrPtr, u32 timeoutPtr);
int sceKernelTryAllocateVpl(SceUID uid, u32 size, u32 addrPtr);
void sceKernelFreeVpl();
int sceKernelFreeVpl(SceUID uid, u32 addr);
void sceKernelCancelVpl();
void sceKernelReferVplStatus();

View File

@ -219,6 +219,18 @@ bool BlockAllocator::Free(u32 position)
}
}
bool BlockAllocator::FreeExact(u32 position)
{
BlockAllocator::Block *b = GetBlockFromAddress(position);
if (b && b->taken && b->start == position)
return Free(position);
else
{
ERROR_LOG(HLE, "BlockAllocator : invalid free %08x", position);
return false;
}
}
void BlockAllocator::CheckBlocks()
{
for (std::list<Block>::iterator iter = blocks.begin(); iter != blocks.end(); iter++)

View File

@ -29,6 +29,7 @@ public:
u32 AllocAt(u32 position, u32 size, const char *tag = 0);
bool Free(u32 position);
bool FreeExact(u32 position);
bool IsBlockFree(u32 position) {
Block *b = GetBlockFromAddress(position);
if (b)