#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
#[derive(Deserialize, Serialize)]
pub enum NumaNodeChoice
{
Any,
Specific(NumaNode),
}
impl Default for NumaNodeChoice
{
#[inline(always)]
fn default() -> Self
{
NumaNodeChoice::Any
}
}
impl Into<i32> for NumaNodeChoice
{
#[inline(always)]
fn into(self) -> i32
{
use self::NumaNodeChoice::*;
match self
{
Any => SOCKET_ID_ANY,
Specific(NumaNode(value)) => value as i32,
}
}
}
impl Into<u32> for NumaNodeChoice
{
#[inline(always)]
fn into(self) -> u32
{
use self::NumaNodeChoice::*;
match self
{
Any => ::std::u32::MAX,
Specific(NumaNode(value)) => value as u32,
}
}
}
impl NumaNodeChoice
{
#[inline(always)]
pub fn for_current_cpu() -> Self
{
Self::from_i32(unsafe { transmute(rte_socket_id()) })
}
#[inline(always)]
pub fn unwrap(self) -> NumaNode
{
self.expect("This is not a NUMA node")
}
#[inline(always)]
pub fn expect(self, message: &str) -> NumaNode
{
use self::NumaNodeChoice::*;
#[inline(never)]
#[cold]
fn expect_failed(message: &str) -> !
{
panic!("{}", message)
}
match self
{
Any => expect_failed(message),
Specific(numa_node) => numa_node,
}
}
#[inline(always)]
pub fn unwrap_or_default(self) -> NumaNode
{
use self::NumaNodeChoice::*;
match self
{
Any => NumaNode::default(),
Specific(numa_node) => numa_node,
}
}
#[inline(always)]
pub fn from_i32(value: i32) -> Self
{
use self::NumaNodeChoice::*;
if likely!(value >= 0)
{
debug_assert!((RTE_MAX_NUMA_NODES as u16) <= (::std::u8::MAX as u16), "RTE_MAX_NUMA_NODES '{}' exceeds ::std::u8::MAX '{}'; the DPDK API is broken", RTE_MAX_NUMA_NODES, ::std::u8::MAX);
assert!((value as u32) < (RTE_MAX_NUMA_NODES as u32), "value '{}' equals or exceeds RTE_MAX_NUMA_NODES '{}'", value, RTE_MAX_NUMA_NODES);
Specific(NumaNode(value as u8))
}
else if unlikely!(value == SOCKET_ID_ANY)
{
Any
}
else
{
panic!("value '{}' is invalid for a NUMA node", value)
}
}
#[inline(always)]
pub fn allocate_uninitialized<T>(&self, alignment_power_of_two: u32) -> Option<DpdkAllocatedMemory<T>>
{
debug_assert!(alignment_power_of_two.is_power_of_two(), "alignment_power_of_two '{}' is not a power of two", alignment_power_of_two);
debug_assert!(alignment_power_of_two >= NumaNode::CacheLineSize, "alignment_power_of_two '{}' is less than CacheLineSize '{}'", alignment_power_of_two, NumaNode::CacheLineSize);
use self::NumaNodeChoice::*;
match self
{
Specific(numa_node) => numa_node.allocate_uninitialized(alignment_power_of_two),
Any =>
{
let result = unsafe { rte_malloc(null(), size_of::<T>(), alignment_power_of_two) };
if unlikely!(result.is_null())
{
None
}
else
{
Some(DpdkAllocatedMemory(result as *mut T))
}
}
}
}
#[inline(always)]
pub fn allocate_zeroed<T>(&self, alignment_power_of_two: u32) -> Option<DpdkAllocatedMemory<T>>
{
debug_assert!(alignment_power_of_two.is_power_of_two(), "alignment_power_of_two '{}' is not a power of two", alignment_power_of_two);
debug_assert!(alignment_power_of_two >= NumaNode::CacheLineSize, "alignment_power_of_two '{}' is less than CacheLineSize '{}'", alignment_power_of_two, NumaNode::CacheLineSize);
use self::NumaNodeChoice::*;
match self
{
Specific(numa_node) => numa_node.allocate_zeroed(alignment_power_of_two),
Any =>
{
let result = unsafe { rte_zmalloc(null(), size_of::<T>(), alignment_power_of_two) };
if unlikely!(result.is_null())
{
None
}
else
{
Some(DpdkAllocatedMemory(result as *mut T))
}
}
}
}
#[inline(always)]
pub fn allocate_uninitialized_for_array<T>(&self, number_of_elements: usize, alignment_power_of_two: u32) -> Option<DpdkAllocatedMemory<T>>
{
debug_assert!(alignment_power_of_two.is_power_of_two(), "alignment_power_of_two '{}' is not a power of two", alignment_power_of_two);
debug_assert!(alignment_power_of_two >= NumaNode::CacheLineSize, "alignment_power_of_two '{}' is less than CacheLineSize '{}'", alignment_power_of_two, NumaNode::CacheLineSize);
use self::NumaNodeChoice::*;
match self
{
Specific(numa_node) => numa_node.allocate_uninitialized_for_array(number_of_elements, alignment_power_of_two),
Any =>
{
let result = unsafe { rte_calloc(null(), number_of_elements, size_of::<T>(), alignment_power_of_two) };
if unlikely!(result.is_null())
{
None
}
else
{
Some(DpdkAllocatedMemory(result as *mut T))
}
}
}
}
#[inline(always)]
pub fn zoned_virtual_memory_statistics(self, sys_path: &SysPath, proc_path: &ProcPath) -> io::Result<HashMap<VirtualMemoryStatisticName, u64>>
{
use self::NumaNodeChoice::*;
match self
{
Specific(numa_node) => numa_node.zoned_virtual_memory_statistics(sys_path),
Any => proc_path.global_zoned_virtual_memory_statistics(),
}
}
#[inline(always)]
pub fn memory_information(&self, sys_path: &SysPath, proc_path: &ProcPath, memory_information_name_prefix: &str) -> Result<MemoryInformation, MemoryInformationParseError>
{
use self::NumaNodeChoice::*;
match self
{
Specific(numa_node) => numa_node.memory_information(sys_path, memory_information_name_prefix),
Any => proc_path.memory_information(memory_information_name_prefix),
}
}
#[inline(always)]
pub fn unreserve_huge_pages(self, sys_path: &SysPath, huge_page_size: HugePageSize) -> io::Result<()>
{
use self::NumaNodeChoice::*;
match self
{
Specific(numa_node) => numa_node.unreserve_huge_pages(sys_path, huge_page_size),
Any => huge_page_size.unreserve_global_huge_pages(sys_path),
}
}
#[inline(always)]
pub fn reserve_huge_pages(self, sys_path: &SysPath, huge_page_size: HugePageSize, number_to_try_to_reserve: u64) -> io::Result<()>
{
use self::NumaNodeChoice::*;
match self
{
Specific(numa_node) => numa_node.reserve_huge_pages(sys_path, huge_page_size, number_to_try_to_reserve),
Any => huge_page_size.reserve_global_huge_pages(sys_path, number_to_try_to_reserve),
}
}
#[inline(always)]
pub fn number_of_huge_pages(self, sys_path: &SysPath, huge_page_size: HugePageSize) -> io::Result<u64>
{
use self::NumaNodeChoice::*;
match self
{
Specific(numa_node) => numa_node.number_of_huge_pages(sys_path, huge_page_size),
Any => huge_page_size.number_of_global_huge_pages(sys_path),
}
}
#[inline(always)]
pub fn number_of_free_global_huge_pages(self, sys_path: &SysPath, huge_page_size: HugePageSize) -> io::Result<u64>
{
use self::NumaNodeChoice::*;
match self
{
Specific(numa_node) => numa_node.number_of_free_global_huge_pages(sys_path, huge_page_size),
Any => huge_page_size.number_of_free_global_huge_pages(sys_path),
}
}
#[inline(always)]
pub fn number_of_surplus_huge_pages(self, sys_path: &SysPath, huge_page_size: HugePageSize) -> io::Result<u64>
{
use self::NumaNodeChoice::*;
match self
{
Specific(numa_node) => numa_node.number_of_surplus_huge_pages(sys_path, huge_page_size),
Any => huge_page_size.number_of_surplus_global_huge_pages(sys_path),
}
}
}