Introduces the freemkv mux throughput highway: a three-stage thread pipeline that replaces the inline single-thread read path for any file-backed source (ISO and m2ts file URLs both route through it). Thread A: read + decrypt (PrefetchedSectorSource / BytePrefetcher) Thread B: M2TS demux (DemuxThread) Thread C: codec parse (PipelinedPesStream, on caller thread) Each handoff uses a bounded crossbeam channel with a recycled buffer pool — no allocations or memcpys in the steady-state hot loop. Component map: * io/byte_prefetcher.rs (new) — std::io::Read producer thread with recycled Vec<u8> pool. Pairs with PrefetchedSectorSource (sector side) so demux_thread::spawn_zero_copy can wire either upstream. * sector/prefetched.rs — recycled buffer pool added; into_channels() peels off the rx/recycle_tx/shell triple for zero-copy demux. * mux/demux_thread.rs (new) — owns the TsDemuxer/PsDemuxer, runs feed() on its thread, ships Vec<PesPacket> batches. * mux/pipelined_stream.rs (new) — the read-side Stream impl. Pulls packets from the demux thread and runs codec parse on the caller. * mux/resolve.rs — build_iso_pipeline (public) / build_m2ts_pipeline (private) assemble the three stages; iso:// and m2ts:// both return PipelinedPesStream. * mux/m2ts.rs — collapsed to a write-only sink (Mode::Read deleted; the read direction lives on the highway now). * mux/codec/h264.rs — find_start_code uses memchr SIMD memmem::find. * mux/codec/hevc.rs — tightened frame_data initial capacity. * mux/ts.rs — boundary-packet handling avoids the per-batch 16 MiB remainder copy; PesAssembler starts at 16 KiB to dodge the 64-page first-touch fault tax that the previous 256 KiB pre-alloc paid on every PES boundary. * mux/disc.rs — gains DiscStream::new_pipeline + read_pipeline as the legacy autorip ingress (drive + multipass paths still need on_event / skip_errors before they migrate to the highway). * io/file_sector_source/* — per-OS prefetch() syscall hook (Linux readahead, macOS F_RDADVISE, Windows/other no-op). * decrypt.rs — FREEMKV_DECRYPT_THREADS renamed to FREEMKV_THREADS; pool sized to all cores by default. Measured on rip1 testbed (Civil War UHD, 62 GiB ISO → null://): 60 → 322 MB/s warm cache (old new_pipeline path) 60 → 660 MB/s warm cache (highway path, this commit) 60 → 126 MB/s sustained disk-bound The IsoSectorReader baseline reader was deleted in favour of FileSectorSource so the freemkv CLI and autorip exercise the same read path.
39 lines
1.6 KiB
Rust
39 lines
1.6 KiB
Rust
//! Shared macOS `fcntl(F_PREALLOCATE)` definitions.
|
|
//!
|
|
//! The `libc` crate doesn't expose these symbols across all macOS SDK
|
|
//! versions, so we define them locally with values from
|
|
//! `/usr/include/sys/fcntl.h`. Two call sites (
|
|
//! [`crate::io::writeback_file`] and [`crate::io::sink::preallocate`])
|
|
//! need the same constants and `fstore_t` layout — keeping a single
|
|
//! source of truth here prevents the two copies from drifting.
|
|
//!
|
|
//! Module-level cfg gate lives in the parent (`io/mod.rs`); this file
|
|
//! is only compiled on macOS, so no inner `#![cfg]` is needed.
|
|
|
|
/// `fcntl(F_PREALLOCATE)` command number from `sys/fcntl.h`.
|
|
pub(crate) const F_PREALLOCATE: libc::c_int = 42;
|
|
|
|
/// Anchor preallocation at the current physical EOF.
|
|
pub(crate) const F_PEOFPOSMODE: libc::c_int = 3;
|
|
|
|
/// Prefer a contiguous allocation. Try this first; on `EINVAL` (no
|
|
/// contiguous run of that size), fall back to `F_ALLOCATEALL`.
|
|
pub(crate) const F_ALLOCATECONTIG: libc::c_uint = 0x0000_0002;
|
|
|
|
/// Allow non-contiguous allocation. Stronger guarantee than just
|
|
/// asking for `F_ALLOCATECONTIG` because the kernel will piece
|
|
/// together fragments rather than failing.
|
|
pub(crate) const F_ALLOCATEALL: libc::c_uint = 0x0000_0004;
|
|
|
|
/// `fstore_t` from `sys/fcntl.h`. `repr(C)` because we hand it to
|
|
/// `fcntl(F_PREALLOCATE)` which writes through the pointer.
|
|
#[repr(C)]
|
|
#[derive(Clone, Copy)]
|
|
pub(crate) struct Fstore {
|
|
pub fst_flags: libc::c_uint,
|
|
pub fst_posmode: libc::c_int,
|
|
pub fst_offset: libc::off_t,
|
|
pub fst_length: libc::off_t,
|
|
pub fst_bytesalloc: libc::off_t,
|
|
}
|