use std::{
cell::Cell,
sync::Arc,
thread::{self},
time::Duration,
};
use thread_map::ThreadMap;
const NTHREADS: i32 = 20;
const NITER: i32 = 10;
const SLEEP_MICROS: u64 = 10;
thread_local! {
static TL: Cell<i32> = const {Cell::new(0)};
}
fn main() {
let tm = Arc::new(ThreadMap::default());
thread::scope(|s| {
for i in 0..NTHREADS {
let tm = tm.clone();
s.spawn(move || {
for _ in 0..NITER {
thread::sleep(Duration::from_micros(SLEEP_MICROS));
tm.with_mut(move |i0: &mut i32| *i0 += i);
TL.with(move |i0: &Cell<i32>| i0.replace(i0.get() + i));
}
{
let value = tm.get();
assert_eq!(i * NITER, value);
}
{
let value = TL.with(Cell::get);
assert_eq!(i * NITER, value);
}
});
}
{
let probed = tm.probe().unwrap();
println!("probed={probed:?}");
}
{
}
for _ in 0..NITER {
tm.with_mut(|i0: &mut i32| *i0 += NTHREADS)
}
for _ in 0..NITER {
TL.with(|i0: &Cell<i32>| i0.replace(i0.get() + NTHREADS));
}
{
let probed = tm.probe().unwrap();
println!("\nprobed={probed:?}");
}
{
}
});
{
let probed = tm.probe().unwrap();
println!("\nprobed={probed:?}");
let expected_sum = (0..=NTHREADS).map(|i| i * NITER).sum::<i32>();
let sum = tm.fold_values(0, |z, v| z + v).unwrap();
assert_eq!(expected_sum, sum);
let dumped = tm.drain().unwrap();
println!("\ndumped={dumped:?}");
}
{
}
}