Skip to content

Commit 8cbf583

Browse files
committed
Experiment with thread local channel data pool
1 parent 71fb222 commit 8cbf583

File tree

2 files changed

+15
-20
lines changed

2 files changed

+15
-20
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ include = [
1515
"LICENSE",
1616
"README.md",
1717
]
18-
rust-version = "1.70"
18+
rust-version = "1.73"
1919

2020
[dependencies]
2121
arc-swap = "1.6"

src/render/quantum.rs

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,20 @@ pub(crate) struct Alloc {
1414
}
1515

1616
#[derive(Debug)]
17-
struct AllocInner {
18-
pool: RefCell<Vec<Rc<[f32; RENDER_QUANTUM_SIZE]>>>,
19-
zeroes: Rc<[f32; RENDER_QUANTUM_SIZE]>,
17+
struct AllocInner {}
18+
19+
thread_local! {
20+
static POOL: RefCell<Vec<Rc<[f32; RENDER_QUANTUM_SIZE]>>> = RefCell::new(Vec::with_capacity(32));
21+
static ZEROES: Rc<[f32; RENDER_QUANTUM_SIZE]> = Rc::new([0.; RENDER_QUANTUM_SIZE]);
2022
}
2123

2224
impl Alloc {
2325
pub fn with_capacity(n: usize) -> Self {
2426
let pool: Vec<_> = (0..n).map(|_| Rc::new([0.; RENDER_QUANTUM_SIZE])).collect();
25-
let zeroes = Rc::new([0.; RENDER_QUANTUM_SIZE]);
26-
27-
let inner = AllocInner {
28-
pool: RefCell::new(pool),
29-
zeroes,
30-
};
27+
POOL.set(pool);
3128

3229
Self {
33-
inner: Rc::new(inner),
30+
inner: Rc::new(AllocInner {}),
3431
}
3532
}
3633

@@ -44,20 +41,20 @@ impl Alloc {
4441

4542
pub fn silence(&self) -> AudioRenderQuantumChannel {
4643
AudioRenderQuantumChannel {
47-
data: Rc::clone(&self.inner.zeroes),
44+
data: ZEROES.with(Rc::clone),
4845
alloc: Rc::clone(&self.inner),
4946
}
5047
}
5148

5249
#[cfg(test)]
5350
pub fn pool_size(&self) -> usize {
54-
self.inner.pool.borrow().len()
51+
POOL.with_borrow(|p| p.len())
5552
}
5653
}
5754

5855
impl AllocInner {
5956
fn allocate(&self) -> Rc<[f32; RENDER_QUANTUM_SIZE]> {
60-
if let Some(rc) = self.pool.borrow_mut().pop() {
57+
if let Some(rc) = POOL.with_borrow_mut(|p| p.pop()) {
6158
// reuse from pool
6259
rc
6360
} else {
@@ -67,9 +64,7 @@ impl AllocInner {
6764
}
6865

6966
fn push(&self, data: Rc<[f32; RENDER_QUANTUM_SIZE]>) {
70-
self.pool
71-
.borrow_mut() // infallible when single threaded
72-
.push(data);
67+
POOL.with_borrow_mut(|p| p.push(data));
7368
}
7469
}
7570

@@ -107,7 +102,7 @@ impl AudioRenderQuantumChannel {
107102
///
108103
/// If this function returns false, it is still possible for all samples to be zero.
109104
pub(crate) fn is_silent(&self) -> bool {
110-
Rc::ptr_eq(&self.data, &self.alloc.zeroes)
105+
ZEROES.with(|z| Rc::ptr_eq(&self.data, z))
111106
}
112107

113108
/// Sum two channels
@@ -121,7 +116,7 @@ impl AudioRenderQuantumChannel {
121116

122117
pub(crate) fn silence(&self) -> Self {
123118
Self {
124-
data: Rc::clone(&self.alloc.zeroes),
119+
data: ZEROES.with(Rc::clone),
125120
alloc: Rc::clone(&self.alloc),
126121
}
127122
}
@@ -152,7 +147,7 @@ impl AsRef<[f32]> for AudioRenderQuantumChannel {
152147
impl std::ops::Drop for AudioRenderQuantumChannel {
153148
fn drop(&mut self) {
154149
if Rc::strong_count(&self.data) == 1 {
155-
let zeroes = Rc::clone(&self.alloc.zeroes);
150+
let zeroes = ZEROES.with(Rc::clone);
156151
let rc = std::mem::replace(&mut self.data, zeroes);
157152
self.alloc.push(rc);
158153
}

0 commit comments

Comments
 (0)