use eyre::eyre;
use hwlocality::{
Topology,
cpu::binding::CpuBindingFlags,
object::{TopologyObject, types::ObjectType},
};
fn main() -> eyre::Result<()> {
let topology = Topology::new()?;
let Some(support) = topology.feature_support().cpu_binding() else {
println!("This example requires CPU binding support");
return Ok(());
};
if !((support.get_current_process() || support.get_current_thread())
&& (support.set_current_process() || support.set_current_thread()))
{
println!(
"This example needs support for querying and setting current process CPU bindings"
);
return Ok(());
}
let cpuset = last_core(&topology)?
.cpuset()
.ok_or_else(|| eyre!("CPU cores should have CPUsets"))?;
let print_binding_location = |situation: &str| -> eyre::Result<()> {
println!(
"Cpu Binding {situation}: {:?}",
topology.cpu_binding(CpuBindingFlags::ASSUME_SINGLE_THREAD)?
);
if support.get_current_process_last_cpu_location() {
println!(
"Cpu Location {situation}: {:?}",
topology.last_cpu_location(CpuBindingFlags::ASSUME_SINGLE_THREAD)?
)
}
Ok(())
};
print_binding_location("before explicit binding")?;
topology.bind_cpu(cpuset, CpuBindingFlags::ASSUME_SINGLE_THREAD)?;
println!("Correctly bound to last core");
print_binding_location("after explicit binding")?;
Ok(())
}
fn last_core(topology: &Topology) -> eyre::Result<&TopologyObject> {
let core_depth = topology.depth_or_below_for_type(ObjectType::Core)?;
let mut all_cores = topology.objects_at_depth(core_depth);
all_cores
.next_back()
.ok_or_else(|| eyre!("at least one Core or PU should be present"))
}