1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// Copyright (c) 2026, The rav1r contributors. All rights reserved
//
// This source code is subject to the terms of the BSD 2 Clause License and
// the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
// was not distributed with this source code in the LICENSE file, you can
// obtain it at www.aomedia.org/license/software. If the Alliance for Open
// Media Patent License 1.0 was not distributed with this source code in the
// PATENTS file, you can obtain it at www.aomedia.org/license/patent.
//! Parallel iteration and thread pools.
//!
//! With the `threading` feature this module re-exports the items of `rayon`
//! that the encoder uses. Without it, the same items run on the calling
//! thread.
#[cfg(feature = "threading")]
pub use rayon::{iter, scope, ThreadPool, ThreadPoolBuilder};
#[cfg(not(feature = "threading"))]
pub use sequential::*;
#[cfg(not(feature = "threading"))]
mod sequential {
use std::convert::Infallible;
pub mod iter {
/// Sequential stand-in for `rayon::iter::IntoParallelIterator`.
pub trait IntoParallelIterator {
type Item: Send;
type Iter: Iterator<Item = Self::Item>;
fn into_par_iter(self) -> Self::Iter;
}
impl<I: IntoIterator> IntoParallelIterator for I
where
I::Item: Send,
{
type Item = I::Item;
type Iter = I::IntoIter;
#[inline(always)]
fn into_par_iter(self) -> Self::Iter {
self.into_iter()
}
}
/// Sequential stand-in for `rayon::iter::IntoParallelRefMutIterator`.
pub trait IntoParallelRefMutIterator<'data> {
type Item: Send + 'data;
type Iter: Iterator<Item = Self::Item>;
fn par_iter_mut(&'data mut self) -> Self::Iter;
}
impl<'data, T: Send + 'data> IntoParallelRefMutIterator<'data> for [T] {
type Item = &'data mut T;
type Iter = std::slice::IterMut<'data, T>;
#[inline(always)]
fn par_iter_mut(&'data mut self) -> Self::Iter {
self.iter_mut()
}
}
}
/// Sequential stand-in for `rayon::Scope`.
pub struct Scope;
impl Scope {
/// Runs `body` on the calling thread before it returns.
#[inline(always)]
pub fn spawn<BODY>(&self, body: BODY)
where
BODY: FnOnce(&Scope) + Send,
{
body(self)
}
}
/// Sequential stand-in for `rayon::scope`.
#[inline(always)]
pub fn scope<OP, R>(op: OP) -> R
where
OP: FnOnce(&Scope) -> R + Send,
R: Send,
{
op(&Scope)
}
/// Sequential stand-in for `rayon::ThreadPoolBuilder`.
#[derive(Default)]
pub struct ThreadPoolBuilder;
impl ThreadPoolBuilder {
#[inline(always)]
pub fn new() -> Self {
ThreadPoolBuilder
}
#[inline(always)]
pub fn num_threads(self, _num_threads: usize) -> Self {
self
}
#[inline(always)]
pub fn build(self) -> Result<ThreadPool, Infallible> {
Ok(ThreadPool)
}
}
/// Sequential stand-in for `rayon::ThreadPool`.
#[derive(Debug)]
pub struct ThreadPool;
impl ThreadPool {
/// Runs `op` on the calling thread.
#[inline(always)]
pub fn install<OP, R>(&self, op: OP) -> R
where
OP: FnOnce() -> R + Send,
R: Send,
{
op()
}
}
}