Struct Topology

Source
pub struct Topology { /* private fields */ }

Implementations§

Source§

impl Topology

Source

pub fn new() -> Topology

Creates a new Topology.

If no further customization is needed on init, this method represents the main entry point. A topology is returned which contains the logical representation of the physical hardware.

§Examples
use hwloc::Topology;

let topology = Topology::new();

Note that the topology implements the Drop trait, so when it goes out of scope no further cleanup is necessary.

Examples found in repository?
examples/walk_tree.rs (line 7)
6fn main() {
7    let topo = Topology::new();
8
9    println!("*** Printing overall tree");
10    print_children(&topo, topo.object_at_root(), 0);
11}
More examples
Hide additional examples
examples/walk_linear.rs (line 8)
7fn main() {
8    let topo = Topology::new();
9
10    for i in 0..topo.depth() {
11        println!("*** Objects at level {}", i);
12
13        for (idx, object) in topo.objects_at_depth(i).iter().enumerate() {
14            println!("{}: {}", idx, object);
15        }
16    }
17}
examples/number_of_packages.rs (line 7)
6fn main() {
7    let topo = Topology::new();
8
9    let package_depth = topo.depth_for_type(&ObjectType::Package);
10    match package_depth {
11        Ok(depth) => println!("*** {} package(s)", topo.size_at_depth(depth)),
12        Err(TypeDepthError::TypeDepthUnknown) => println!("*** The number of packages is unknown"),
13        Err(e) => println!("Unknown Error: {:?}", e),
14    }
15}
examples/processor_cache.rs (line 8)
7fn main() {
8    let topo = Topology::new();
9
10    let pu = topo.objects_with_type(&ObjectType::PU).unwrap()[0];
11
12    let mut parent = pu.parent();
13    let mut levels = 0;
14    let mut size = 0;
15
16    while let Some(p) = parent {
17        if p.object_type() == ObjectType::Cache {
18            levels += 1;
19            // This should actually be size(), but there is a (compiler) bug? with the c-ffi unions
20            size += p.cache_attributes().unwrap().size;
21        }
22        parent = p.parent();
23    }
24
25    println!("*** Logical processor 0 has {} caches totalling {} KB",
26             levels,
27             size / 1024);
28}
examples/support.rs (line 7)
6fn main() {
7    let topo = Topology::new();
8
9    // Check if Process Binding for CPUs is supported
10    println!("CPU Binding (current process) supported: {}",
11             topo.support().cpu().set_current_process());
12    println!("CPU Binding (any process) supported: {}",
13             topo.support().cpu().set_process());
14
15    // Check if Thread Binding for CPUs is supported
16    println!("CPU Binding (current thread) supported: {}",
17             topo.support().cpu().set_current_thread());
18    println!("CPU Binding (any thread) supported: {}",
19             topo.support().cpu().set_thread());
20
21    // Check if Memory Binding is supported
22    println!("Memory Binding supported: {}",
23             topo.support().memory().set_current_process());
24
25    // Debug Print all the Support Flags
26    println!("All Flags:\n{:?}", topo.support());
27}
examples/bind_to_last_core.rs (line 20)
19fn main() {
20    let mut topo = Topology::new();
21
22    // Grab last core and exctract its CpuSet
23    let mut cpuset = last_core(&mut topo).cpuset().unwrap();
24
25    //  Get only one logical processor (in case the core is SMT/hyper-threaded).
26    cpuset.singlify();
27
28    // Print the current cpu binding before explicit setting
29    println!("Cpu Binding before explicit bind: {:?}",
30             topo.get_cpubind(CPUBIND_PROCESS));
31    println!("Cpu Location before explicit bind: {:?}",
32             topo.get_cpu_location(CPUBIND_PROCESS));
33
34    // Try to bind all threads of the current (possibly multithreaded) process.
35    match topo.set_cpubind(cpuset, CPUBIND_PROCESS) {
36        Ok(_) => println!("Correctly bound to last core"),
37        Err(e) => println!("Failed to bind: {:?}", e),
38    }
39
40    // Print the current cpu binding after explicit setting
41    println!("Cpu Binding after explicit bind: {:?}",
42             topo.get_cpubind(CPUBIND_PROCESS));
43    println!("Cpu Location after explicit bind: {:?}",
44             topo.get_cpu_location(CPUBIND_PROCESS));
45}
Source

pub fn with_flags(flags: Vec<TopologyFlag>) -> Topology

Creates a new Topology with custom flags.

This method works like new, but allows to provide a vector of flags which customize the topology discovery process.

§Examples
use hwloc::{Topology, TopologyFlag};

let topology = Topology::with_flags(vec![TopologyFlag::IoDevices]);

Note that the topology implements the Drop trait, so when it goes out of scope no further cleanup is necessary.

Source

pub fn support(&self) -> &TopologySupport

Examples found in repository?
examples/support.rs (line 11)
6fn main() {
7    let topo = Topology::new();
8
9    // Check if Process Binding for CPUs is supported
10    println!("CPU Binding (current process) supported: {}",
11             topo.support().cpu().set_current_process());
12    println!("CPU Binding (any process) supported: {}",
13             topo.support().cpu().set_process());
14
15    // Check if Thread Binding for CPUs is supported
16    println!("CPU Binding (current thread) supported: {}",
17             topo.support().cpu().set_current_thread());
18    println!("CPU Binding (any thread) supported: {}",
19             topo.support().cpu().set_thread());
20
21    // Check if Memory Binding is supported
22    println!("Memory Binding supported: {}",
23             topo.support().memory().set_current_process());
24
25    // Debug Print all the Support Flags
26    println!("All Flags:\n{:?}", topo.support());
27}
Source

pub fn flags(&self) -> Vec<TopologyFlag>

Returns the flags currently set for this topology.

Note that the flags are only used during initialization, so this method can just be used for debugging purposes.

§Examples
use hwloc::{Topology,TopologyFlag};

let default_topology = Topology::new();
assert_eq!(0, default_topology.flags().len());

let topology_with_flags = Topology::with_flags(vec![TopologyFlag::IoDevices]);
assert_eq!(vec![TopologyFlag::IoDevices], topology_with_flags.flags());
Source

pub fn depth(&self) -> u32

Returns the full depth of the topology.

In practice, the full depth of the topology equals the depth of the ObjectType::PU plus one.

The full topology depth is useful to know if one needs to manually traverse the complete topology.

§Examples
use hwloc::Topology;

let topology = Topology::new();
assert!(topology.depth() > 0);
Examples found in repository?
examples/walk_linear.rs (line 10)
7fn main() {
8    let topo = Topology::new();
9
10    for i in 0..topo.depth() {
11        println!("*** Objects at level {}", i);
12
13        for (idx, object) in topo.objects_at_depth(i).iter().enumerate() {
14            println!("{}: {}", idx, object);
15        }
16    }
17}
Source

pub fn depth_for_type( &self, object_type: &ObjectType, ) -> Result<u32, TypeDepthError>

Returns the depth for the given ObjectType.

§Examples
use hwloc::{Topology,ObjectType};

let topology = Topology::new();

let machine_depth = topology.depth_for_type(&ObjectType::Machine).unwrap();
let pu_depth = topology.depth_for_type(&ObjectType::PU).unwrap();
assert!(machine_depth < pu_depth);
§Failures

If hwloc can’t find the depth for the given ObjectType, this method will return an error from the TypeDepthError enum. See this one for more info on each specific error.

Note that for ObjectType::Bridge, ObjectType::PCIDevice and ObjectType::OSDevice, always an error will be returned which signals their virtual depth.

Examples found in repository?
examples/number_of_packages.rs (line 9)
6fn main() {
7    let topo = Topology::new();
8
9    let package_depth = topo.depth_for_type(&ObjectType::Package);
10    match package_depth {
11        Ok(depth) => println!("*** {} package(s)", topo.size_at_depth(depth)),
12        Err(TypeDepthError::TypeDepthUnknown) => println!("*** The number of packages is unknown"),
13        Err(e) => println!("Unknown Error: {:?}", e),
14    }
15}
Source

pub fn depth_or_below_for_type( &self, object_type: &ObjectType, ) -> Result<u32, TypeDepthError>

Examples found in repository?
examples/bind_process.rs (line 51)
50fn last_core(topo: &mut Topology) -> &TopologyObject {
51    let core_depth = topo.depth_or_below_for_type(&ObjectType::Core).unwrap();
52    let all_cores = topo.objects_at_depth(core_depth);
53    all_cores.last().unwrap()
54}
More examples
Hide additional examples
examples/bind_to_last_core.rs (line 49)
48fn last_core(topo: &mut Topology) -> &TopologyObject {
49    let core_depth = topo.depth_or_below_for_type(&ObjectType::Core).unwrap();
50    let all_cores = topo.objects_at_depth(core_depth);
51    all_cores.last().unwrap()
52}
Source

pub fn depth_or_above_for_type( &self, object_type: &ObjectType, ) -> Result<u32, TypeDepthError>

Source

pub fn type_at_depth(&self, depth: u32) -> ObjectType

Returns the corresponding ObjectType for the given depth.

§Examples
use hwloc::{Topology,ObjectType};

let topology = Topology::new();

// Load depth for PU to assert against
let pu_depth = topology.depth_for_type(&ObjectType::PU).unwrap();
// Retrieve the type for the given depth
assert_eq!(ObjectType::PU, topology.type_at_depth(pu_depth));
§Panics

This method will panic if the given depth is larger than the full depth minus one. It can’t be negative since its an unsigned integer, but be careful with the depth provided in general.

Source

pub fn size_at_depth(&self, depth: u32) -> u32

Returns the number of objects at the given depth.

§Examples
use hwloc::Topology;

let topology = Topology::new();

let topo_depth = topology.depth();
assert!(topology.size_at_depth(topo_depth - 1) > 0);
§Panics

This method will panic if the given depth is larger than the full depth minus one. It can’t be negative since its an unsigned integer, but be careful with the depth provided in general.

Examples found in repository?
examples/number_of_packages.rs (line 11)
6fn main() {
7    let topo = Topology::new();
8
9    let package_depth = topo.depth_for_type(&ObjectType::Package);
10    match package_depth {
11        Ok(depth) => println!("*** {} package(s)", topo.size_at_depth(depth)),
12        Err(TypeDepthError::TypeDepthUnknown) => println!("*** The number of packages is unknown"),
13        Err(e) => println!("Unknown Error: {:?}", e),
14    }
15}
Source

pub fn object_at_root(&self) -> &TopologyObject

Returns the TopologyObject at the root of the topology.

§Examples
use hwloc::{Topology,TopologyObject};

let topology = Topology::new();

assert_eq!(topology.type_at_root(), topology.object_at_root().object_type());
Examples found in repository?
examples/walk_tree.rs (line 10)
6fn main() {
7    let topo = Topology::new();
8
9    println!("*** Printing overall tree");
10    print_children(&topo, topo.object_at_root(), 0);
11}
Source

pub fn type_at_root(&self) -> ObjectType

Returns the ObjectType at the root of the topology.

This method is a convenient shorthand for type_at_depth(0).

§Examples
use hwloc::{Topology,ObjectType};

let topology = Topology::new();

let root_type = topology.type_at_root();
let depth_type = topology.type_at_depth(0);
assert_eq!(root_type, depth_type);
Source

pub fn objects_with_type( &self, object_type: &ObjectType, ) -> Result<Vec<&TopologyObject>, TypeDepthError>

Returns all TopologyObjects with the given ObjectType.

Examples found in repository?
examples/processor_cache.rs (line 10)
7fn main() {
8    let topo = Topology::new();
9
10    let pu = topo.objects_with_type(&ObjectType::PU).unwrap()[0];
11
12    let mut parent = pu.parent();
13    let mut levels = 0;
14    let mut size = 0;
15
16    while let Some(p) = parent {
17        if p.object_type() == ObjectType::Cache {
18            levels += 1;
19            // This should actually be size(), but there is a (compiler) bug? with the c-ffi unions
20            size += p.cache_attributes().unwrap().size;
21        }
22        parent = p.parent();
23    }
24
25    println!("*** Logical processor 0 has {} caches totalling {} KB",
26             levels,
27             size / 1024);
28}
More examples
Hide additional examples
examples/bind_threads.rs (line 30)
21fn main() {
22    let topo = Arc::new(Mutex::new(Topology::new()));
23
24    // Grab the number of cores in a block so that the lock is removed once
25    // the end of the block is reached.
26    let num_cores = {
27        let topo_rc = topo.clone();
28        let topo_locked = topo_rc.lock().unwrap();
29        (*topo_locked)
30            .objects_with_type(&ObjectType::Core)
31            .unwrap()
32            .len()
33    };
34    println!("Found {} cores.", num_cores);
35
36    // Spawn one thread for each and pass the topology down into scope.
37    let handles: Vec<_> = (0..num_cores)
38        .map(|i| {
39            let child_topo = topo.clone();
40            thread::spawn(move || {
41                // Get the current thread id and lock the topology to use.
42                let tid = get_thread_id();
43                let mut locked_topo = child_topo.lock().unwrap();
44
45                // Thread binding before explicit set.
46                let before = locked_topo.get_cpubind_for_thread(tid, CPUBIND_THREAD);
47
48                // load the cpuset for the given core index.
49                let mut bind_to = cpuset_for_core(&*locked_topo, i);
50
51                // Get only one logical processor (in case the core is SMT/hyper-threaded).
52                bind_to.singlify();
53
54                // Set the binding.
55                locked_topo
56                    .set_cpubind_for_thread(tid, bind_to, CPUBIND_THREAD)
57                    .unwrap();
58
59                // Thread binding after explicit set.
60                let after = locked_topo.get_cpubind_for_thread(tid, CPUBIND_THREAD);
61                println!("Thread {}: Before {:?}, After {:?}", i, before, after);
62            })
63        })
64        .collect();
65
66    // Wait for all threads to complete before ending the program.
67    for h in handles {
68        h.join().unwrap();
69    }
70}
71
72/// Load the `CpuSet` for the given core index.
73fn cpuset_for_core(topology: &Topology, idx: usize) -> CpuSet {
74    let cores = (*topology).objects_with_type(&ObjectType::Core).unwrap();
75    match cores.get(idx) {
76        Some(val) => val.cpuset().unwrap(),
77        None => panic!("No Core found with id {}", idx),
78    }
79}
Source

pub fn objects_at_depth(&self, depth: u32) -> Vec<&TopologyObject>

Returns all TopologyObjects at the given depth.

Examples found in repository?
examples/bind_process.rs (line 52)
50fn last_core(topo: &mut Topology) -> &TopologyObject {
51    let core_depth = topo.depth_or_below_for_type(&ObjectType::Core).unwrap();
52    let all_cores = topo.objects_at_depth(core_depth);
53    all_cores.last().unwrap()
54}
More examples
Hide additional examples
examples/bind_to_last_core.rs (line 50)
48fn last_core(topo: &mut Topology) -> &TopologyObject {
49    let core_depth = topo.depth_or_below_for_type(&ObjectType::Core).unwrap();
50    let all_cores = topo.objects_at_depth(core_depth);
51    all_cores.last().unwrap()
52}
examples/walk_linear.rs (line 13)
7fn main() {
8    let topo = Topology::new();
9
10    for i in 0..topo.depth() {
11        println!("*** Objects at level {}", i);
12
13        for (idx, object) in topo.objects_at_depth(i).iter().enumerate() {
14            println!("{}: {}", idx, object);
15        }
16    }
17}
Source

pub fn set_cpubind( &mut self, set: CpuSet, flags: CpuBindFlags, ) -> Result<(), CpuBindError>

Binds the current process or thread on CPUs given in the CpuSet.

Examples found in repository?
examples/bind_to_last_core.rs (line 35)
19fn main() {
20    let mut topo = Topology::new();
21
22    // Grab last core and exctract its CpuSet
23    let mut cpuset = last_core(&mut topo).cpuset().unwrap();
24
25    //  Get only one logical processor (in case the core is SMT/hyper-threaded).
26    cpuset.singlify();
27
28    // Print the current cpu binding before explicit setting
29    println!("Cpu Binding before explicit bind: {:?}",
30             topo.get_cpubind(CPUBIND_PROCESS));
31    println!("Cpu Location before explicit bind: {:?}",
32             topo.get_cpu_location(CPUBIND_PROCESS));
33
34    // Try to bind all threads of the current (possibly multithreaded) process.
35    match topo.set_cpubind(cpuset, CPUBIND_PROCESS) {
36        Ok(_) => println!("Correctly bound to last core"),
37        Err(e) => println!("Failed to bind: {:?}", e),
38    }
39
40    // Print the current cpu binding after explicit setting
41    println!("Cpu Binding after explicit bind: {:?}",
42             topo.get_cpubind(CPUBIND_PROCESS));
43    println!("Cpu Location after explicit bind: {:?}",
44             topo.get_cpu_location(CPUBIND_PROCESS));
45}
Source

pub fn get_cpubind(&self, flags: CpuBindFlags) -> Option<CpuSet>

Get current process or thread binding.

Examples found in repository?
examples/bind_to_last_core.rs (line 30)
19fn main() {
20    let mut topo = Topology::new();
21
22    // Grab last core and exctract its CpuSet
23    let mut cpuset = last_core(&mut topo).cpuset().unwrap();
24
25    //  Get only one logical processor (in case the core is SMT/hyper-threaded).
26    cpuset.singlify();
27
28    // Print the current cpu binding before explicit setting
29    println!("Cpu Binding before explicit bind: {:?}",
30             topo.get_cpubind(CPUBIND_PROCESS));
31    println!("Cpu Location before explicit bind: {:?}",
32             topo.get_cpu_location(CPUBIND_PROCESS));
33
34    // Try to bind all threads of the current (possibly multithreaded) process.
35    match topo.set_cpubind(cpuset, CPUBIND_PROCESS) {
36        Ok(_) => println!("Correctly bound to last core"),
37        Err(e) => println!("Failed to bind: {:?}", e),
38    }
39
40    // Print the current cpu binding after explicit setting
41    println!("Cpu Binding after explicit bind: {:?}",
42             topo.get_cpubind(CPUBIND_PROCESS));
43    println!("Cpu Location after explicit bind: {:?}",
44             topo.get_cpu_location(CPUBIND_PROCESS));
45}
Source

pub fn set_cpubind_for_process( &mut self, pid: pid_t, set: CpuSet, flags: CpuBindFlags, ) -> Result<(), CpuBindError>

Binds a process (identified by its pid) on CPUs identified by the given CpuSet.

Examples found in repository?
examples/bind_process.rs (line 36)
12fn main() {
13    let mut topo = Topology::new();
14
15    // load the current pid through libc
16    let pid = get_pid();
17
18    println!("Binding Process with PID {:?}", pid);
19
20    // Grab last core and exctract its CpuSet
21    let mut cpuset = last_core(&mut topo).cpuset().unwrap();
22
23    // Get only one logical processor (in case the core is SMT/hyper-threaded).
24    cpuset.singlify();
25
26    println!("Before Bind: {:?}",
27             topo.get_cpubind_for_process(pid, CPUBIND_PROCESS)
28                 .unwrap());
29
30    // Last CPU Location for this PID (not implemented on all systems)
31    if let Some(l) = topo.get_cpu_location_for_process(pid, CPUBIND_PROCESS) {
32        println!("Last Known CPU Location: {:?}", l);
33    }
34
35    // Bind to one core.
36    topo.set_cpubind_for_process(pid, cpuset, CPUBIND_PROCESS)
37        .unwrap();
38
39    println!("After Bind: {:?}",
40             topo.get_cpubind_for_process(pid, CPUBIND_PROCESS)
41                 .unwrap());
42
43    // Last CPU Location for this PID (not implemented on all systems)
44    if let Some(l) = topo.get_cpu_location_for_process(pid, CPUBIND_PROCESS) {
45        println!("Last Known CPU Location: {:?}", l);
46    }
47}
Source

pub fn get_cpubind_for_process( &self, pid: pid_t, flags: CpuBindFlags, ) -> Option<CpuSet>

Get the current physical binding of a process, identified by its pid.

Examples found in repository?
examples/bind_process.rs (line 27)
12fn main() {
13    let mut topo = Topology::new();
14
15    // load the current pid through libc
16    let pid = get_pid();
17
18    println!("Binding Process with PID {:?}", pid);
19
20    // Grab last core and exctract its CpuSet
21    let mut cpuset = last_core(&mut topo).cpuset().unwrap();
22
23    // Get only one logical processor (in case the core is SMT/hyper-threaded).
24    cpuset.singlify();
25
26    println!("Before Bind: {:?}",
27             topo.get_cpubind_for_process(pid, CPUBIND_PROCESS)
28                 .unwrap());
29
30    // Last CPU Location for this PID (not implemented on all systems)
31    if let Some(l) = topo.get_cpu_location_for_process(pid, CPUBIND_PROCESS) {
32        println!("Last Known CPU Location: {:?}", l);
33    }
34
35    // Bind to one core.
36    topo.set_cpubind_for_process(pid, cpuset, CPUBIND_PROCESS)
37        .unwrap();
38
39    println!("After Bind: {:?}",
40             topo.get_cpubind_for_process(pid, CPUBIND_PROCESS)
41                 .unwrap());
42
43    // Last CPU Location for this PID (not implemented on all systems)
44    if let Some(l) = topo.get_cpu_location_for_process(pid, CPUBIND_PROCESS) {
45        println!("Last Known CPU Location: {:?}", l);
46    }
47}
Source

pub fn set_cpubind_for_thread( &mut self, tid: pthread_t, set: CpuSet, flags: CpuBindFlags, ) -> Result<(), CpuBindError>

Bind a thread (by its tid) on CPUs given in through the CpuSet.

Examples found in repository?
examples/bind_threads.rs (line 56)
21fn main() {
22    let topo = Arc::new(Mutex::new(Topology::new()));
23
24    // Grab the number of cores in a block so that the lock is removed once
25    // the end of the block is reached.
26    let num_cores = {
27        let topo_rc = topo.clone();
28        let topo_locked = topo_rc.lock().unwrap();
29        (*topo_locked)
30            .objects_with_type(&ObjectType::Core)
31            .unwrap()
32            .len()
33    };
34    println!("Found {} cores.", num_cores);
35
36    // Spawn one thread for each and pass the topology down into scope.
37    let handles: Vec<_> = (0..num_cores)
38        .map(|i| {
39            let child_topo = topo.clone();
40            thread::spawn(move || {
41                // Get the current thread id and lock the topology to use.
42                let tid = get_thread_id();
43                let mut locked_topo = child_topo.lock().unwrap();
44
45                // Thread binding before explicit set.
46                let before = locked_topo.get_cpubind_for_thread(tid, CPUBIND_THREAD);
47
48                // load the cpuset for the given core index.
49                let mut bind_to = cpuset_for_core(&*locked_topo, i);
50
51                // Get only one logical processor (in case the core is SMT/hyper-threaded).
52                bind_to.singlify();
53
54                // Set the binding.
55                locked_topo
56                    .set_cpubind_for_thread(tid, bind_to, CPUBIND_THREAD)
57                    .unwrap();
58
59                // Thread binding after explicit set.
60                let after = locked_topo.get_cpubind_for_thread(tid, CPUBIND_THREAD);
61                println!("Thread {}: Before {:?}, After {:?}", i, before, after);
62            })
63        })
64        .collect();
65
66    // Wait for all threads to complete before ending the program.
67    for h in handles {
68        h.join().unwrap();
69    }
70}
Source

pub fn get_cpubind_for_thread( &self, tid: pthread_t, flags: CpuBindFlags, ) -> Option<CpuSet>

Get the current physical binding of thread tid.

Examples found in repository?
examples/bind_threads.rs (line 46)
21fn main() {
22    let topo = Arc::new(Mutex::new(Topology::new()));
23
24    // Grab the number of cores in a block so that the lock is removed once
25    // the end of the block is reached.
26    let num_cores = {
27        let topo_rc = topo.clone();
28        let topo_locked = topo_rc.lock().unwrap();
29        (*topo_locked)
30            .objects_with_type(&ObjectType::Core)
31            .unwrap()
32            .len()
33    };
34    println!("Found {} cores.", num_cores);
35
36    // Spawn one thread for each and pass the topology down into scope.
37    let handles: Vec<_> = (0..num_cores)
38        .map(|i| {
39            let child_topo = topo.clone();
40            thread::spawn(move || {
41                // Get the current thread id and lock the topology to use.
42                let tid = get_thread_id();
43                let mut locked_topo = child_topo.lock().unwrap();
44
45                // Thread binding before explicit set.
46                let before = locked_topo.get_cpubind_for_thread(tid, CPUBIND_THREAD);
47
48                // load the cpuset for the given core index.
49                let mut bind_to = cpuset_for_core(&*locked_topo, i);
50
51                // Get only one logical processor (in case the core is SMT/hyper-threaded).
52                bind_to.singlify();
53
54                // Set the binding.
55                locked_topo
56                    .set_cpubind_for_thread(tid, bind_to, CPUBIND_THREAD)
57                    .unwrap();
58
59                // Thread binding after explicit set.
60                let after = locked_topo.get_cpubind_for_thread(tid, CPUBIND_THREAD);
61                println!("Thread {}: Before {:?}, After {:?}", i, before, after);
62            })
63        })
64        .collect();
65
66    // Wait for all threads to complete before ending the program.
67    for h in handles {
68        h.join().unwrap();
69    }
70}
Source

pub fn get_cpu_location(&self, flags: CpuBindFlags) -> Option<CpuSet>

Get the last physical CPU where the current process or thread ran.

The operating system may move some tasks from one processor to another at any time according to their binding, so this function may return something that is already outdated.

Flags can include either CPUBIND_PROCESS or CPUBIND_THREAD to specify whether the query should be for the whole process (union of all CPUs on which all threads are running), or only the current thread. If the process is single-threaded, flags can be set to zero to let hwloc use whichever method is available on the underlying OS.

Examples found in repository?
examples/bind_to_last_core.rs (line 32)
19fn main() {
20    let mut topo = Topology::new();
21
22    // Grab last core and exctract its CpuSet
23    let mut cpuset = last_core(&mut topo).cpuset().unwrap();
24
25    //  Get only one logical processor (in case the core is SMT/hyper-threaded).
26    cpuset.singlify();
27
28    // Print the current cpu binding before explicit setting
29    println!("Cpu Binding before explicit bind: {:?}",
30             topo.get_cpubind(CPUBIND_PROCESS));
31    println!("Cpu Location before explicit bind: {:?}",
32             topo.get_cpu_location(CPUBIND_PROCESS));
33
34    // Try to bind all threads of the current (possibly multithreaded) process.
35    match topo.set_cpubind(cpuset, CPUBIND_PROCESS) {
36        Ok(_) => println!("Correctly bound to last core"),
37        Err(e) => println!("Failed to bind: {:?}", e),
38    }
39
40    // Print the current cpu binding after explicit setting
41    println!("Cpu Binding after explicit bind: {:?}",
42             topo.get_cpubind(CPUBIND_PROCESS));
43    println!("Cpu Location after explicit bind: {:?}",
44             topo.get_cpu_location(CPUBIND_PROCESS));
45}
Source

pub fn get_cpu_location_for_process( &self, pid: pid_t, flags: CpuBindFlags, ) -> Option<CpuSet>

Get the last physical CPU where a process ran.

The operating system may move some tasks from one processor to another at any time according to their binding, so this function may return something that is already outdated.

Examples found in repository?
examples/bind_process.rs (line 31)
12fn main() {
13    let mut topo = Topology::new();
14
15    // load the current pid through libc
16    let pid = get_pid();
17
18    println!("Binding Process with PID {:?}", pid);
19
20    // Grab last core and exctract its CpuSet
21    let mut cpuset = last_core(&mut topo).cpuset().unwrap();
22
23    // Get only one logical processor (in case the core is SMT/hyper-threaded).
24    cpuset.singlify();
25
26    println!("Before Bind: {:?}",
27             topo.get_cpubind_for_process(pid, CPUBIND_PROCESS)
28                 .unwrap());
29
30    // Last CPU Location for this PID (not implemented on all systems)
31    if let Some(l) = topo.get_cpu_location_for_process(pid, CPUBIND_PROCESS) {
32        println!("Last Known CPU Location: {:?}", l);
33    }
34
35    // Bind to one core.
36    topo.set_cpubind_for_process(pid, cpuset, CPUBIND_PROCESS)
37        .unwrap();
38
39    println!("After Bind: {:?}",
40             topo.get_cpubind_for_process(pid, CPUBIND_PROCESS)
41                 .unwrap());
42
43    // Last CPU Location for this PID (not implemented on all systems)
44    if let Some(l) = topo.get_cpu_location_for_process(pid, CPUBIND_PROCESS) {
45        println!("Last Known CPU Location: {:?}", l);
46    }
47}

Trait Implementations§

Source§

impl Default for Topology

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl Drop for Topology

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl Send for Topology

Source§

impl Sync for Topology

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.