vita: tell stdio what to buffer a file with - #116
Open
frangarcj wants to merge 1 commit into
Open
Conversation
__swhatbuf_r asks fstat for st_blksize and falls back to BUFSIZ when nobody answers. Nothing here ever filled it in, and configure.host did not define HAVE_BLKSIZE for the target either, so every FILE got 1024 bytes. Reading a file in 4 KiB calls measured 2.64 MB/s that way against 6.99 with no buffer at all: the caller asks for 4 KiB, the buffer holds one, so each read becomes four device reads plus a copy through it. Measured on hardware, MB/s, against a 11.78 ceiling from sceIoRead: 1 KiB 2.64, 4 KiB 6.97, 16 KiB 9.93, 32 KiB 10.71, 64 KiB 11.12, 256 KiB 11.49. SceLibc uses 64 KiB and the curve flattens there. The device cannot be asked for its cluster size: sceIoDevctl 0x3001, which is what statvfs uses, returns 0x80010030 from a normal application for every spelling of the drive. Only regular files get it, so a process that only prints keeps its tty on the old 1024 rather than paying 64 KiB for stdout. Assisted-by: Claude Opus 5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
vita: tell stdio what to buffer a file with
What does this change?
Fills in
st_blksizefor regular files, and definesHAVE_BLKSIZEfor thetarget so newlib's stdio consults it.
Two lines of effect:
configure.hostgains-DHAVE_BLKSIZEon thearm*vita*entry, and
scestat_to_statsetsst_blksizeto 64 KiB when the file is aregular file.
Why is this change needed?
__swhatbuf_rasksfstatforst_blksizeand uses it as the stdio buffersize, falling back to
BUFSIZwhen it gets nothing. On Vita it got nothingtwice over: the target never defined
HAVE_BLKSIZE, so the branch that readsthe field is not even compiled, and nothing in
sys/vitaever filled the fieldin. Every
FILEtherefore gotBUFSIZ, which is 1024.That is not merely a small buffer. It is slower than switching buffering off:
Reading a file in 4 KiB
freadcalls, the caller asks for 4 KiB and the bufferholds 1, so each call becomes four device reads plus a copy through the buffer.
Unbuffered at least passes the request straight down.
The ceiling for the device is 11.78 MB/s, from
sceIoReadin 256 KiB chunks;the same read in 64 KiB chunks gives 11.38. Buffered stdio tracks raw
sceIoReadalmost exactly at matching sizes, so the buffer size is the whole story here.
64 KiB reaches 95% of that ceiling and is where the curve flattens — 128 KiB
buys another 2%, 256 KiB another 1%. It is also what SceLibc uses, which its
setvbufandsetbufshow as a hardcoded0x10000.The device cannot be asked for its real cluster size.
sceIoDevctlwith 0x3001,which is what
statvfsuses to fillf_bsize, fails from a normal applicationfor every spelling of the drive:
0x80010030forux0:andux0:/,0x80010016forux0,0x80010013forux0:data. So the value has to be aconstant.
Testing
Measured on real PlayStation Vita hardware with a purpose-built probe: it writes
an 8 MiB file, then reads it back in 4 KiB
freadcalls with the stdio bufferset through
setvbufto each size above, reopening the file for every pass andtaking the best of three. It also measures
sceIoReaddirectly at 4, 16, 64 and256 KiB for the ceiling, and reports what the device answers to the 0x3001
devctl. The numbers above are that run.
Compatibility
No API or ABI change.
st_blksizeis an existing field that was always left atzero.
Two behaviour changes worth a reviewer's attention:
FILEopened on a regular file now allocates a 64 KiB buffer instead of1 KiB. A program holding 20 open files goes from 20 KiB to 1.25 MB of stdio
buffers. Callers that care can still choose with
setvbuf, and 32 KiB reaches91% of the ceiling for half the memory if that trade is preferred.
st_blksizeitself now gets 65536 rather than 0 for regularfiles. Anything sizing a buffer from it was previously getting zero.
Directories, ttys, sockets and pipes are untouched and keep falling back to
BUFSIZ, so a process that only prints does not pay for stdout.No RFC required.
Third-party material
None.
AI assistance
Additional context
The same devctl failure means
statvfsreturns -1 withEIOon hardware forany path, since
fs.cbuildsf_bsizeand the block counts from that call.sceAppMgrGetDevInfoanswers correctly where the devctl does not. That is aseparate fix and not part of this pull request.