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"},
|
{0xBED27435,WrapI_IUUU<sceKernelAllocateVpl>,"sceKernelAllocateVpl"},
|
||||||
{0xEC0A693F,WrapI_IUUU<sceKernelAllocateVplCB>,"sceKernelAllocateVplCB"},
|
{0xEC0A693F,WrapI_IUUU<sceKernelAllocateVplCB>,"sceKernelAllocateVplCB"},
|
||||||
{0xAF36D708,WrapI_IUU<sceKernelTryAllocateVpl>,"sceKernelTryAllocateVpl"},
|
{0xAF36D708,WrapI_IUU<sceKernelTryAllocateVpl>,"sceKernelTryAllocateVpl"},
|
||||||
{0xB736E9FF,sceKernelFreeVpl,"sceKernelFreeVpl"},
|
{0xB736E9FF,WrapI_IU<sceKernelFreeVpl>,"sceKernelFreeVpl"},
|
||||||
{0x1D371B8A,sceKernelCancelVpl,"sceKernelCancelVpl"},
|
{0x1D371B8A,sceKernelCancelVpl,"sceKernelCancelVpl"},
|
||||||
{0x39810265,sceKernelReferVplStatus,"sceKernelReferVplStatus"},
|
{0x39810265,sceKernelReferVplStatus,"sceKernelReferVplStatus"},
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
// Official git repository and contact information can be found at
|
// Official git repository and contact information can be found at
|
||||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include "HLE.h"
|
#include "HLE.h"
|
||||||
#include "../System.h"
|
#include "../System.h"
|
||||||
#include "../MIPS/MIPS.h"
|
#include "../MIPS/MIPS.h"
|
||||||
@ -130,12 +131,15 @@ struct VPL : public KernelObject
|
|||||||
{
|
{
|
||||||
p.Do(nv);
|
p.Do(nv);
|
||||||
p.Do(address);
|
p.Do(address);
|
||||||
|
SceUID dv = 0;
|
||||||
|
p.Do(waitingThreads, dv);
|
||||||
alloc.DoState(p);
|
alloc.DoState(p);
|
||||||
p.DoMarker("VPL");
|
p.DoMarker("VPL");
|
||||||
}
|
}
|
||||||
|
|
||||||
SceKernelVplInfo nv;
|
SceKernelVplInfo nv;
|
||||||
u32 address;
|
u32 address;
|
||||||
|
std::vector<SceUID> waitingThreads;
|
||||||
BlockAllocator alloc;
|
BlockAllocator alloc;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -894,8 +898,14 @@ int sceKernelAllocateVpl(SceUID uid, u32 size, u32 addrPtr, u32 timeoutPtr)
|
|||||||
{
|
{
|
||||||
VPL *vpl = kernelObjects.Get<VPL>(uid, error);
|
VPL *vpl = kernelObjects.Get<VPL>(uid, error);
|
||||||
if (vpl)
|
if (vpl)
|
||||||
|
{
|
||||||
vpl->nv.numWaitThreads++;
|
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);
|
__KernelSetVplTimeout(timeoutPtr);
|
||||||
__KernelWaitCurThread(WAITTYPE_VPL, uid, size, timeoutPtr, false);
|
__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);
|
VPL *vpl = kernelObjects.Get<VPL>(uid, error);
|
||||||
if (vpl)
|
if (vpl)
|
||||||
|
{
|
||||||
vpl->nv.numWaitThreads++;
|
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);
|
__KernelSetVplTimeout(timeoutPtr);
|
||||||
__KernelWaitCurThread(WAITTYPE_VPL, uid, size, timeoutPtr, true);
|
__KernelWaitCurThread(WAITTYPE_VPL, uid, size, timeoutPtr, true);
|
||||||
}
|
}
|
||||||
@ -930,26 +946,32 @@ int sceKernelTryAllocateVpl(SceUID uid, u32 size, u32 addrPtr)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sceKernelFreeVpl()
|
int sceKernelFreeVpl(SceUID uid, u32 addr)
|
||||||
{
|
{
|
||||||
SceUID id = PARAM(0);
|
if (addr && !Memory::IsValidAddress(addr))
|
||||||
u32 blockPtr = PARAM(1);
|
{
|
||||||
DEBUG_LOG(HLE,"sceKernelFreeVpl(%i, %08x)", id, blockPtr);
|
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;
|
u32 error;
|
||||||
VPL *vpl = kernelObjects.Get<VPL>(id, error);
|
VPL *vpl = kernelObjects.Get<VPL>(uid, error);
|
||||||
if (vpl)
|
if (vpl)
|
||||||
{
|
{
|
||||||
if (vpl->alloc.Free(blockPtr)) {
|
if (vpl->alloc.FreeExact(addr))
|
||||||
RETURN(0);
|
{
|
||||||
// Should trigger waiting threads
|
// Should trigger waiting threads
|
||||||
} else {
|
return 0;
|
||||||
ERROR_LOG(HLE, "sceKernelFreeVpl: Error freeing %08x", blockPtr);
|
}
|
||||||
RETURN(-1);
|
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 {
|
else
|
||||||
RETURN(error);
|
return error;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sceKernelCancelVpl()
|
void sceKernelCancelVpl()
|
||||||
|
@ -41,7 +41,7 @@ void sceKernelDeleteVpl();
|
|||||||
int sceKernelAllocateVpl(SceUID uid, u32 size, u32 addrPtr, u32 timeoutPtr);
|
int sceKernelAllocateVpl(SceUID uid, u32 size, u32 addrPtr, u32 timeoutPtr);
|
||||||
int sceKernelAllocateVplCB(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);
|
int sceKernelTryAllocateVpl(SceUID uid, u32 size, u32 addrPtr);
|
||||||
void sceKernelFreeVpl();
|
int sceKernelFreeVpl(SceUID uid, u32 addr);
|
||||||
void sceKernelCancelVpl();
|
void sceKernelCancelVpl();
|
||||||
void sceKernelReferVplStatus();
|
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()
|
void BlockAllocator::CheckBlocks()
|
||||||
{
|
{
|
||||||
for (std::list<Block>::iterator iter = blocks.begin(); iter != blocks.end(); iter++)
|
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);
|
u32 AllocAt(u32 position, u32 size, const char *tag = 0);
|
||||||
|
|
||||||
bool Free(u32 position);
|
bool Free(u32 position);
|
||||||
|
bool FreeExact(u32 position);
|
||||||
bool IsBlockFree(u32 position) {
|
bool IsBlockFree(u32 position) {
|
||||||
Block *b = GetBlockFromAddress(position);
|
Block *b = GetBlockFromAddress(position);
|
||||||
if (b)
|
if (b)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user