mirror of
https://github.com/libretro/parallel-dc.git
synced 2026-11-10 17:26:21 -10:00
The CHD reader fed every compressed hunk to rchd with rchd_feed_at, which copies it into the decoder's staging buffer - a whole hunk per hunk, out of a mapping that is already stable memory. It now uses rchd_feed_borrow on the mapped path: the decoder reads the compressed bytes where they lie in the page cache and the copy is gone. The bounce buffer stays for files that are not mapped, since a read syscall needs a destination; that is the only copy left on that path. A GD-ROM read lands on an arbitrary hunk, and a cold page there stalls whichever thread decodes it - the reader or the read-ahead worker. chd_image_prefetch() takes the hunk range a read is about to cover, asks rchd_hunk_location() where each hunk's blob sits, merges the neighbours (chdman writes hunks in order, so a run is one range) and hands each range to core_fprefetch(). CHDTrack::Prefetch() maps the sectors of the SPI/HLE read hint to hunks and calls it on the main handle; both handles are on one file, so one hint serves both. Capped at 256 hunks, more than one GD-ROM command reads at chdman's eight frames per hunk. Hunks that carry no blob of their own - self and parent references, uncompressed runs - are skipped. tools/chd/run.sh now builds chd_image_test twice, with and without HAVE_MMAP, so the borrowed path and the bounce-buffer path are both checked under ASan and UBSan; the test issues the hint in every shape before the reads it is for. rchd.c is synced with libretro-common (an unsigned compare of the hunk limit). Measured in this container, where the disk's cold reads could not be reproduced through posix_fadvise(DONTNEED), 64 hunks decode in the same ~7 ms with or without the hint; the hint is one madvise per contiguous run and costs nothing when the pages are already in. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01LZc3GaYf7kS6FWTkSv6e6n