Skip to content

Commit

Permalink
Merge pull request #14513 from ANR2ME/adhoc
Browse files Browse the repository at this point in the history
[Adhoc] Reducing HLE delays due to Mutiplayer performance regressions
  • Loading branch information
hrydgard authored Jun 7, 2021
2 parents 66a52e7 + eda0e3e commit 084f97c
Showing 1 changed file with 29 additions and 29 deletions.
58 changes: 29 additions & 29 deletions Core/HLE/sceNetAdhoc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1526,7 +1526,7 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int
// Free Network Lock
//_freeNetworkLock();

hleEatMicro(1000); // Can be longer than 1ms tho
hleEatMicro(50); // Can be longer than 1ms tho
// Sent Data
if (sent >= 0) {
DEBUG_LOG(SCENET, "sceNetAdhocPdpSend[%i:%u]: Sent %u bytes to %s:%u\n", id, getLocalPort(pdpsocket.id), sent, ip2str(target.sin_addr).c_str(), ntohs(target.sin_port));
Expand All @@ -1537,7 +1537,7 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int

// Non-Blocking
if (flag)
return hleLogSuccessVerboseI(SCENET, ERROR_NET_ADHOC_WOULD_BLOCK, "would block");
return hleLogSuccessVerboseX(SCENET, ERROR_NET_ADHOC_WOULD_BLOCK, "would block");

// Does PDP can Timeout? There is no concept of Timeout when sending UDP due to no ACK, but might happen if the socket buffer is full, not sure about PDP since some games did use the timeout arg
return hleLogDebug(SCENET, ERROR_NET_ADHOC_TIMEOUT, "timeout?"); // ERROR_NET_ADHOC_INVALID_ADDR;
Expand Down Expand Up @@ -1618,7 +1618,7 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int
// Free Network Lock
//_freeNetworkLock();

hleEatMicro(1000);
hleEatMicro(50);
// Success, Broadcast never fails!
return 0; // len;
}
Expand Down Expand Up @@ -1761,7 +1761,7 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void *
// Free Network Lock
//_freeNetworkLock();

return hleLogSuccessVerboseI(SCENET, ERROR_NET_ADHOC_NOT_ENOUGH_SPACE, "not enough space"); //received;
return hleLogSuccessVerboseX(SCENET, ERROR_NET_ADHOC_NOT_ENOUGH_SPACE, "not enough space"); //received;
}
sinlen = sizeof(sin);
memset(&sin, 0, sinlen);
Expand All @@ -1776,10 +1776,10 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void *
return WaitBlockingAdhocSocket(threadSocketId, PDP_RECV, id, buf, len, timeout, saddr, sport, "pdp recv");
}

return hleLogSuccessVerboseI(SCENET, ERROR_NET_ADHOC_WOULD_BLOCK, "would block");
return hleLogSuccessVerboseX(SCENET, ERROR_NET_ADHOC_WOULD_BLOCK, "would block");
}

hleEatMicro(1000);
hleEatMicro(50);
// Received Data. UDP can also receives 0 data, while on TCP 0 data = connection gracefully closed, but not sure about PDP tho
if (received >= 0) {
DEBUG_LOG(SCENET, "sceNetAdhocPdpRecv[%i:%u]: Received %u bytes from %s:%u\n", id, getLocalPort(pdpsocket.id), received, ip2str(sin.sin_addr).c_str(), ntohs(sin.sin_port));
Expand Down Expand Up @@ -2024,7 +2024,7 @@ int sceNetAdhocPollSocket(u32 socketStructAddr, int count, int timeout, int nonb
}
}
// Workaround to get 30 FPS instead of the too fast 60 FPS on Fate Unlimited Codes, it's abit absurd for a non-blocking call to have this much delay tho, and hleDelayResult doesn't works as good as hleEatMicro for this workaround.
hleEatMicro(1000); // hleEatMicro(7500); // normally 1ms, but using 7.5ms here seems to show better result for Bleach Heat the Soul 7 and other games with too high FPS, but may have a risk of slowing down games that already runs at normal FPS? (need more games to test this)
hleEatMicro(50); // hleEatMicro(7500); // normally 1ms, but using 7.5ms here seems to show better result for Bleach Heat the Soul 7 and other games with too high FPS, but may have a risk of slowing down games that already runs at normal FPS? (need more games to test this)
return hleLogDebug(SCENET, affectedsockets, "success");
}
//else if (nonblock && affectedsockets < 0)
Expand Down Expand Up @@ -2268,7 +2268,7 @@ int sceNetAdhocctlGetScanInfo(u32 sizeAddr, u32 bufAddr) {
// Multithreading Unlock
peerlock.unlock();

hleEatMicro(2000);
hleEatMicro(200);
// Return Success
return 0;
}
Expand Down Expand Up @@ -3090,7 +3090,7 @@ static int sceNetAdhocGetPtpStat(u32 structSize, u32 structAddr) {
// Update Buffer Length
*buflen = i * sizeof(SceNetAdhocPtpStat);

hleEatMicro(1000); // Not sure how long it takes, since GetPtpStat didn't get logged when using prx files on JPCSP
hleEatMicro(50); // Not sure how long it takes, since GetPtpStat didn't get logged when using prx files on JPCSP
// Success
return 0;
}
Expand Down Expand Up @@ -3431,7 +3431,7 @@ static int sceNetAdhocPtpAccept(int id, u32 peerMacAddrPtr, u32 peerPortPtr, int

// Listener Socket
if (ptpsocket.state == ADHOC_PTP_STATE_LISTEN) {
hleEatMicro(500);
hleEatMicro(50);
// Address Information
struct sockaddr_in peeraddr;
memset(&peeraddr, 0, sizeof(peeraddr));
Expand Down Expand Up @@ -3467,26 +3467,26 @@ static int sceNetAdhocPtpAccept(int id, u32 peerMacAddrPtr, u32 peerPortPtr, int

// Action would block
if (flag)
return hleLogSuccessVerboseI(SCENET, ERROR_NET_ADHOC_WOULD_BLOCK, "would block");
return hleLogSuccessVerboseX(SCENET, ERROR_NET_ADHOC_WOULD_BLOCK, "would block");

// Timeout
return hleLogSuccessVerboseI(SCENET, ERROR_NET_ADHOC_TIMEOUT, "timeout");
return hleLogSuccessVerboseX(SCENET, ERROR_NET_ADHOC_TIMEOUT, "timeout");
}

// Client Socket
return hleLogSuccessVerboseI(SCENET, ERROR_NET_ADHOC_NOT_LISTENED, "not listened");
return hleLogSuccessVerboseX(SCENET, ERROR_NET_ADHOC_NOT_LISTENED, "not listened");
}

// Invalid Socket
return hleLogSuccessVerboseI(SCENET, ERROR_NET_ADHOC_INVALID_SOCKET_ID, "invalid socket id");
return hleLogSuccessVerboseX(SCENET, ERROR_NET_ADHOC_INVALID_SOCKET_ID, "invalid socket id");
}

// Invalid Arguments
return hleLogSuccessVerboseI(SCENET, ERROR_NET_ADHOC_INVALID_ARG, "invalid arg");
return hleLogSuccessVerboseX(SCENET, ERROR_NET_ADHOC_INVALID_ARG, "invalid arg");
}

// Library is uninitialized
return hleLogSuccessVerboseI(SCENET, ERROR_NET_ADHOC_NOT_INITIALIZED, "not initialized");
return hleLogSuccessVerboseX(SCENET, ERROR_NET_ADHOC_NOT_INITIALIZED, "not initialized");
}

int NetAdhocPtp_Connect(int id, int timeout, int flag, bool allowForcedConnect) {
Expand All @@ -3512,7 +3512,7 @@ int NetAdhocPtp_Connect(int id, int timeout, int flag, bool allowForcedConnect)

// Valid Client Socket
if (ptpsocket.state == ADHOC_PTP_STATE_CLOSED || ptpsocket.state == ADHOC_PTP_STATE_SYN_SENT) {
hleEatMicro(500);
hleEatMicro(50);
// Target Address
struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
Expand Down Expand Up @@ -3894,7 +3894,7 @@ static int sceNetAdhocPtpSend(int id, u32 dataAddr, u32 dataSizeAddr, int timeou

// Success
if (sent > 0) {
hleEatMicro(1000); // mostly 1ms, sometimes 1~10ms ? doesn't seems to be switching to a different thread during this duration
hleEatMicro(50); // mostly 1ms, sometimes 1~10ms ? doesn't seems to be switching to a different thread during this duration
// Save Length
*len = sent;

Expand All @@ -3912,7 +3912,7 @@ static int sceNetAdhocPtpSend(int id, u32 dataAddr, u32 dataSizeAddr, int timeou
else if (sent == SOCKET_ERROR && (error == EAGAIN || error == EWOULDBLOCK || (ptpsocket.state == ADHOC_PTP_STATE_SYN_SENT && (error == ENOTCONN || connectInProgress(error))))) {
// Non-Blocking
if (flag)
return hleLogSuccessVerboseI(SCENET, ERROR_NET_ADHOC_WOULD_BLOCK, "would block");
return hleLogSuccessVerboseX(SCENET, ERROR_NET_ADHOC_WOULD_BLOCK, "would block");

// Simulate blocking behaviour with non-blocking socket
u64 threadSocketId = ((u64)__KernelGetCurThread()) << 32 | ptpsocket.id;
Expand Down Expand Up @@ -4001,13 +4001,13 @@ static int sceNetAdhocPtpRecv(int id, u32 dataAddr, u32 dataSizeAddr, int timeou
return WaitBlockingAdhocSocket(threadSocketId, PTP_RECV, id, buf, len, timeout, nullptr, nullptr, "ptp recv");
}

return hleLogSuccessVerboseI(SCENET, ERROR_NET_ADHOC_WOULD_BLOCK, "would block");
return hleLogSuccessVerboseX(SCENET, ERROR_NET_ADHOC_WOULD_BLOCK, "would block");
}

// Free Network Lock
// _freeNetworkLock();

hleEatMicro(1000);
hleEatMicro(50);

// Received Data
if (received > 0) {
Expand Down Expand Up @@ -4103,7 +4103,7 @@ static int sceNetAdhocPtpFlush(int id, int timeout, int nonblock) {

// Connected Socket
if (ptpsocket.state == ADHOC_PTP_STATE_ESTABLISHED) {
hleEatMicro(1000);
hleEatMicro(50);
// There are two ways to flush, you can either set TCP_NODELAY to 1 or TCP_CORK to 0.
// Apply Send Timeout Settings to Socket
setSockTimeout(ptpsocket.id, SO_SNDTIMEO, timeout);
Expand All @@ -4113,7 +4113,7 @@ static int sceNetAdhocPtpFlush(int id, int timeout, int nonblock) {
if (error == EAGAIN || error == EWOULDBLOCK) {
// Non-Blocking
if (nonblock)
return hleLogSuccessVerboseI(SCENET, ERROR_NET_ADHOC_WOULD_BLOCK, "would block");
return hleLogSuccessVerboseX(SCENET, ERROR_NET_ADHOC_WOULD_BLOCK, "would block");

// Simulate blocking behaviour with non-blocking socket
u64 threadSocketId = ((u64)__KernelGetCurThread()) << 32 | ptpsocket.id;
Expand Down Expand Up @@ -4264,7 +4264,7 @@ static int sceNetAdhocGameModeUpdateMaster() {
gma.dataSent = 0;
}

hleEatMicro(1000);
hleEatMicro(100);
return 0;
}

Expand Down Expand Up @@ -4329,7 +4329,7 @@ static int sceNetAdhocGameModeUpdateReplica(int id, u32 infoAddr) {
}
}

hleEatMicro(1000);
hleEatMicro(100);
return 0;
}

Expand Down Expand Up @@ -5297,7 +5297,7 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf)
}

// Return Success
return hleDelayResult(0, "delay 1 ~ 10ms", 1000); // seems to have different thread running within the delay duration
return hleDelayResult(0, "delay 100 ~ 1000us", 100); // seems to have different thread running within the delay duration
}

// Gran Turismo may replace the 1st bit of the 1st byte of MAC address's OUI with 0 (unicast bit), or replace the whole 6-bytes of MAC address with all 00 (invalid mac) for unknown reason
Expand Down Expand Up @@ -5684,7 +5684,7 @@ static int sceNetAdhocctlGetGameModeInfo(u32 infoAddr) {
break;
}

hleEatMicro(1000);
hleEatMicro(100);
return 0;
}

Expand Down Expand Up @@ -5771,7 +5771,7 @@ static int sceNetAdhocctlGetPeerList(u32 sizeAddr, u32 bufAddr) {
peerlock.unlock();

// Return Success
return hleDelayResult(0, "delay 1 ~ 10ms", 1000); // seems to have different thread running within the delay duration
return hleDelayResult(0, "delay 100 ~ 1000us", 100); // seems to have different thread running within the delay duration
}

// Invalid Arguments
Expand Down Expand Up @@ -5888,7 +5888,7 @@ static int sceNetAdhocctlGetAddrByName(const char *nickName, u32 sizeAddr, u32 b
peerlock.unlock();

// Return Success
return hleLogDebug(SCENET, hleDelayResult(0, "delay 1 ~ 10ms", 1000), "success"); // FIXME: Might have similar delay with GetPeerList? need to know which games using this tho
return hleLogDebug(SCENET, hleDelayResult(0, "delay 100 ~ 1000us", 100), "success"); // FIXME: Might have similar delay with GetPeerList? need to know which games using this tho
}

// Invalid Arguments
Expand Down

0 comments on commit 084f97c

Please sign in to comment.