awooter: better locking

This commit is contained in:
Lofty 2022-11-26 19:38:36 +00:00
parent 026c2883e5
commit 1b80a559e2

View File

@ -1,7 +1,7 @@
use std::{ use std::{
collections::HashMap, collections::HashMap,
ptr::NonNull, ptr::NonNull,
sync::{atomic::AtomicUsize, Mutex}, sync::{atomic::AtomicUsize, Mutex, RwLock},
}; };
use colored::Colorize; use colored::Colorize;
@ -219,40 +219,40 @@ fn partition_nets(
north += 1; north += 1;
pips_n pips_n
.entry((loc.x, loc.y)) .entry((loc.x, loc.y))
.and_modify(|pip_list: &mut Vec<(npnr::PipId, Vec<npnr::IdString>)>| { .and_modify(|pip_list: &mut Vec<(npnr::PipId, RwLock<Vec<npnr::IdString>>)>| {
pip_list.push((pip, Vec::new())) pip_list.push((pip, RwLock::new(Vec::new())))
}) })
.or_insert_with(|| vec![(pip, Vec::new())]); .or_insert_with(|| vec![(pip, RwLock::new(Vec::new()))]);
} }
if dir.x > 0 { if dir.x > 0 {
south += 1; south += 1;
pips_s pips_s
.entry((loc.x, loc.y)) .entry((loc.x, loc.y))
.and_modify(|pip_list: &mut Vec<(npnr::PipId, Vec<npnr::IdString>)>| { .and_modify(|pip_list: &mut Vec<(npnr::PipId, RwLock<Vec<npnr::IdString>>)>| {
pip_list.push((pip, Vec::new())) pip_list.push((pip, RwLock::new(Vec::new())))
}) })
.or_insert_with(|| vec![(pip, Vec::new())]); .or_insert_with(|| vec![(pip, RwLock::new(Vec::new()))]);
} }
if dir.y < 0 { if dir.y < 0 {
east += 1; east += 1;
pips_e pips_e
.entry((loc.x, loc.y)) .entry((loc.x, loc.y))
.and_modify(|pip_list: &mut Vec<(npnr::PipId, Vec<npnr::IdString>)>| { .and_modify(|pip_list: &mut Vec<(npnr::PipId, RwLock<Vec<npnr::IdString>>)>| {
pip_list.push((pip, Vec::new())) pip_list.push((pip, RwLock::new(Vec::new())))
}) })
.or_insert_with(|| vec![(pip, Vec::new())]); .or_insert_with(|| vec![(pip, RwLock::new(Vec::new()))]);
} }
if dir.y > 0 { if dir.y > 0 {
west += 1; west += 1;
pips_w pips_w
.entry((loc.x, loc.y)) .entry((loc.x, loc.y))
.and_modify(|pip_list: &mut Vec<(npnr::PipId, Vec<npnr::IdString>)>| { .and_modify(|pip_list: &mut Vec<(npnr::PipId, RwLock<Vec<npnr::IdString>>)>| {
pip_list.push((pip, Vec::new())) pip_list.push((pip, RwLock::new(Vec::new())))
}) })
.or_insert_with(|| vec![(pip, Vec::new())]); .or_insert_with(|| vec![(pip, RwLock::new(Vec::new()))]);
} }
} }
} }
@ -266,11 +266,6 @@ fn partition_nets(
log_info!(" {} are south-bound\n", south.to_string().bold()); log_info!(" {} are south-bound\n", south.to_string().bold());
log_info!(" {} are west-bound\n", west.to_string().bold()); log_info!(" {} are west-bound\n", west.to_string().bold());
let pips_n = Mutex::new(pips_n);
let pips_e = Mutex::new(pips_e);
let pips_s = Mutex::new(pips_s);
let pips_w = Mutex::new(pips_w);
let progress = ProgressBar::new(nets.len() as u64); let progress = ProgressBar::new(nets.len() as u64);
progress.set_style( progress.set_style(
ProgressStyle::with_template("[{elapsed}] [{bar:40.cyan/blue}] {msg}") ProgressStyle::with_template("[{elapsed}] [{bar:40.cyan/blue}] {msg}")
@ -336,24 +331,23 @@ fn partition_nets(
} else if source_is_north != sink_is_north && source_is_east == sink_is_east { } else if source_is_north != sink_is_north && source_is_east == sink_is_east {
let middle = (x, (source.y + sink_loc.y) / 2); let middle = (x, (source.y + sink_loc.y) / 2);
let middle = (middle.0.clamp(1, ctx.grid_dim_x()-1), middle.1.clamp(1, ctx.grid_dim_y()-1)); let middle = (middle.0.clamp(1, ctx.grid_dim_x()-1), middle.1.clamp(1, ctx.grid_dim_y()-1));
let mut pips_s = pips_s.lock().unwrap();
let mut pips_n = pips_n.lock().unwrap();
let pips = match source_is_north { let pips = match source_is_north {
true => pips_s.get_mut(&middle).unwrap(), true => pips_s.get(&middle).unwrap(),
false => pips_n.get_mut(&middle).unwrap(), false => pips_n.get(&middle).unwrap(),
}; };
let (selected_pip, pip_uses) = pips let (selected_pip, pip_uses) = pips
.iter_mut() .iter()
.min_by_key(|(pip, uses)| { .min_by_key(|(pip, uses)| {
let src_to_pip = let src_to_pip =
ctx.estimate_delay(source_wire, ctx.pip_src_wire(*pip)); ctx.estimate_delay(source_wire, ctx.pip_src_wire(*pip));
let pip_to_snk = ctx.estimate_delay(ctx.pip_dst_wire(*pip), sink_wire); let pip_to_snk = ctx.estimate_delay(ctx.pip_dst_wire(*pip), sink_wire);
let uses = uses.read().unwrap();
let uses = uses.len() - (uses.contains(name) as usize); let uses = uses.len() - (uses.contains(name) as usize);
(1000.0 * (src_to_pip + ((uses + 1) as f32) * pip_to_snk)) as u64 (1000.0 * (src_to_pip + ((uses + 1) as f32) * pip_to_snk)) as u64
}) })
.unwrap(); .unwrap();
pip_uses.push(*name); pip_uses.write().unwrap().push(*name);
let selected_pip = *selected_pip; let selected_pip = *selected_pip;
explored_pips.fetch_add(pips.len(), std::sync::atomic::Ordering::SeqCst); explored_pips.fetch_add(pips.len(), std::sync::atomic::Ordering::SeqCst);
@ -371,24 +365,23 @@ fn partition_nets(
} else if source_is_north == sink_is_north && source_is_east != sink_is_east { } else if source_is_north == sink_is_north && source_is_east != sink_is_east {
let middle = ((source.x + sink_loc.x) / 2, y); let middle = ((source.x + sink_loc.x) / 2, y);
let middle = (middle.0.clamp(1, ctx.grid_dim_x()-1), middle.1.clamp(1, ctx.grid_dim_y()-1)); let middle = (middle.0.clamp(1, ctx.grid_dim_x()-1), middle.1.clamp(1, ctx.grid_dim_y()-1));
let mut pips_e = pips_e.lock().unwrap();
let mut pips_w = pips_w.lock().unwrap();
let pips = match source_is_east { let pips = match source_is_east {
true => pips_w.get_mut(&middle).unwrap(), true => pips_w.get(&middle).unwrap(),
false => pips_e.get_mut(&middle).unwrap_or_else(|| panic!("\nwhile partitioning an arc between ({}, {}) and ({}, {})\n({}, {}) does not exist in the pip library\n", source.x, source.y, sink_loc.x, sink_loc.y, middle.0, middle.1)), false => pips_e.get(&middle).unwrap_or_else(|| panic!("\nwhile partitioning an arc between ({}, {}) and ({}, {})\n({}, {}) does not exist in the pip library\n", source.x, source.y, sink_loc.x, sink_loc.y, middle.0, middle.1)),
}; };
let (selected_pip, pip_uses) = pips let (selected_pip, pip_uses) = pips
.iter_mut() .iter()
.min_by_key(|(pip, uses)| { .min_by_key(|(pip, uses)| {
let src_to_pip = let src_to_pip =
ctx.estimate_delay(source_wire, ctx.pip_src_wire(*pip)); ctx.estimate_delay(source_wire, ctx.pip_src_wire(*pip));
let pip_to_snk = ctx.estimate_delay(ctx.pip_dst_wire(*pip), sink_wire); let pip_to_snk = ctx.estimate_delay(ctx.pip_dst_wire(*pip), sink_wire);
let uses = uses.read().unwrap();
let uses = uses.len() - (uses.contains(name) as usize); let uses = uses.len() - (uses.contains(name) as usize);
(1000.0 * (src_to_pip + ((uses + 1) as f32) * pip_to_snk)) as u64 (1000.0 * (src_to_pip + ((uses + 1) as f32) * pip_to_snk)) as u64
}) })
.unwrap(); .unwrap();
pip_uses.push(*name); pip_uses.write().unwrap().push(*name);
let selected_pip = *selected_pip; let selected_pip = *selected_pip;
explored_pips.fetch_add(pips.len(), std::sync::atomic::Ordering::SeqCst); explored_pips.fetch_add(pips.len(), std::sync::atomic::Ordering::SeqCst);
@ -406,47 +399,45 @@ fn partition_nets(
} else { } else {
let middle = (x, split_line_over_x((source, sink_loc), x)); let middle = (x, split_line_over_x((source, sink_loc), x));
let middle = (middle.0.clamp(1, ctx.grid_dim_x()-1), middle.1.clamp(1, ctx.grid_dim_y()-1)); let middle = (middle.0.clamp(1, ctx.grid_dim_x()-1), middle.1.clamp(1, ctx.grid_dim_y()-1));
let mut pips_e = pips_e.lock().unwrap();
let mut pips_w = pips_w.lock().unwrap();
let pips = match source_is_east { let pips = match source_is_east {
true => pips_w.get_mut(&middle).unwrap(), true => pips_w.get(&middle).unwrap(),
false => pips_e.get_mut(&middle).unwrap(), false => pips_e.get(&middle).unwrap(),
}; };
let (horiz_pip, pip_uses) = pips let (horiz_pip, pip_uses) = pips
.iter_mut() .iter()
.min_by_key(|(pip, uses)| { .min_by_key(|(pip, uses)| {
let src_to_pip = let src_to_pip =
ctx.estimate_delay(source_wire, ctx.pip_src_wire(*pip)); ctx.estimate_delay(source_wire, ctx.pip_src_wire(*pip));
let pip_to_snk = ctx.estimate_delay(ctx.pip_dst_wire(*pip), sink_wire); let pip_to_snk = ctx.estimate_delay(ctx.pip_dst_wire(*pip), sink_wire);
let uses = uses.read().unwrap();
let uses = uses.len() - (uses.contains(name) as usize); let uses = uses.len() - (uses.contains(name) as usize);
(1000.0 * (src_to_pip + ((uses + 1) as f32) * pip_to_snk)) as u64 (1000.0 * (src_to_pip + ((uses + 1) as f32) * pip_to_snk)) as u64
}) })
.unwrap(); .unwrap();
pip_uses.push(*name); pip_uses.write().unwrap().push(*name);
let horiz_pip = *horiz_pip; let horiz_pip = *horiz_pip;
explored_pips.fetch_add(pips.len(), std::sync::atomic::Ordering::SeqCst); explored_pips.fetch_add(pips.len(), std::sync::atomic::Ordering::SeqCst);
let middle = (split_line_over_y((source, sink_loc), y), y); let middle = (split_line_over_y((source, sink_loc), y), y);
let middle = (middle.0.clamp(1, ctx.grid_dim_x()-1), middle.1.clamp(1, ctx.grid_dim_y()-1)); let middle = (middle.0.clamp(1, ctx.grid_dim_x()-1), middle.1.clamp(1, ctx.grid_dim_y()-1));
let mut pips_s = pips_s.lock().unwrap();
let mut pips_n = pips_n.lock().unwrap();
let pips = match source_is_north { let pips = match source_is_north {
true => pips_s.get_mut(&middle).unwrap(), true => pips_s.get(&middle).unwrap(),
false => pips_n.get_mut(&middle).unwrap(), false => pips_n.get(&middle).unwrap(),
}; };
let (vert_pip, pip_uses) = pips let (vert_pip, pip_uses) = pips
.iter_mut() .iter()
.min_by_key(|(pip, uses)| { .min_by_key(|(pip, uses)| {
let src_to_pip = let src_to_pip =
ctx.estimate_delay(source_wire, ctx.pip_src_wire(*pip)); ctx.estimate_delay(source_wire, ctx.pip_src_wire(*pip));
let pip_to_snk = ctx.estimate_delay(ctx.pip_dst_wire(*pip), sink_wire); let pip_to_snk = ctx.estimate_delay(ctx.pip_dst_wire(*pip), sink_wire);
let uses = uses.read().unwrap();
let uses = uses.len() - (uses.contains(name) as usize); let uses = uses.len() - (uses.contains(name) as usize);
(1000.0 * (src_to_pip + ((uses + 1) as f32) * pip_to_snk)) as u64 (1000.0 * (src_to_pip + ((uses + 1) as f32) * pip_to_snk)) as u64
}) })
.unwrap(); .unwrap();
pip_uses.push(*name); pip_uses.write().unwrap().push(*name);
let vert_pip = *vert_pip; let vert_pip = *vert_pip;
explored_pips.fetch_add(pips.len(), std::sync::atomic::Ordering::SeqCst); explored_pips.fetch_add(pips.len(), std::sync::atomic::Ordering::SeqCst);