#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct NodeIndex(pub(crate) u8);
impl Index for NodeIndex
{
#[inline(always)]
fn to_c_uint(&self) -> c_uint
{
self.0 as c_uint
}
}
impl Default for NodeIndex
{
#[inline(always)]
fn default() -> Self
{
NodeIndex(0)
}
}
impl NodeIndex
{
#[inline(always)]
pub fn new(value: u8) -> Self
{
NodeIndex(value)
}
#[inline(always)]
pub fn number_of_nodes_in_nodemask() -> usize
{
match unsafe { numa_num_possible_nodes() }
{
x if x.is_negative() => panic!("numa_num_possible_nodes returned a negative value {}", x),
x @ _ => x as usize,
}
}
#[inline(always)]
pub fn number_of_nodes_permitted() -> usize
{
match unsafe { numa_num_task_nodes() }
{
x if x.is_negative() => panic!("numa_num_task_nodes returned a negative value {}", x),
0 => panic!("numa_num_task_nodes returned 0"),
x @ _ => x as usize,
}
}
pub fn number_of_node_configured() -> usize
{
match unsafe { numa_num_configured_nodes() }
{
x if x.is_negative() => panic!("numa_num_configured_nodes returned a negative value {}", x),
0 => panic!("numa_num_configured_nodes returned 0"),
x @ _ => x as usize,
}
}
#[inline(always)]
pub fn highest_possible() -> Self
{
match unsafe { numa_max_possible_node() }
{
x if x.is_negative() => panic!("numa_max_possible_node returned a negative value {}", x),
x if x > 255 => panic!("Wow, a node index greater than 255 should be impossible"),
x @ _ => NodeIndex(x as u8),
}
}
pub fn highest_available_currently() -> Self
{
match unsafe { numa_max_node() }
{
x if x.is_negative() => panic!("numa_max_node returned a negative value {}", x),
x if x > 255 => panic!("Wow, a node index greater than 255 should be impossible"),
x @ _ => NodeIndex(x as u8),
}
}
#[inline(always)]
pub fn preferred() -> Self
{
match unsafe { numa_preferred() }
{
x if x.is_negative() => panic!("numa_preferred returned a negative value {}", x),
x if x > 255 => panic!("Wow, a node index greater than 255 should be impossible"),
x @ _ => NodeIndex(x as u8),
}
}
#[inline(always)]
pub fn interleaved() -> Self
{
match unsafe { numa_get_interleave_node() }
{
x if x.is_negative() => panic!("numa_get_interleave_node returned a negative value {}", x),
x if x > 255 => panic!("Wow, a node index greater than 255 should be impossible"),
x @ _ => NodeIndex(x as u8),
}
}
#[inline(always)]
pub fn allows_try_to_allocate_from_this_node_for_the_current_thread_before_falling_back_to_other_nodes(&self)
{
unsafe { numa_set_preferred(self.0 as c_int) }
}
pub fn distance(&self, to: &NodeIndex) -> Option<u8>
{
match unsafe { numa_distance(self.0 as c_int, to.0 as c_int) }
{
0 => None,
x if x.is_negative() => panic!("numa_distance returned a negative value {}", x),
x if x % 10 == 0 => Some(((x as u64 / 10) - 1) as u8),
x @ _ => panic!("numa_distance returned a-non-power-of-ten factor {}", x),
}
}
pub fn size(&self) -> (usize, usize)
{
let mut free: c_longlong = unsafe { uninitialized() };
let free_pointer: *mut c_longlong = &mut free;
match unsafe { numa_node_size64(self.0 as c_int, free_pointer) }
{
-1 => panic!("numa_node_size64 returned an error"),
x if x.is_negative() => panic!("numa_node_size64 returned a negative memory size {}", x),
size @ _ =>
{
if free.is_negative()
{
panic!("numa_node_size64 returned a negative free memory size {}", free);
}
(size as usize, free as usize)
},
}
}
pub fn run_current_thread_on_this(&self)
{
match unsafe { numa_run_on_node(self.0 as c_int) }
{
0 => (),
-1 => match errno().0
{
::libc::EFAULT => panic!("numa_run_on_node EFAULT"),
::libc::EINVAL => panic!("numa_run_on_node EINVAL - is the NodeIndex value in range?"), ::libc::EPERM => panic!("numa_run_on_node EPERM"),
::libc::ESRCH => panic!("numa_run_on_node ESRCH"),
unexpected @ _ => panic!("numa_run_on_node set an unexpected errno {}; this is possible because not all paths in its code seem to set errno", unexpected),
},
unexpected @ _ => panic!("numa_run_on_node returned unexpected value {}", unexpected),
}
}
pub fn run_on_any_cpu()
{
match unsafe { numa_run_on_node(-1) }
{
0 => (),
-1 => match errno().0
{
::libc::EFAULT => panic!("numa_run_on_node EFAULT"),
::libc::EINVAL => panic!("numa_run_on_node EINVAL"),
::libc::EPERM => panic!("numa_run_on_node EPERM"),
::libc::ESRCH => panic!("numa_run_on_node ESRCH"),
unexpected @ _ => panic!("numa_run_on_node set an unexpected errno {}; this is possible because not all paths in its code seem to set errno", unexpected),
},
unexpected @ _ => panic!("numa_run_on_node returned unexpected value {}", unexpected),
}
}
#[inline(always)]
pub fn allocate(&self, size: size_t) -> NumaMemory
{
NumaMemory::wrap(unsafe { numa_alloc_onnode(size, self.0 as c_int) }, size)
}
pub fn node_to_cpus(&mut self) -> CpuMask
{
let cpu_mask = CpuMask::allocate();
match unsafe { numa_node_to_cpus(self.0 as c_int, (cpu_mask.0).0) }
{
0 => cpu_mask,
-1 => match errno().0
{
::libc::ERANGE => panic!("numa_node_to_cpus ERANGE"),
unexpected @ _ => panic!("numa_node_to_cpus set an unexpected errno {}", unexpected),
},
unexpected @ _ => panic!("numa_node_to_cpus returned unexpected value {}", unexpected),
}
}
}