mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-01-22 22:06:58 +00:00
Clean up sceKernelFreeVpl(), not waking yet.
This commit is contained in:
parent
c8bb837996
commit
4c510b5649
@ -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"},
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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++)
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user