mirror of
https://github.com/quer3q/ps5-dump-forge.git
synced 2026-10-19 03:59:52 -05:00
A .pkg build on the PS5 ran at 9 MB/s with the console idle; it now holds ~40 MB/s (7.4 GB in the first 3 min of compress of an 89 GB game image, was ~1.6). - CPU count: the PS5 refuses std's process-level cpuset query (ERANGE), so std said 16 CPUs from sysconf while a payload may run on 5 (mask 0xea00); every pool ran 3x oversubscribed. ps5/compat.c wraps cpuset_getaffinity and answers it from the thread's mask, so every pool, the vendored crates' included, sees 5. - serve's default compression_threads leaves 2 cores on the PS5 (3 workers; 4% slower than 4, the console's browser stays usable), 1 elsewhere as before. - verify: the hashing pool keeps POOL_MAX (8) spare slices whatever its thread count; with 5 spares the same build ran at half speed (fresh 8 MiB slices, likely page-faulting through the PS5 libc). - crates/ps5-dump-forge-ps5: the payload's global allocator (CLI, PS5 only). The PS5 libc serializes every malloc, realloc and free across threads; Pool keeps freed blocks of 64 B..4 MiB in power-of-two classes (lock-free slots, ~56 MiB at most): 4 Kraken threads on a fixed 32 MiB sample went 12.7 -> 49.3 MB/s. - vendor patch 0022: the Kraken encoder allocates less per block, same bytes: allocation-free huffman_lengths (two queues, tested against the heap), literal mode chosen by encoded_len instead of coding both, stream arrays and bit writers reserved whole. Same output on four 32 MiB samples; 13.1 -> 27.3 MB/s at 4 threads alone. - Measured and dropped: smaller hash/window tables, literal-run skipping (no gain, or ratio cost). .exfat/.ffpkg/.ffpfsc writes show no allocator effect (I/O-bound). - AGENTS.md, ps5/README.md, vendor/README.md. Reviewed with Codex (2 rounds, clean).
36 lines
1.8 KiB
C
36 lines
1.8 KiB
C
/* PS5-only adapters outside shim/ (which stays byte-identical to upstream): statfs symvers and the
|
|
* cpuset query below. libc's FreeBSD 11 ABI (--cfg libc_unstable_freebsd_version="11") asks for
|
|
* statfs@FBSD_1.0 and fstatfs@FBSD_1.0; the SDK exports them unversioned, with the same FreeBSD 11
|
|
* struct statfs (MNAMELEN 88), so forwarding is enough, as shim/freebsd11.c does for stat. Plain
|
|
* fstatfs is the shim's --wrap=fstatfs (raw syscall 397, the FreeBSD 11 layout).
|
|
*/
|
|
#include <sys/param.h>
|
|
#include <sys/mount.h>
|
|
|
|
int ps5_statfs(const char *path, struct statfs *buffer) {
|
|
return statfs(path, buffer);
|
|
}
|
|
int ps5_fstatfs(int fd, struct statfs *buffer) {
|
|
return fstatfs(fd, buffer);
|
|
}
|
|
__asm__(".symver ps5_statfs,statfs@FBSD_1.0");
|
|
__asm__(".symver ps5_fstatfs,fstatfs@FBSD_1.0");
|
|
|
|
/* std's available_parallelism asks cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1) with
|
|
* libc's 256-bit cpuset_t; the PS5 refuses that (ERANGE) and std fell back to sysconf's 16 CPUs,
|
|
* while a payload may run on 5 (mask 0xea00: CPUs 9, 11, 13-15), so every pool ran 3x
|
|
* oversubscribed (a .pkg's Kraken at 9 MB/s with 15 threads, 43 with 4). The thread query with the
|
|
* kernel's 128-bit set works, and a thread starts with its process's mask, so the process query is
|
|
* answered from the calling thread's. */
|
|
#include <string.h>
|
|
#include <sys/types.h>
|
|
int __real_cpuset_getaffinity(int level, int which, id_t id, size_t size, void *mask);
|
|
int __wrap_cpuset_getaffinity(int level, int which, id_t id, size_t size, void *mask) {
|
|
enum { WHICH_TID = 1, WHICH_PID = 2, KERNEL_SET = 16 };
|
|
if (which == WHICH_PID && id == (id_t)-1 && size >= KERNEL_SET) {
|
|
memset(mask, 0, size);
|
|
return __real_cpuset_getaffinity(level, WHICH_TID, -1, KERNEL_SET, mask);
|
|
}
|
|
return __real_cpuset_getaffinity(level, which, id, size, mask);
|
|
}
|