Commit Graph
318 Commits
Author SHA1 Message Date
Henrik RydgårdandClaude Opus 5.5 63e661baf3 test.py: Run the single-console ad hoc tests at 800%
Their first login to the server they start takes real time, a few hundred
ms on the Windows runner, and a group request gives up after 5 emulated
seconds: at 1600% every P2P one failed to create its group there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 10:10:52 +01:00
Henrik RydgårdandClaude Opus 5.5 32070e633c test.py: Skip relay pair/vanish on macOS CI for now
Only there, the host's matching drops the departed client without a
TIMEOUT event. The instances stay in step (no sync warnings in the log),
and it passes on a Mac and on the other runners.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:37:32 +01:00
Henrik RydgårdandClaude Opus 5.5 ec7064e40b test.py: Run the relay ad hoc tests at 800%
Every hop through the relay waits a millisecond or so of real time, which
the speed multiplies: at 1600% on macOS CI a relay PTP receive in
pair/ptppoll timed out. Relay mode hardly gains above 800% anyway (26 s
against 22 s locally); P2P stays at 1600%.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:17:04 +01:00
Henrik RydgårdandClaude Opus 5.5 00382b2e6b test.py: Run the ad hoc tests at 1600%, and pair/vanish in P2P again
With the instances in step, a busy runner no longer pulls them apart.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:04:00 +01:00
Henrik RydgårdandClaude Opus 5.5 841902950a proAdhocServer: Wait for logins and messages with select instead of polling
- Fixes #19248

The server loop polled every socket and slept 10 ms, so it woke 100
times a second with nothing to do, and every message could wait up to
10 ms of real time before it was handled, which at a sped-up emulation
speed is many times that in game time. It now waits in select() on the
listening socket and every user, and wakes at least every 50 ms to notice
being stopped. It also no longer stops serving everyone while the hosting
instance is paused in the debugger.

pspautotests: pair/discover and pair/ptpmsg.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 08:08:20 +01:00
Henrik RydgårdandClaude Opus 5.5 4221c4cd54 sceNetAdhoc: Receive PDP through a queue of the socket's buffer size
A PSP keeps what arrives in the socket's buffer, of the size given to
PdpCreate, and drops a datagram that doesn't fit: a buffer of 0 gets
nothing, one of 2048 bytes only some of ten 1000-byte datagrams
(pspautotests net/adhoc/pair/flow). Each transport now only hands over
the datagrams that have arrived (PdpTakeDatagram), into a queue per
socket that is filled every millisecond and whenever the game looks, and
PdpRecv, its blocking retry, GetPdpStat, PollSocket and game mode read
from that. This replaces each transport's own receive paths, so the
relay now reports the sender with NOT_ENOUGH_SPACE too, and P2P's
blocking receive no longer misreads a stale errno.

A datagram to ourselves goes straight into our own socket's queue, as on
a PSP, so it's there at once through the relay too (net/adhoc/term).

Also from comparing the transports:
- P2P: a blocking Accept of a connection from outside the group keeps
  waiting instead of returning -1.
- Relay: an accepted socket gets an id of its own, not its listener's,
  which blocking calls are told apart by.
- ALERT in PollSocket comes from the socket in both transports.
- No send/receive timeouts are set on the game's sockets: all host
  sockets are non-blocking, and in relay mode the ids aren't host
  sockets at all.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 08:05:38 +01:00
Henrik RydgårdandClaude Opus 5.5 02db3f1be4 test.py: Skip pair/vanish in P2P mode for now
It times the socket failures from when the peer drops off the peer list,
which the ad hoc server updates in wall time, so on macOS CI at 600% the
failure lands under a second after it instead of 1-2s. The relay run
still covers it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 07:17:43 +01:00
Henrik RydgårdandClaude Opus 5.5 670b667ed1 test.py: Run the ad hoc tests at 600% on CI
Each instance runs on its own, so on a busy runner they drift apart in
emulated time, and a real second's lag is 8 emulated seconds at 800%:
long enough for pairSync (10 s) to give up on macOS CI. ADHOC_SPEED
still overrides it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 01:49:58 +01:00
Henrik RydgårdandClaude Opus 5.5 978eb5bafe sceNetAdhoc: Check a pending P2P connect the way Winsock reports a failure
Winsock never makes a socket whose connect failed writable; the failure
shows in select's exception set, with the reason in SO_ERROR. The poll
now checks both, and SO_ERROR on a writable socket too, which is where
other systems put a refusal.

Windows still retries a refused connect for about a second before
reporting it, far longer than a PSP at the tests' 800% speed, so
pair/basic is a known P2P failure on Windows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 00:48:11 +01:00
Henrik RydgårdandClaude Opus 5.5 80d9952861 pspautotests: pdp and ptp cover a late too-big datagram and closing while connecting
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 00:44:36 +01:00
Henrik RydgårdandClaude Opus 5.5 321a440884 test.py: Run the single-console ad hoc tests in relay mode too, and basic in CI
Like the two-console tests, each runs through the built-in server's relay
and in P2P, with adhoc_known_failures for the ones that fail in one mode.
pair/basic passes in P2P now and moves to tests_good, a known failure
through the relay.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 00:44:36 +01:00
Henrik RydgårdandClaude Opus 5.5 f988ab9566 sceNetAdhoc: A relay listener accepts connections into its backlog by itself
A PSP completes a connect to a listener without the game calling Accept,
so an opened PTP connection is up a few ms after PtpOpen (pspautotests
net/adhoc/pair/ptppoll). The relay only answers the connecting side once
the listening side accepts, so the relay transport now accepts pending
connections into a queue as long as the listener's backlog, from a new
per-millisecond AdhocTransport::Poll() and from polls and accepts, and
PtpAccept takes them from there. A poll reports ACCEPT while the queue
isn't empty.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 00:44:36 +01:00
Henrik RydgårdandClaude Opus 5.5 7f094cbf45 sceNetAdhoc: P2P mode handles leaving the network like the relay mode
Out of the group, a PSP's sends reach nobody and nothing reaches it, and
a PTP connection to a peer that has left fails once its retransmits would
have run out. Only the relay transport did this; the P2P one kept sending
over the host's sockets, so neither side ever noticed the other was gone
(pspautotests net/adhoc/pair/vanish).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 00:44:36 +01:00
Henrik RydgårdandClaude Opus 5.5 d3a7e13541 test.py: Name the backend split --skip-cpu-independent, and add --only-cpu-independent
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 00:44:36 +01:00
Henrik RydgårdandClaude Opus 5.5 4a01b6644d test.py: Run the networking tests with one CPU backend in CI
--cpu-backend-only leaves out the tests that don't depend on the CPU
backend (net/ for now, the two-console ones taking about 40 s of a 60 s
run). The Linux CI jobs run everything with the JIT and pass it for
jit-ir, ir and the interpreter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 00:44:36 +01:00
Henrik RydgårdandClaude Opus 5.5 074b6bf547 test.py: Run the two-console ad hoc tests in relay and P2P mode, and in CI
The pair tests that pass go in tests_good, and each runs twice: through
the built-in server's relay and P2P. pair_known_failures lists the ones
that fail in only one mode. A P2P test that needs a loopback address
the machine lacks (macOS has only 127.0.0.1) is skipped with a warning,
and the run fails at the end with the command that adds it. The macOS
CI runners add 127.0.0.2. Each run gets a random port offset.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 00:44:36 +01:00
Henrik RydgårdandClaude Opus 5.5 1437c15f52 sceNetApctl: Fail GetState before Init, let GetLocalEtherAddr work in infrastructure mode
- Fixes #22857

PES 2009 calls sceNetApctlGetState first and only calls sceNetApctlInit
when it fails with 0x80410a0d. We returned success, so Init was never
called, apctl's state never advanced and the Netconf dialog waited on
"Connecting to the access point" forever. A PSP returns 0x80410a0d before
Init and after Term (pspautotests net/adhoc/apctlinit).

After that the game polls sceNetGetLocalEtherAddr until it succeeds, which
we only allowed in ad hoc mode. Also allow it once apctl has connected. It
still fails with apctl initialized but not connected, as the test shows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 23:50:28 +01:00
Henrik Rydgård 36b6db5458 Merge pull request #22851 from hrydgard/adhoc-9-fixes
Ad hoc 9/9: Fixes from playing games, and 8x faster ad hoc tests
2026-10-30 13:09:06 +01:00
Henrik RydgårdandClaude Opus 5.5 c1058fd589 sceNetAdhoc: Disconnect is BUSY until a Create or Connect has connected
As on a PSP (pspautotests net/adhoc/abandon): the Disconnect fails and
the join goes on to CONNECT. Before, it was accepted, and the join's late
answer from the server could still connect us afterwards.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 12:04:33 +01:00
Henrik RydgårdandClaude Opus 5.5 d12e19ed35 test.py: Keep the ad hoc tests' ports below Linux's ephemeral ports
With offsets of up to 30000, a port net/adhoc/limits listened on could
be one an outgoing connection was using, and the listen failed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 11:53:44 +01:00
Henrik RydgårdandClaude Opus 5.5 c52f8c9657 Headless: --speed and --port-offset, and run the ad hoc tests at 8x
--speed=PERCENT runs a --realtime headless at an alternate speed (speed
control while connected is allowed for it), and pacing follows it. The
ad hoc tests now run at 800%, which takes their part of test.py -g from
about 71 s to 12 s; only local network round trips stay real time.

test.py also gives each ad hoc test run its own --port-offset: a
connection the previous run made with the same ports is still in TCP
TIME_WAIT, and connecting again failed with EADDRINUSE once runs came
close together.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 10:15:35 +01:00
Henrik RydgårdandClaude Opus 5.5 b707ff4306 test.py: Update the reasons for poll and ptp
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 10:15:35 +01:00
Henrik RydgårdandClaude Opus 5.5 8912d956ff test.py: Run the passing single-console ad hoc tests with the good ones
alerts, discover, gamemode, limits, loopback, self, socketids and term
pass, so they move to tests_good. They run in real time against the
built-in server, about 71 s together. The ad hoc tests left in
tests_next say why they don't pass yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 10:15:35 +01:00
Henrik RydgårdandClaude Opus 5.5 6b14884e26 sceNetAdhoc: sceNetAdhocTerm leaves adhocctl and the group alone
A PSP stays in its group through sceNetAdhocTerm and sceNetAdhocInit,
and matching keeps working; only the sockets go, and calls on them
return NOT_INITIALIZED until the next init (net/adhoc/term, recorded on
a PSP). We also terminated adhocctl, so a game that restarts the adhoc
library inside a group found itself disconnected. Every other caller
already terminates adhocctl itself first.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 10:15:35 +01:00
Henrik RydgårdandClaude Opus 5.5 a8a63fa11d sceNetAdhoc: Start socket IDs over at 1 after sceNetAdhocTerm
A PSP hands out socket IDs from 1 again after sceNetAdhocTerm and
sceNetAdhocInit (net/adhoc/socketids, recorded on a PSP). We kept
counting up. Pangya: Fantasy Golf tears down the network between its
room and the round, and then keeps using socket 1 without looking at
what PdpCreate returned, so every send and receive failed with
INVALID_SOCKET_ID and each player saw the other as "Off-line".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 10:15:35 +01:00
Henrik RydgårdandClaude Opus 5.5 d0d6f0f61b sceNetAdhocMatching: A child lists its parent first after a keepalive
- Fixes #22331

A child's GetMembers starts with itself, then switches to the parent
first one keepalive interval after it was accepted
(net/adhoc/pair/matchingorder, recorded on two PSPs). We kept it self
first. Bomberman's client checks that the first member is the host
before it marks itself ready, so its lobby stayed empty and the host's
start failed with "failed to connect to the game".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 10:15:14 +01:00
Henrik RydgårdandClaude Opus 5.5 c3defa2e0f sceMd5: Keep the MD5/SHA-1 contexts 4-aligned, fixing a bus error on ARM32
The u64 total length made both context structs 8-aligned, while the
game's context only has to be 4-aligned (hash/hash puts it in a char
array). On ARM32, GCC then copies buf with vld1.64 [:64], which faults
on such an address - on hardware too, not just under qemu as the
known-failures entry assumed. Store the length as two words; the layout
is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 09:28:42 +01:00
Henrik RydgårdandClaude Opus 5.5 559b4e404b test.py: Add net/adhoc/ctlinit to tests_next
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 22:39:07 +01:00
Henrik RydgårdandClaude Opus 5.5 d5503978e7 Interrupts: Check whether a sub-interrupt is enabled when its turn comes
All the enabled sub-interrupt handlers were queued when the interrupt fired,
so a handler disabled by an earlier one in the same VBLANK still ran, and one
an earlier handler enabled waited for the next VBLANK. The PSP checks each
handler as it gets to it (intr/disablepending): skip a disabled one, and
queue a newly enabled one if it comes after the handler that's running.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 08:58:33 +01:00
Henrik RydgårdandClaude Opus 5.5 fe6cfb6c77 Test: intr/releaseself, a subinterrupt handler releasing itself
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 08:22:19 +01:00
Henrik Rydgård 7aecf86c4d Merge pull request #22830 from hrydgard/inet-8-stack
sceNetInet: The firmware's stack check, and GetPspError as it computes it
2026-10-28 19:00:09 +01:00
Henrik RydgårdandClaude Opus 5.5 129e3b7312 test.py: Run the two-console tests, and give the ad hoc tests a server
The pair tests (net/adhoc/pair) run on two headless instances through
Tools/adhoc_multi.py and the host's built-in relay. They're all in
tests_next for now. The single-console ad hoc tests get the built-in
server and real-time speed, which they need to get past creating a
group, with a timeout to match.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 14:48:47 +01:00
Henrik RydgårdandClaude Opus 5.5 fdbce5fbf2 sceNetInet: The firmware's stack check, and GetPspError as it computes it
Every export of pspnet_inet.prx but the address conversions starts with
sceKernelCheckThreadStack(), and fails without doing anything if the
thread has less than 0x1000 bytes of stack free (0xFE0 for socket()):
the socket calls with -1, without setting errno, and Init, Term,
GetErrno, GetPspError and SocketAbort with 0x80410005. Each function's
limit plus its own stack frame comes to that. pspautotests
net/inet/errnothread shows it on a thread with a 4 KB stack.

GetPspError is 0x80010000 | errno, and 0 for no error, rather than a
table of guesses, so 0x80010001 on a thread with no errno record yet
(net/inet/errnothread).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 13:41:44 +01:00
Henrik RydgårdandClaude Opus 5.5 3ee22fbd3d sceNetInet: TCP socket states and bind's port sharing
Following pspautotests net/inet/errors, states and reuse:
- bind decides itself whether a port is in use, as 4.4BSD's in_pcbbind()
  does with SO_REUSEADDR and SO_REUSEPORT. The host can't, since its
  sockets have both on for running several instances, so any number of
  sockets could bind the same port. A socket that's bound already is
  EINVAL.
- Shutting down the sending side of an unconnected TCP socket, or a
  failed connect, throws away its TCP state as in 4.4BSD's tcp_usrreq(),
  after which bind, listen, connect, accept and shutdown fail with
  EINVAL, and its port is free again. shutdown otherwise only fails for
  a bad how, and still reaches the host, so a thread waiting in accept
  wakes up.
- listen on an unbound TCP socket binds one, which Winsock didn't, and on
  a connected one succeeds.
- connect on a listening socket is EOPNOTSUPP. Winsock's WSAEINVAL for
  it looked like a connect in progress, and a blocking socket waited
  forever. A second connect on a loopback connection the host hasn't
  noticed finishing is EISCONN once it has.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 13:09:28 +01:00
Henrik RydgårdandClaude Opus 5.5 d76e1a4496 sceNetInet: Recvmsg, Sendmsg rewritten, and sendto without an address
Recvmsg was a stub that failed without setting errno. It now receives
like recvfrom, scattering into the buffers and waiting like the other
blocking calls. Sendmsg is rewritten around the same msghdr reading.
Following pspautotests net/inet/msg:
- Recvmsg truncates the address to namelen, gives TCP none and a namelen
  of 0, sets MSG_TRUNC in msg_flags, and controllen to 0.
- Sendmsg with no buffers sends an empty datagram, which macOS failed.
- sendto without an address works on a connected socket. Linux failed
  it, given an address of length 0.

On Windows, Sendmsg uses WSASendTo, since WSASendMsg only takes
datagram sockets, and Recvmsg WSARecvFrom.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 12:25:39 +01:00
Henrik RydgårdandClaude Opus 5.5 759c9e590a sceNetInet: Poll and select as on hardware, and host sockets past FD_SETSIZE
Following pspautotests net/inet/polledge:
- poll reports only what was asked for, and never POLLHUP or POLLERR,
  even for a peer that closed or reset the connection.
- select with a closed descriptor in a set fails with EBADF and leaves
  the sets alone. It used to skip it.

The host side now uses poll() outside Windows, where select() can't take
a descriptor numbered FD_SETSIZE or above and FD_SET wrote past the
fd_set. macOS reports a peer that closed as POLLHUP with POLLPRI, and
the POLLPRI is ignored, as its select() shows nothing for it. Winsock's
select() has no such limit, but takes only 64 sockets a set, so it's
called on groups of 64, and poll is no longer cut short at 64 entries
there. A failing poll sets the host's errno rather than EINTR.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 11:37:32 +01:00
Henrik RydgårdandClaude Opus 5.5 59e9d889e1 sceNetInet: Socket options as the PSP keeps them
The PSP's getsockopt and setsockopt work like 4.4BSD's, which
pspautotests net/inet/options records in detail, and most of it didn't
match: flags read back as their bit (SO_REUSEADDR as 4, SO_NBIO as
0x80), buffer sizes have their own defaults, getsockopt copies as much
as fits and says how much, and unknown options and levels fail with
ENOPROTOOPT and EINVAL.

So the socket-level options are now kept in InetSocket, and only the
ones that change what the host socket does are passed on to it. That
also stops the timeouts reaching the host, where Winsock read the
timeval as a millisecond count. Accepted sockets copy their options from
the listener, like BSD's sonewconn(). IP_TTL is kept too, as Windows'
default is 128 and the PSP's 64.

Timeouts are set in microseconds, but kept in 10 ms clock ticks, and
one under a tick is no timeout at all (net/inet/limits). Buffers can be
up to 233016 bytes (net/inet/limits), 4.4BSD's limit with 256-byte
mbufs, where we allowed 8 MB. SO_ERROR reads as an SCE error code rather
than an errno (net/inet/tcp).

The host's TCP send buffer is capped at 64 KB, closer to the PSP's.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 10:59:24 +01:00
Henrik RydgårdandClaude Opus 5.5 0a86a248da sceNetInet: Addresses in and out like the PSP
- accept and recvfrom write only as much of the address as its length
  allows, and set the length to that (pspautotests net/inet/udp and
  tcp). They wrote all 16 bytes and set it to 16. They now also give the
  host an address of their own, so one the game passes without a length
  can't make the host fail the call with EFAULT.
- InetAton and InetAddr take the forms 4.4BSD's inet_aton() does
  ("1.2.3", "16909060", "0x7f.1", octal with a leading zero), which the
  host's inet_pton() didn't. InetPton takes only a plain dotted quad,
  and only AF_INET. All three stop at a space. InetNtop returns NULL with
  ENOSPC when the string doesn't fit, leaving the buffer alone, and with
  EAFNOSUPPORT for other families (net/inet/addr).
- getpeername after the peer closed is ENOTCONN rather than macOS's
  EINVAL, as 4.4BSD checks for a connection first (net/inet/errors).

Coded Arms Contagion calls InetNtop with a 4-byte buffer, which now gets
NULL, as on hardware.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 10:29:23 +01:00
Henrik RydgårdandClaude Opus 5.5 79537d18bd sceNetInet: errno per thread as on hardware, and the socket table
errno:
- A thread that hasn't made a call yet reads 0x80410001 from GetErrno,
  as the PSP has no errno record for it until then. errno is saved in
  savestates now, in a new sceNet section version.
- socket(), close() and setsockopt() clear it when they succeed.
- Running out of descriptors is EMFILE, at 255 like the PSP, and an
  unconnected UDP socket sending without an address EDESTADDRREQ, which
  Winsock calls ENOTCONN.
- On Windows, ENOBUFS, EPROTOTYPE, ENOPROTOOPT, EMSGSIZE, ENETRESET and
  EDESTADDRREQ now map to the PSP's errnos. They only did elsewhere.
All from pspautotests net/inet/errors, options and errnothread.

The socket table:
- Descriptor numbers are handed out round-robin up to 255, as on the PSP
  (net/inet/states), rather than the lowest free one.
- Closing frees the slot even if the host's close fails, and Close and
  CloseAll take the lock the rest of SocketManager does.
- accept no longer leaks the host socket when it runs out of numbers.
- bind no longer asks UPnP to forward port 0, and closing the socket
  removes its forward, unless another socket still uses the port.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 09:50:48 +01:00
Henrik Rydgård 5c84203bbe Merge pull request #22512 from hrydgard/inet-select-wait
sceNetInet: Wait in emulated time instead of blocking the host
2026-10-27 22:17:24 +01:00
Henrik RydgårdandClaude Opus 5.5 475e548878 Add the net/inet/offline pspautotest to tests_next
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:13:45 +01:00
Henrik RydgårdandClaude Opus 5.5 1d9cccb877 Add the net/adhoc/alerts and net/inet/stats pspautotests to tests_next
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:13:45 +01:00
Henrik RydgårdandClaude Opus 5.5 5629c233e0 Add the new net/inet and net/adhoc/limits pspautotests to tests_next
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:13:45 +01:00
Henrik RydgårdandClaude Opus 5.5 78151eadca Add the net/adhoc discover and loopback pspautotests to tests_next
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:13:45 +01:00
Henrik RydgårdandClaude Opus 5.5 54df259d6e Add the remaining single-console net/adhoc pspautotests to tests_next
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:13:45 +01:00
Henrik RydgårdandClaude Opus 5.5 5fd1afffd8 Add the net/adhoc pspautotests to tests_next
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:13:45 +01:00
Henrik RydgårdandClaude Opus 5.5 22e0a1a536 sceNetInet: Wait for blocking socket calls in emulated time
Host sockets are always non-blocking, so a game's blocking recv(), accept()
and so on came back with EAGAIN at once, and connect() and poll() blocked the
whole emulator in the host call instead. Now recv, recvfrom, send, sendto,
accept, connect, poll and select try once, and if the call would block on a
blocking socket (no SO_NBIO or MSG_DONTWAIT), the thread waits and a
CoreTiming event retries it every millisecond. It ends when the call completes
or fails, or when SO_RCVTIMEO/SO_SNDTIMEO runs out in emulated time.

Sockets accepted on Linux are made non-blocking too: unlike BSD and Windows,
Linux doesn't pass that on from the listening socket. select() rejects a
tv_usec of a second or more with EINVAL.

Hardware behaviour from pspautotests net/inet/blocking.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:03:59 +01:00
Henrik RydgårdandClaude Opus 5.5 561badca05 sceAudio: Check sceAudioInput's arguments and routing modes like the PSP
pspautotests audio/sceaudio/input and audio/sceaudio/routing.

- sceAudioInput fails until sceAudioInputInit, then checks that the
  sample count is a nonzero multiple of 64 before checking the rate
  (11025, 22050 or 44100 only). A rate of 0 now gets the PSP's error
  instead of the USB mic's. Init takes about 3ms.
- A blocking mic input woke with the byte count rather than the sample
  count that the non-blocking call returns.
- The routing functions are exported by both sceAudio and
  sceAudioRouting, and the latter had its own copy that ignored the
  stored modes. Both now share the one in sceAudio, with the ranges
  checked. SetVolumeMode returns 0, not the previous mode, and both
  modes start at 0.

sceAudio's savestate section goes to version 5 for the input init flag.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 10:56:46 +01:00
Henrik RydgårdandClaude Opus 5.5 455209b43e Net: Fix use-after-pop, the resolver after loads, inet sockaddr/poll
- The apctl, NpAuth and NpMatching2 event loops kept references to the
  front of their deque after popping it, so callbacks could get the
  next event's arguments. NpMatching2 also dereferenced its optional
  opt param when it was null.
- The resolver was left stopped after any savestate load or reboot,
  which broke Outrun 2006 (it relies on it starting out running).
- Getpeername/Getsockname with a namelen under 2 copied a negative size.
  They now write the PSP's 16-byte sockaddr truncated to namelen, with
  sa_len 16, as pspautotests net/inet/poll shows on hardware.
- Poll handed an fd that isn't open (-1) to FD_SET. It now reports
  POLLNVAL for it and counts it, as on hardware (net/inet/poll).
  Setsockopt read past a local u32 for larger options, and passed a
  negative optlen to the host. A zero cmsg_len looped forever.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 08:43:28 +01:00
Henrik RydgårdandClaude Opus 5.5 e9fa393546 Kernel: Match GetModuleIdList and heap allocation to hardware
pspautotests modules/idlist shows that sceKernelGetModuleIdList still
writes a partial entry at the end of the buffer (a size of 6 gives two
entries), which the previous commit had stopped. A NULL buffer or a
negative size returns ILLEGAL_ADDR without writing the count.

sysmem/kernel/heap shows sceKernelAllocHeapMemory returning null for
sizes near 4GB, rather than wrapping. The WithOption variant already
checked this. The plain one now does too.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-26 22:05:55 +01:00