use libc::{c_int, c_uint, c_ulonglong, c_char};
use {pid_t, pthread_t};
use num::{ToPrimitive, FromPrimitive};
use topology_object::TopologyObject;
use bitmap::IntHwlocBitmap;
use std::cmp::{PartialOrd, Ordering};
use support::TopologySupport;
pub enum HwlocTopology {}
#[repr(u32)]
#[derive(Debug,Clone)]
pub enum ObjectType {
System,
Machine,
NUMANode,
Package,
Cache,
Core,
PU,
Group,
Misc,
Bridge,
PCIDevice,
OSDevice,
TypeMax,
}
impl PartialOrd for ObjectType {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
let compared = unsafe { hwloc_compare_types(self.clone(), other.clone()) };
match compared {
c if c < 0 => Some(Ordering::Less),
c if c == 0 => Some(Ordering::Equal),
c if c > 0 => Some(Ordering::Greater),
_ => None,
}
}
}
impl PartialEq for ObjectType {
fn eq(&self, other: &Self) -> bool {
match self.partial_cmp(other) {
Some(Ordering::Equal) => true,
_ => false,
}
}
}
#[derive(Debug,PartialEq)]
pub enum TypeDepthError {
TypeDepthUnknown = -1,
TypeDepthMultiple = -2,
TypeDepthBridge = -3,
TypeDepthPCIDevice = -4,
TypeDepthOSDevice = -5,
Unkown = -99,
}
const TOPOLOGY_FLAG_WHOLE_SYSTEM: i64 = 1;
const TOPOLOGY_FLAG_IS_THIS_SYSTEM: i64 = 2;
const TOPOLOGY_FLAG_IO_DEVICES: i64 = 4;
const TOPOLOGY_FLAG_IO_BRIDGES: i64 = 8;
const TOPOLOGY_FLAG_WHOLE_IO: i64 = 16;
const TOPOLOGY_FLAG_I_CACHES: i64 = 32;
#[derive(Debug,PartialEq)]
pub enum TopologyFlag {
WholeSystem = TOPOLOGY_FLAG_WHOLE_SYSTEM as isize,
IsThisSystem = TOPOLOGY_FLAG_IS_THIS_SYSTEM as isize,
IoDevices = TOPOLOGY_FLAG_IO_DEVICES as isize,
IoBridges = TOPOLOGY_FLAG_IO_BRIDGES as isize,
WholeIo = TOPOLOGY_FLAG_WHOLE_IO as isize,
ICaches = TOPOLOGY_FLAG_I_CACHES as isize,
}
impl ToPrimitive for TopologyFlag {
fn to_i64(&self) -> Option<i64> {
match *self {
TopologyFlag::WholeSystem => Some(TopologyFlag::WholeSystem as i64),
TopologyFlag::IsThisSystem => Some(TopologyFlag::IsThisSystem as i64),
TopologyFlag::IoDevices => Some(TopologyFlag::IoDevices as i64),
TopologyFlag::IoBridges => Some(TopologyFlag::IoBridges as i64),
TopologyFlag::WholeIo => Some(TopologyFlag::WholeIo as i64),
TopologyFlag::ICaches => Some(TopologyFlag::ICaches as i64),
}
}
fn to_u64(&self) -> Option<u64> {
self.to_i64().and_then(|x| x.to_u64())
}
}
impl FromPrimitive for TopologyFlag {
fn from_i64(n: i64) -> Option<Self> {
match n {
TOPOLOGY_FLAG_WHOLE_SYSTEM => Some(TopologyFlag::WholeSystem),
TOPOLOGY_FLAG_IS_THIS_SYSTEM => Some(TopologyFlag::IsThisSystem),
TOPOLOGY_FLAG_IO_DEVICES => Some(TopologyFlag::IoDevices),
TOPOLOGY_FLAG_IO_BRIDGES => Some(TopologyFlag::IoBridges),
TOPOLOGY_FLAG_WHOLE_IO => Some(TopologyFlag::WholeIo),
TOPOLOGY_FLAG_I_CACHES => Some(TopologyFlag::ICaches),
_ => None,
}
}
fn from_u64(n: u64) -> Option<Self> {
FromPrimitive::from_i64(n as i64)
}
}
#[cfg(target_os = "windows")]
#[link(name = "libhwloc")]
extern "C" {
pub fn hwloc_topology_init(topology: *mut *mut HwlocTopology) -> c_int;
pub fn hwloc_topology_load(topology: *mut HwlocTopology) -> c_int;
pub fn hwloc_topology_destroy(topology: *mut HwlocTopology);
pub fn hwloc_topology_set_flags(topology: *mut HwlocTopology, flags: c_ulonglong) -> c_int;
pub fn hwloc_topology_get_flags(topology: *mut HwlocTopology) -> c_ulonglong;
pub fn hwloc_topology_get_support(topology: *mut HwlocTopology) -> *const TopologySupport;
pub fn hwloc_topology_get_depth(topology: *mut HwlocTopology) -> c_uint;
pub fn hwloc_get_type_depth(topology: *mut HwlocTopology, object_type: ObjectType) -> c_int;
pub fn hwloc_get_depth_type(topology: *mut HwlocTopology, depth: c_uint) -> ObjectType;
pub fn hwloc_get_nbobjs_by_depth(topology: *mut HwlocTopology, depth: c_uint) -> c_uint;
pub fn hwloc_get_obj_by_depth(topology: *mut HwlocTopology,
depth: c_uint,
idx: c_uint)
-> *mut TopologyObject;
pub fn hwloc_set_cpubind(topology: *mut HwlocTopology,
set: *const IntHwlocBitmap,
flags: c_int)
-> c_int;
pub fn hwloc_get_cpubind(topology: *mut HwlocTopology,
set: *mut IntHwlocBitmap,
flags: c_int)
-> c_int;
pub fn hwloc_get_last_cpu_location(topology: *mut HwlocTopology,
set: *mut IntHwlocBitmap,
flags: c_int)
-> c_int;
pub fn hwloc_get_proc_last_cpu_location(topology: *mut HwlocTopology,
pid: pid_t,
set: *mut IntHwlocBitmap,
flags: c_int)
-> c_int;
pub fn hwloc_set_proc_cpubind(topology: *mut HwlocTopology,
pid: pid_t,
set: *const IntHwlocBitmap,
flags: c_int)
-> c_int;
pub fn hwloc_get_proc_cpubind(topology: *mut HwlocTopology,
pid: pid_t,
set: *mut IntHwlocBitmap,
flags: c_int)
-> c_int;
pub fn hwloc_set_thread_cpubind(topology: *mut HwlocTopology,
thread: pthread_t,
set: *const IntHwlocBitmap,
flags: c_int)
-> c_int;
pub fn hwloc_get_thread_cpubind(topology: *mut HwlocTopology,
pid: pthread_t,
set: *mut IntHwlocBitmap,
flags: c_int)
-> c_int;
pub fn hwloc_bitmap_alloc() -> *mut IntHwlocBitmap;
pub fn hwloc_bitmap_alloc_full() -> *mut IntHwlocBitmap;
pub fn hwloc_bitmap_free(bitmap: *mut IntHwlocBitmap);
pub fn hwloc_bitmap_list_asprintf(strp: *mut *mut c_char,
bitmap: *const IntHwlocBitmap)
-> c_int;
pub fn hwloc_bitmap_set(bitmap: *mut IntHwlocBitmap, id: c_uint);
pub fn hwloc_bitmap_set_range(bitmap: *mut IntHwlocBitmap, begin: c_uint, end: c_int);
pub fn hwloc_bitmap_clr(bitmap: *mut IntHwlocBitmap, id: c_uint);
pub fn hwloc_bitmap_clr_range(bitmap: *mut IntHwlocBitmap, begin: c_uint, end: c_int);
pub fn hwloc_bitmap_weight(bitmap: *const IntHwlocBitmap) -> c_int;
pub fn hwloc_bitmap_zero(bitmap: *mut IntHwlocBitmap);
pub fn hwloc_bitmap_iszero(bitmap: *const IntHwlocBitmap) -> c_int;
pub fn hwloc_bitmap_isset(bitmap: *const IntHwlocBitmap, id: c_uint) -> c_int;
pub fn hwloc_bitmap_singlify(bitmap: *mut IntHwlocBitmap);
pub fn hwloc_bitmap_not(result: *mut IntHwlocBitmap, bitmap: *const IntHwlocBitmap);
pub fn hwloc_bitmap_first(bitmap: *const IntHwlocBitmap) -> c_int;
pub fn hwloc_bitmap_last(bitmap: *const IntHwlocBitmap) -> c_int;
pub fn hwloc_bitmap_dup(src: *const IntHwlocBitmap) -> *mut IntHwlocBitmap;
pub fn hwloc_bitmap_compare(left: *const IntHwlocBitmap,
right: *const IntHwlocBitmap)
-> c_int;
pub fn hwloc_bitmap_isequal(left: *const IntHwlocBitmap,
right: *const IntHwlocBitmap)
-> c_int;
pub fn hwloc_bitmap_isfull(bitmap: *const IntHwlocBitmap) -> c_int;
pub fn hwloc_bitmap_next(bitmap: *const IntHwlocBitmap, prev: c_int) -> c_int;
pub fn hwloc_obj_type_snprintf(into: *mut c_char,
size: c_int,
object: *const TopologyObject,
verbose: bool)
-> c_int;
pub fn hwloc_obj_attr_snprintf(into: *mut c_char,
size: c_int,
object: *const TopologyObject,
separator: *const c_char,
verbose: bool)
-> c_int;
pub fn hwloc_compare_types(type1: ObjectType, type2: ObjectType) -> c_int;
}
#[cfg(not(target_os = "windows"))]
#[link(name = "hwloc")]
extern "C" {
pub fn hwloc_topology_init(topology: *mut *mut HwlocTopology) -> c_int;
pub fn hwloc_topology_load(topology: *mut HwlocTopology) -> c_int;
pub fn hwloc_topology_destroy(topology: *mut HwlocTopology);
pub fn hwloc_topology_set_flags(topology: *mut HwlocTopology, flags: c_ulonglong) -> c_int;
pub fn hwloc_topology_get_flags(topology: *mut HwlocTopology) -> c_ulonglong;
pub fn hwloc_topology_get_support(topology: *mut HwlocTopology) -> *const TopologySupport;
pub fn hwloc_topology_get_depth(topology: *mut HwlocTopology) -> c_uint;
pub fn hwloc_get_type_depth(topology: *mut HwlocTopology, object_type: ObjectType) -> c_int;
pub fn hwloc_get_depth_type(topology: *mut HwlocTopology, depth: c_uint) -> ObjectType;
pub fn hwloc_get_nbobjs_by_depth(topology: *mut HwlocTopology, depth: c_uint) -> c_uint;
pub fn hwloc_get_obj_by_depth(topology: *mut HwlocTopology,
depth: c_uint,
idx: c_uint)
-> *mut TopologyObject;
pub fn hwloc_set_cpubind(topology: *mut HwlocTopology,
set: *const IntHwlocBitmap,
flags: c_int)
-> c_int;
pub fn hwloc_get_cpubind(topology: *mut HwlocTopology,
set: *mut IntHwlocBitmap,
flags: c_int)
-> c_int;
pub fn hwloc_get_last_cpu_location(topology: *mut HwlocTopology,
set: *mut IntHwlocBitmap,
flags: c_int)
-> c_int;
pub fn hwloc_get_proc_last_cpu_location(topology: *mut HwlocTopology,
pid: pid_t,
set: *mut IntHwlocBitmap,
flags: c_int)
-> c_int;
pub fn hwloc_set_proc_cpubind(topology: *mut HwlocTopology,
pid: pid_t,
set: *const IntHwlocBitmap,
flags: c_int)
-> c_int;
pub fn hwloc_get_proc_cpubind(topology: *mut HwlocTopology,
pid: pid_t,
set: *mut IntHwlocBitmap,
flags: c_int)
-> c_int;
pub fn hwloc_set_thread_cpubind(topology: *mut HwlocTopology,
thread: pthread_t,
set: *const IntHwlocBitmap,
flags: c_int)
-> c_int;
pub fn hwloc_get_thread_cpubind(topology: *mut HwlocTopology,
pid: pthread_t,
set: *mut IntHwlocBitmap,
flags: c_int)
-> c_int;
pub fn hwloc_bitmap_alloc() -> *mut IntHwlocBitmap;
pub fn hwloc_bitmap_alloc_full() -> *mut IntHwlocBitmap;
pub fn hwloc_bitmap_free(bitmap: *mut IntHwlocBitmap);
pub fn hwloc_bitmap_list_asprintf(strp: *mut *mut c_char,
bitmap: *const IntHwlocBitmap)
-> c_int;
pub fn hwloc_bitmap_set(bitmap: *mut IntHwlocBitmap, id: c_uint);
pub fn hwloc_bitmap_set_range(bitmap: *mut IntHwlocBitmap, begin: c_uint, end: c_int);
pub fn hwloc_bitmap_clr(bitmap: *mut IntHwlocBitmap, id: c_uint);
pub fn hwloc_bitmap_clr_range(bitmap: *mut IntHwlocBitmap, begin: c_uint, end: c_int);
pub fn hwloc_bitmap_weight(bitmap: *const IntHwlocBitmap) -> c_int;
pub fn hwloc_bitmap_zero(bitmap: *mut IntHwlocBitmap);
pub fn hwloc_bitmap_iszero(bitmap: *const IntHwlocBitmap) -> c_int;
pub fn hwloc_bitmap_isset(bitmap: *const IntHwlocBitmap, id: c_uint) -> c_int;
pub fn hwloc_bitmap_singlify(bitmap: *mut IntHwlocBitmap);
pub fn hwloc_bitmap_not(result: *mut IntHwlocBitmap, bitmap: *const IntHwlocBitmap);
pub fn hwloc_bitmap_first(bitmap: *const IntHwlocBitmap) -> c_int;
pub fn hwloc_bitmap_last(bitmap: *const IntHwlocBitmap) -> c_int;
pub fn hwloc_bitmap_dup(src: *const IntHwlocBitmap) -> *mut IntHwlocBitmap;
pub fn hwloc_bitmap_compare(left: *const IntHwlocBitmap,
right: *const IntHwlocBitmap)
-> c_int;
pub fn hwloc_bitmap_isequal(left: *const IntHwlocBitmap,
right: *const IntHwlocBitmap)
-> c_int;
pub fn hwloc_bitmap_isfull(bitmap: *const IntHwlocBitmap) -> c_int;
pub fn hwloc_bitmap_next(bitmap: *const IntHwlocBitmap, prev: c_int) -> c_int;
pub fn hwloc_obj_type_snprintf(into: *mut c_char,
size: c_int,
object: *const TopologyObject,
verbose: bool)
-> c_int;
pub fn hwloc_obj_attr_snprintf(into: *mut c_char,
size: c_int,
object: *const TopologyObject,
separator: *const c_char,
verbose: bool)
-> c_int;
pub fn hwloc_compare_types(type1: ObjectType, type2: ObjectType) -> c_int;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn should_convert_flag_to_primitive() {
assert_eq!(1, TopologyFlag::WholeSystem as u64);
assert_eq!(16, TopologyFlag::WholeIo as u64);
}
#[test]
fn should_compare_object_types() {
assert!(ObjectType::Machine == ObjectType::Machine);
assert!(ObjectType::PU == ObjectType::PU);
assert!(ObjectType::Machine < ObjectType::PU);
assert!(ObjectType::PU > ObjectType::Cache);
}
}