1b8a62b91Sopenharmony_ciuse crate::process::Pid; 2b8a62b91Sopenharmony_ciuse crate::{backend, io}; 3b8a62b91Sopenharmony_ci 4b8a62b91Sopenharmony_ci/// `CpuSet` represents a bit-mask of CPUs. 5b8a62b91Sopenharmony_ci/// 6b8a62b91Sopenharmony_ci/// `CpuSet`s are used by [`sched_setaffinity`] and [`sched_getaffinity`], for 7b8a62b91Sopenharmony_ci/// example. 8b8a62b91Sopenharmony_ci/// 9b8a62b91Sopenharmony_ci/// # References 10b8a62b91Sopenharmony_ci/// - [Linux] 11b8a62b91Sopenharmony_ci/// 12b8a62b91Sopenharmony_ci/// [Linux]: https://man7.org/linux/man-pages/man3/CPU_SET.3.html 13b8a62b91Sopenharmony_ci/// [`sched_setaffinity`]: crate::process::sched_setaffinity 14b8a62b91Sopenharmony_ci/// [`sched_getaffinity`]: crate::process::sched_getaffinity 15b8a62b91Sopenharmony_ci#[repr(C)] 16b8a62b91Sopenharmony_ci#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] 17b8a62b91Sopenharmony_cipub struct CpuSet { 18b8a62b91Sopenharmony_ci cpu_set: backend::process::types::RawCpuSet, 19b8a62b91Sopenharmony_ci} 20b8a62b91Sopenharmony_ci 21b8a62b91Sopenharmony_ciimpl CpuSet { 22b8a62b91Sopenharmony_ci /// The maximum number of CPU in `CpuSet`. 23b8a62b91Sopenharmony_ci pub const MAX_CPU: usize = backend::process::types::CPU_SETSIZE; 24b8a62b91Sopenharmony_ci 25b8a62b91Sopenharmony_ci /// Create a new and empty `CpuSet`. 26b8a62b91Sopenharmony_ci #[inline] 27b8a62b91Sopenharmony_ci pub fn new() -> Self { 28b8a62b91Sopenharmony_ci Self { 29b8a62b91Sopenharmony_ci cpu_set: backend::process::types::raw_cpu_set_new(), 30b8a62b91Sopenharmony_ci } 31b8a62b91Sopenharmony_ci } 32b8a62b91Sopenharmony_ci 33b8a62b91Sopenharmony_ci /// Test to see if a CPU is in the `CpuSet`. 34b8a62b91Sopenharmony_ci /// 35b8a62b91Sopenharmony_ci /// `field` is the CPU id to test. 36b8a62b91Sopenharmony_ci #[inline] 37b8a62b91Sopenharmony_ci pub fn is_set(&self, field: usize) -> bool { 38b8a62b91Sopenharmony_ci backend::process::cpu_set::CPU_ISSET(field, &self.cpu_set) 39b8a62b91Sopenharmony_ci } 40b8a62b91Sopenharmony_ci 41b8a62b91Sopenharmony_ci /// Add a CPU to `CpuSet`. 42b8a62b91Sopenharmony_ci /// 43b8a62b91Sopenharmony_ci /// `field` is the CPU id to add. 44b8a62b91Sopenharmony_ci #[inline] 45b8a62b91Sopenharmony_ci pub fn set(&mut self, field: usize) { 46b8a62b91Sopenharmony_ci backend::process::cpu_set::CPU_SET(field, &mut self.cpu_set) 47b8a62b91Sopenharmony_ci } 48b8a62b91Sopenharmony_ci 49b8a62b91Sopenharmony_ci /// Remove a CPU from `CpuSet`. 50b8a62b91Sopenharmony_ci /// 51b8a62b91Sopenharmony_ci /// `field` is the CPU id to remove. 52b8a62b91Sopenharmony_ci #[inline] 53b8a62b91Sopenharmony_ci pub fn unset(&mut self, field: usize) { 54b8a62b91Sopenharmony_ci backend::process::cpu_set::CPU_CLR(field, &mut self.cpu_set) 55b8a62b91Sopenharmony_ci } 56b8a62b91Sopenharmony_ci 57b8a62b91Sopenharmony_ci /// Count the number of CPUs set in the `CpuSet`. 58b8a62b91Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 59b8a62b91Sopenharmony_ci #[inline] 60b8a62b91Sopenharmony_ci pub fn count(&self) -> u32 { 61b8a62b91Sopenharmony_ci backend::process::cpu_set::CPU_COUNT(&self.cpu_set) 62b8a62b91Sopenharmony_ci } 63b8a62b91Sopenharmony_ci 64b8a62b91Sopenharmony_ci /// Zeroes the `CpuSet`. 65b8a62b91Sopenharmony_ci #[inline] 66b8a62b91Sopenharmony_ci pub fn clear(&mut self) { 67b8a62b91Sopenharmony_ci backend::process::cpu_set::CPU_ZERO(&mut self.cpu_set) 68b8a62b91Sopenharmony_ci } 69b8a62b91Sopenharmony_ci} 70b8a62b91Sopenharmony_ci 71b8a62b91Sopenharmony_ciimpl Default for CpuSet { 72b8a62b91Sopenharmony_ci #[inline] 73b8a62b91Sopenharmony_ci fn default() -> Self { 74b8a62b91Sopenharmony_ci Self::new() 75b8a62b91Sopenharmony_ci } 76b8a62b91Sopenharmony_ci} 77b8a62b91Sopenharmony_ci 78b8a62b91Sopenharmony_ci/// `sched_setaffinity(pid, cpuset)`—Set a thread's CPU affinity mask. 79b8a62b91Sopenharmony_ci/// 80b8a62b91Sopenharmony_ci/// `pid` is the thread ID to update. If pid is `None`, then the current thread 81b8a62b91Sopenharmony_ci/// is updated. 82b8a62b91Sopenharmony_ci/// 83b8a62b91Sopenharmony_ci/// The `CpuSet` argument specifies the set of CPUs on which the thread will 84b8a62b91Sopenharmony_ci/// be eligible to run. 85b8a62b91Sopenharmony_ci/// 86b8a62b91Sopenharmony_ci/// # References 87b8a62b91Sopenharmony_ci/// - [Linux] 88b8a62b91Sopenharmony_ci/// 89b8a62b91Sopenharmony_ci/// [Linux]: https://man7.org/linux/man-pages/man2/sched_setaffinity.2.html 90b8a62b91Sopenharmony_ci#[inline] 91b8a62b91Sopenharmony_cipub fn sched_setaffinity(pid: Option<Pid>, cpuset: &CpuSet) -> io::Result<()> { 92b8a62b91Sopenharmony_ci backend::process::syscalls::sched_setaffinity(pid, &cpuset.cpu_set) 93b8a62b91Sopenharmony_ci} 94b8a62b91Sopenharmony_ci 95b8a62b91Sopenharmony_ci/// `sched_getaffinity(pid)`—Get a thread's CPU affinity mask. 96b8a62b91Sopenharmony_ci/// 97b8a62b91Sopenharmony_ci/// `pid` is the thread ID to check. If pid is `None`, then the current thread 98b8a62b91Sopenharmony_ci/// is checked. 99b8a62b91Sopenharmony_ci/// 100b8a62b91Sopenharmony_ci/// Returns the set of CPUs on which the thread is eligible to run. 101b8a62b91Sopenharmony_ci/// 102b8a62b91Sopenharmony_ci/// # References 103b8a62b91Sopenharmony_ci/// - [Linux] 104b8a62b91Sopenharmony_ci/// 105b8a62b91Sopenharmony_ci/// [Linux]: https://man7.org/linux/man-pages/man2/sched_getaffinity.2.html 106b8a62b91Sopenharmony_ci#[inline] 107b8a62b91Sopenharmony_cipub fn sched_getaffinity(pid: Option<Pid>) -> io::Result<CpuSet> { 108b8a62b91Sopenharmony_ci let mut cpuset = CpuSet::new(); 109b8a62b91Sopenharmony_ci backend::process::syscalls::sched_getaffinity(pid, &mut cpuset.cpu_set).and(Ok(cpuset)) 110b8a62b91Sopenharmony_ci} 111