jpegxl_sys\threads/thread_parallel_runner.rs
1/*
2This file is part of jpegxl-sys.
3
4jpegxl-sys is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 3 of the License, or
7(at your option) any later version.
8
9jpegxl-sys is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with jpegxl-sys. If not, see <https://www.gnu.org/licenses/>.
16*/
17
18//! Implementation using `std::thread` of a [`JxlParallelRunner`].
19
20//! Implementation of [`JxlParallelRunner`] that can be used to enable
21//! multithreading when using the JPEG XL library. This uses `std::thread`
22//! internally and related synchronization functions. The number of threads
23//! created is fixed at construction time and the threads are re-used for every
24//! `ThreadParallelRunner::Runner` call. Only one concurrent
25//! `JxlThreadParallelRunner` call per instance is allowed at a time.
26//!
27//! This is a scalable, lower-overhead thread pool runner, especially suitable
28//! for data-parallel computations in the fork-join model, where clients need to
29//! know when all tasks have completed.
30//!
31//! This thread pool can efficiently load-balance millions of tasks using an
32//! atomic counter, thus avoiding per-task virtual or system calls. With 48
33//! hyperthreads and 1M tasks that add to an atomic counter, overall runtime is
34//! 10-20x higher when using `std::async`, and ~200x for a queue-based thread
35//! pool.
36
37use std::ffi::c_void;
38
39#[cfg(doc)]
40use super::parallel_runner::JxlParallelRunner;
41use super::parallel_runner::{JxlParallelRetCode, JxlParallelRunFunction, JxlParallelRunInit};
42use crate::common::memory_manager::JxlMemoryManager;
43
44extern "C-unwind" {
45 /// Parallel runner internally using `std::thread`. Use as [`JxlParallelRunner`].
46 pub fn JxlThreadParallelRunner(
47 runner_opaque: *mut c_void,
48 jpegxl_opaque: *mut c_void,
49 init: JxlParallelRunInit,
50 func: JxlParallelRunFunction,
51 start_range: u32,
52 end_range: u32,
53 ) -> JxlParallelRetCode;
54
55 /// Creates the runner for [`JxlThreadParallelRunner`]. Use as the opaque runner.
56 pub fn JxlThreadParallelRunnerCreate(
57 memory_manager: *const JxlMemoryManager,
58 num_worker_threads: usize,
59 ) -> *mut c_void;
60
61 /// Destroys the runner created by [`JxlThreadParallelRunnerCreate`].
62 pub fn JxlThreadParallelRunnerDestroy(runner_opaque: *mut c_void);
63
64 /// Returns a default `num_worker_threads` value for [`JxlThreadParallelRunnerCreate`].
65 pub fn JxlThreadParallelRunnerDefaultNumWorkerThreads() -> usize;
66}