mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 13:30:02 +00:00
Net: Handle memory allocation better.
This commit is contained in:
parent
eeff56cdbf
commit
dfb10f197e
@ -21,6 +21,7 @@
|
||||
#include "Common/ChunkFile.h"
|
||||
#include "Core/HLE/HLE.h"
|
||||
#include "Core/HLE/FunctionWrappers.h"
|
||||
#include "Core/HLE/sceKernelMemory.h"
|
||||
#include "Core/MIPS/MIPS.h"
|
||||
#include "Core/Config.h"
|
||||
#include "Core/MemMapHelpers.h"
|
||||
@ -40,6 +41,9 @@ static bool netInetInited;
|
||||
static bool netApctlInited;
|
||||
u32 netDropRate = 0;
|
||||
u32 netDropDuration = 0;
|
||||
u32 netPoolAddr = 0;
|
||||
u32 netThread1Addr = 0;
|
||||
u32 netThread2Addr = 0;
|
||||
|
||||
static struct SceNetMallocStat netMallocStat;
|
||||
|
||||
@ -78,7 +82,7 @@ static void __UpdateApctlHandlers(int oldState, int newState, int flag, int erro
|
||||
|
||||
// This feels like a dubious proposition, mostly...
|
||||
void __NetDoState(PointerWrap &p) {
|
||||
auto s = p.Section("sceNet", 1, 2);
|
||||
auto s = p.Section("sceNet", 1, 3);
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
@ -94,6 +98,28 @@ void __NetDoState(PointerWrap &p) {
|
||||
p.Do(netDropRate);
|
||||
p.Do(netDropDuration);
|
||||
}
|
||||
if (s < 3) {
|
||||
netPoolAddr = 0;
|
||||
netThread1Addr = 0;
|
||||
netThread2Addr = 0;
|
||||
} else {
|
||||
p.Do(netPoolAddr);
|
||||
p.Do(netThread1Addr);
|
||||
p.Do(netThread2Addr);
|
||||
}
|
||||
}
|
||||
|
||||
static inline u32 AllocUser(u32 size, bool fromTop, const char *name) {
|
||||
u32 addr = userMemory.Alloc(size, true, "netstack1");
|
||||
if (addr == -1)
|
||||
return 0;
|
||||
return addr;
|
||||
}
|
||||
|
||||
static inline void FreeUser(u32 &addr) {
|
||||
if (addr != 0)
|
||||
userMemory.Free(addr);
|
||||
addr = 0;
|
||||
}
|
||||
|
||||
static u32 sceNetTerm() {
|
||||
@ -103,23 +129,55 @@ static u32 sceNetTerm() {
|
||||
|
||||
WARN_LOG(SCENET, "sceNetTerm()");
|
||||
netInited = false;
|
||||
FreeUser(netPoolAddr);
|
||||
FreeUser(netThread1Addr);
|
||||
FreeUser(netThread2Addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO: should that struct actually be initialized here?
|
||||
static u32 sceNetInit(u32 poolSize, u32 calloutPri, u32 calloutStack, u32 netinitPri, u32 netinitStack) {
|
||||
// May need to Terminate old one first since the game (ie. GTA:VCS) might not called sceNetTerm before the next sceNetInit and behave strangely
|
||||
if (netInited)
|
||||
static int sceNetInit(u32 poolSize, u32 calloutPri, u32 calloutStack, u32 netinitPri, u32 netinitStack) {
|
||||
// TODO: The correct behavior is actually to allocate more and leak the other threads/pool.
|
||||
// But we reset here for historic reasons (GTA:VCS potentially triggers this.)
|
||||
if (netInited)
|
||||
sceNetTerm();
|
||||
|
||||
if (poolSize == 0) {
|
||||
return hleLogError(SCENET, SCE_KERNEL_ERROR_ILLEGAL_MEMSIZE, "invalid pool size");
|
||||
} else if (calloutPri < 0x08 || calloutPri > 0x77) {
|
||||
return hleLogError(SCENET, SCE_KERNEL_ERROR_ILLEGAL_PRIORITY, "invalid callout thread priority");
|
||||
} else if (netinitPri < 0x08 || netinitPri > 0x77) {
|
||||
return hleLogError(SCENET, SCE_KERNEL_ERROR_ILLEGAL_PRIORITY, "invalid init thread priority");
|
||||
}
|
||||
|
||||
// TODO: Should also start the threads, probably? For now, let's just allocate.
|
||||
// TODO: Respect the stack size if firmware set to 1.50?
|
||||
u32 stackSize = 4096;
|
||||
netThread1Addr = AllocUser(stackSize, true, "netstack1");
|
||||
if (netThread1Addr == 0) {
|
||||
return hleLogError(SCENET, SCE_KERNEL_ERROR_NO_MEMORY, "unable to allocate thread");
|
||||
}
|
||||
netThread2Addr = AllocUser(stackSize, true, "netstack2");
|
||||
if (netThread2Addr == 0) {
|
||||
FreeUser(netThread1Addr);
|
||||
return hleLogError(SCENET, SCE_KERNEL_ERROR_NO_MEMORY, "unable to allocate thread");
|
||||
}
|
||||
|
||||
netPoolAddr = AllocUser(poolSize, false, "netpool");
|
||||
if (netPoolAddr == 0) {
|
||||
FreeUser(netThread1Addr);
|
||||
FreeUser(netThread2Addr);
|
||||
return hleLogError(SCENET, SCE_KERNEL_ERROR_NO_MEMORY, "unable to allocate pool");
|
||||
}
|
||||
|
||||
WARN_LOG(SCENET, "sceNetInit(poolsize=%d, calloutpri=%i, calloutstack=%d, netintrpri=%i, netintrstack=%d) at %08x", poolSize, calloutPri, calloutStack, netinitPri, netinitStack, currentMIPS->pc);
|
||||
netInited = true;
|
||||
netMallocStat.maximum = poolSize;
|
||||
netMallocStat.free = poolSize;
|
||||
netMallocStat.pool = 0;
|
||||
|
||||
return 0;
|
||||
return hleLogSuccessI(SCENET, 0);
|
||||
}
|
||||
|
||||
static u32 sceWlanGetEtherAddr(u32 addrAddr) {
|
||||
@ -468,7 +526,7 @@ static int sceNetSetDropRate(u32 dropRate, u32 dropDuration)
|
||||
}
|
||||
|
||||
const HLEFunction sceNet[] = {
|
||||
{0X39AF39A6, &WrapU_UUUUU<sceNetInit>, "sceNetInit", 'x', "xxxxx"},
|
||||
{0X39AF39A6, &WrapI_UUUUU<sceNetInit>, "sceNetInit", 'i', "xxxxx"},
|
||||
{0X281928A9, &WrapU_V<sceNetTerm>, "sceNetTerm", 'x', "" },
|
||||
{0X89360950, &WrapI_UU<sceNetEtherNtostr>, "sceNetEtherNtostr", 'i', "xx" },
|
||||
{0XD27961C9, &WrapI_UU<sceNetEtherStrton>, "sceNetEtherStrton", 'i', "xx" },
|
||||
|
@ -380,6 +380,7 @@ int main(int argc, const char* argv[])
|
||||
g_Config.bMemStickInserted = true;
|
||||
g_Config.bFragmentTestCache = true;
|
||||
g_Config.iAudioLatency = 1;
|
||||
g_Config.bEnableWlan = true;
|
||||
|
||||
#ifdef _WIN32
|
||||
g_Config.internalDataDirectory = "";
|
||||
|
Loading…
Reference in New Issue
Block a user