From 6079a8264f18e0f4ff8bd6a256fb493b6f7d3c8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 31 Oct 2026 12:01:20 +0100 Subject: [PATCH] sceNetAdhoc: Relay without fixed real-time waits aemu_postoffice is now at upstream main, which has the relay performance fixes: the built-in relay server waits for traffic and pumps as soon as it arrives instead of sleeping 1 ms between pumps, and pumps on its own thread instead of waking three workers twice each per pump; closing a session no longer sleeps 50 ms (the delay is now an option, 0 here, where everything but a PTP connect's thread, which is joined before its session closes, runs on the CPU thread); connects and blocking waits for the server's replies wait on the socket instead of sleeping or spinning. Unread PTP data is also delivered before a close now. The pair tests through the relay used to barely gain from speed (29 s at 600%, 22 s at 1600%); now 19 s and 11 s, as fast as P2P at 600%. Co-Authored-By: Claude Opus 5.5 --- Core/HLE/sceNetAdhoc.cpp | 16 ++++++++++------ ext/aemu_postoffice | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 9fd16d1292..c7ec7aa299 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -1442,6 +1442,10 @@ static void SetupAdhocRelayMode() { netAdhocRelayModeEnetPdpReliable = g_Config.bAdhocRelayModeEnetPdpReliable; init_aemu_postoffice(netAdhocUseUdp); + // Closing a session normally first sleeps 50 ms, in case another thread is about to use it. Here + // everything but a PTP connect's own thread runs on the CPU thread, and that thread is joined + // before its session is closed. + set_close_delay_aemu_postoffice(0); if (netAdhocUseUdp) { aemuPostofficeEnetPumping = true; @@ -1735,8 +1739,9 @@ void __NetAdhocInit() { * from ppsspp's adhocctl server */ config.strict_mode = false; - // One worker per pool is plenty for a server that sees a handful of players. - config.num_threads = 1; + // No worker threads: for a server that sees a handful of players, pumping on this thread + // beats waking workers several times per pump. + config.num_threads = 0; // The port the relay client connects to. config.port = AEMU_POSTOFFICE_PORT; @@ -1752,14 +1757,13 @@ void __NetAdhocInit() { INFO_LOG(Log::sceNet, "RelayServer: Listening for Connections on TCP Port %u", config.port); while (adhocServerRunning) { - auto start = std::chrono::steady_clock::now(); auto pump_status = relay_server.pump(); if (pump_status == aemu_postoffice_server::ServerPumpStatus::LISTEN_SOCK_DEAD) { break; } - // Every hop through the relay waits for the next pump, so keep them close together. Idle - // (nobody connected) too, since that's when a game's first connection comes in. - std::this_thread::sleep_until(start + std::chrono::milliseconds(1)); + // Pump again as soon as something arrives, so a message is relayed at once. The timeout + // only bounds how long it takes to notice adhocServerRunning going false. + relay_server.wait(10); } INFO_LOG(Log::sceNet, "RelayServer: Shutdown complete"); diff --git a/ext/aemu_postoffice b/ext/aemu_postoffice index 6c18042403..663788ca63 160000 --- a/ext/aemu_postoffice +++ b/ext/aemu_postoffice @@ -1 +1 @@ -Subproject commit 6c1804240370148669e916c4377fbcd863b98382 +Subproject commit 663788ca63195b40796b5c818328398e4da89799