#[derive(Default, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[derive(Deserialize, Serialize)]
#[repr(transparent)]
pub struct NumaNodes(pub BitSet<NumaNode>);
impl Deref for NumaNodes
{
type Target = BitSet<NumaNode>;
#[inline(always)]
fn deref(&self) -> &Self::Target
{
&self.0
}
}
impl DerefMut for NumaNodes
{
#[inline(always)]
fn deref_mut(&mut self) -> &mut Self::Target
{
&mut self.0
}
}
impl NumaNodes
{
#[inline(always)]
pub fn valid(sys_path: &SysPath, proc_path: &ProcPath) -> Option<Self>
{
let mut valid = Self::has_a_folder_path(sys_path)?;
valid.intersection(&Self::is_in_proc_self_status(proc_path));
valid.intersection(&Self::have_at_least_one_cpu(sys_path).unwrap());
valid.intersection(&Self::possible(sys_path).unwrap());
valid.intersection(&Self::online(sys_path).unwrap());
valid.intersection(&Self::have_normal_memory(sys_path).unwrap());
assert!(!valid.is_empty());
valid.shrink_to_fit();
Some(valid)
}
#[inline(always)]
pub fn set_affinity(&self, path: impl AsRef<Path>) -> io::Result<()>
{
assert_effective_user_id_is_root("write affinity to path");
let path = path.as_ref();
if path.exists()
{
let mask = IntoBitMask(self);
path.write_value(mask)
}
else
{
Ok(())
}
}
#[inline(always)]
pub fn set_affinity_list(&self, path: impl AsRef<Path>) -> io::Result<()>
{
assert_effective_user_id_is_root("write affinity to path");
let path = path.as_ref();
if path.exists()
{
let list = IntoList(&self.0);
path.write_value(list)
}
else
{
Ok(())
}
}
#[inline(always)]
fn has_a_folder_path(sys_path: &SysPath) -> Option<Self>
{
sys_path.numa_nodes_folder_path().entries_in_folder_path().unwrap().map(|bit_set| Self(bit_set))
}
#[inline(always)]
fn is_in_proc_self_status(proc_path: &ProcPath) -> Self
{
let process_status_statistics = Status::self_status(proc_path).unwrap();
process_status_statistics.numa_nodes_allowed
}
#[inline(always)]
fn have_at_least_one_cpu(sys_path: &SysPath) -> Option<Self>
{
Self::read_numa_node_list(sys_path, "has_cpu")
}
#[inline(always)]
pub(crate) fn possible(sys_path: &SysPath) -> Option<Self>
{
Self::read_numa_node_list(sys_path, "possible")
}
#[inline(always)]
fn online(sys_path: &SysPath) -> Option<Self>
{
Self::read_numa_node_list(sys_path, "online")
}
#[inline(always)]
fn have_normal_memory(sys_path: &SysPath) -> Option<Self>
{
Self::read_numa_node_list(sys_path, "has_normal_memory")
}
#[inline(always)]
pub fn have_movable_memory(sys_path: &SysPath) -> Option<Self>
{
Self::read_numa_node_list(sys_path, "has_memory")
}
#[inline(always)]
pub fn have_high_memory(sys_path: &SysPath) -> Option<Self>
{
Self::read_numa_node_list(sys_path, "has_high_memory")
}
#[inline(always)]
fn read_numa_node_list(sys_path: &SysPath, file_name: &str) -> Option<Self>
{
let file_path = sys_path.numa_nodes_path(file_name);
file_path.read_hyper_thread_or_numa_node_list_if_exists().unwrap().map(Self)
}
}