use eyre::eyre;
use hwlocality::{
Topology,
cpu::binding::CpuBindingFlags,
object::types::ObjectType,
topology::support::{DiscoverySupport, FeatureSupport},
};
fn main() -> eyre::Result<()> {
let topology = Topology::new()?;
if !topology.supports(FeatureSupport::discovery, DiscoverySupport::pu_count) {
println!("This example needs accurate reporting of PU objects");
return Ok(());
}
let Some(cpu_support) = topology.feature_support().cpu_binding() else {
println!("This example requires CPU binding support");
return Ok(());
};
if !(cpu_support.get_thread() && cpu_support.set_thread()) {
println!("This example needs support for querying and setting thread CPU bindings");
return Ok(());
}
let core_depth = topology.depth_or_below_for_type(ObjectType::Core)?;
let cores = topology.objects_at_depth(core_depth).collect::<Vec<_>>();
println!("Found {} cores, will bind one thread per core", cores.len());
std::thread::scope(|scope| {
for (idx, core) in cores.into_iter().enumerate() {
let topology = &topology;
scope.spawn(move || -> eyre::Result<()> {
let tid = hwlocality::current_thread_id();
let before = topology.thread_cpu_binding(tid, CpuBindingFlags::empty())?;
let mut bind_to = core
.cpuset()
.ok_or_else(|| eyre!("CPU cores should have CpuSets"))?
.clone_target();
bind_to.singlify();
topology.bind_thread_cpu(tid, &bind_to, CpuBindingFlags::empty())?;
let after = topology.thread_cpu_binding(tid, CpuBindingFlags::empty())?;
println!("- Thread {idx} binding: {before:?} -> {after:?}");
Ok(())
});
}
});
Ok(())
}