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}