Skip to content

Commit 900ce9d

Browse files
committed
Add test for atomic parallel modification
1 parent 21051f2 commit 900ce9d

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

texel/tests/atomic.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
use image_texel::texels::{AtomicBuffer, U32};
2+
use std::{mem, thread};
3+
4+
#[test]
5+
fn mapping_atomics_parallel() {
6+
const LEN: usize = 128;
7+
let buffer = AtomicBuffer::new(LEN * mem::size_of::<u32>());
8+
// And receive all the results in this shared copy of our buffer.
9+
let output_tap = buffer.clone();
10+
11+
const SPLIT_MAX: usize = 1 << 6;
12+
// Proxy for whether we run with optimization. Makes execution time bearable.
13+
#[cfg(debug_assertions)]
14+
const REPEAT: usize = 1 << 6;
15+
#[cfg(not(debug_assertions))]
16+
const REPEAT: usize = 1 << 12;
17+
18+
for split in 0..SPLIT_MAX {
19+
// We want the modifying loops to overlap as much as possible for the strongest test, so
20+
// ensure they do not run early.
21+
let barrier = &std::sync::Barrier::new(2);
22+
23+
// Concurrently and repeatedly increment non-overlapping parts of the image.
24+
thread::scope(|join| {
25+
let img_a = buffer.clone();
26+
let img_b = buffer.clone();
27+
28+
join.spawn(move || {
29+
let _ = barrier.wait();
30+
for _ in 0..REPEAT {
31+
img_a.map_within(..split, 0, |n: u32| n + 1, U32, U32);
32+
}
33+
});
34+
35+
join.spawn(move || {
36+
let _ = barrier.wait();
37+
for _ in 0..REPEAT {
38+
img_b.map_within(split.., split, |n: u32| n + 1, U32, U32);
39+
}
40+
});
41+
});
42+
}
43+
44+
// Each individual `u32` has been incremented precisely as often as each other. Since the
45+
// individual transforms are synchronized with thread-scope and within they do not overlap with
46+
// each other, we must expect that the values have each been touched precisely how we intended
47+
// them to.
48+
let expected = (SPLIT_MAX * REPEAT) as u32;
49+
assert_eq!(
50+
output_tap.to_owned().as_texels(U32)[..LEN].to_vec(),
51+
(0..LEN as u32).map(|_| expected).collect::<Vec<_>>()
52+
);
53+
}

0 commit comments

Comments
 (0)