mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-10-22 23:13:01 +02:00
rust: cpu: Introduce CpuId abstraction
This adds abstraction for representing a CPU identifier. Suggested-by: Boqun Feng <boqun.feng@gmail.com> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
This commit is contained in:
parent
4823a58093
commit
ebf2e500e0
|
@ -6,6 +6,116 @@
|
||||||
|
|
||||||
use crate::{bindings, device::Device, error::Result, prelude::ENODEV};
|
use crate::{bindings, device::Device, error::Result, prelude::ENODEV};
|
||||||
|
|
||||||
|
/// Returns the maximum number of possible CPUs in the current system configuration.
|
||||||
|
#[inline]
|
||||||
|
pub fn nr_cpu_ids() -> u32 {
|
||||||
|
#[cfg(any(NR_CPUS_1, CONFIG_FORCE_NR_CPUS))]
|
||||||
|
{
|
||||||
|
bindings::NR_CPUS
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(any(NR_CPUS_1, CONFIG_FORCE_NR_CPUS)))]
|
||||||
|
// SAFETY: `nr_cpu_ids` is a valid global provided by the kernel.
|
||||||
|
unsafe {
|
||||||
|
bindings::nr_cpu_ids
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The CPU ID.
|
||||||
|
///
|
||||||
|
/// Represents a CPU identifier as a wrapper around an [`u32`].
|
||||||
|
///
|
||||||
|
/// # Invariants
|
||||||
|
///
|
||||||
|
/// The CPU ID lies within the range `[0, nr_cpu_ids())`.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use kernel::cpu::CpuId;
|
||||||
|
///
|
||||||
|
/// let cpu = 0;
|
||||||
|
///
|
||||||
|
/// // SAFETY: 0 is always a valid CPU number.
|
||||||
|
/// let id = unsafe { CpuId::from_u32_unchecked(cpu) };
|
||||||
|
///
|
||||||
|
/// assert_eq!(id.as_u32(), cpu);
|
||||||
|
/// assert!(CpuId::from_i32(0).is_some());
|
||||||
|
/// assert!(CpuId::from_i32(-1).is_none());
|
||||||
|
/// ```
|
||||||
|
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||||
|
pub struct CpuId(u32);
|
||||||
|
|
||||||
|
impl CpuId {
|
||||||
|
/// Creates a new [`CpuId`] from the given `id` without checking bounds.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// The caller must ensure that `id` is a valid CPU ID (i.e., `0 <= id < nr_cpu_ids()`).
|
||||||
|
#[inline]
|
||||||
|
pub unsafe fn from_i32_unchecked(id: i32) -> Self {
|
||||||
|
debug_assert!(id >= 0);
|
||||||
|
debug_assert!((id as u32) < nr_cpu_ids());
|
||||||
|
|
||||||
|
// INVARIANT: The function safety guarantees `id` is a valid CPU id.
|
||||||
|
Self(id as u32)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a new [`CpuId`] from the given `id`, checking that it is valid.
|
||||||
|
pub fn from_i32(id: i32) -> Option<Self> {
|
||||||
|
if id < 0 || id as u32 >= nr_cpu_ids() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
// INVARIANT: `id` has just been checked as a valid CPU ID.
|
||||||
|
Some(Self(id as u32))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a new [`CpuId`] from the given `id` without checking bounds.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// The caller must ensure that `id` is a valid CPU ID (i.e., `0 <= id < nr_cpu_ids()`).
|
||||||
|
#[inline]
|
||||||
|
pub unsafe fn from_u32_unchecked(id: u32) -> Self {
|
||||||
|
debug_assert!(id < nr_cpu_ids());
|
||||||
|
|
||||||
|
// Ensure the `id` fits in an [`i32`] as it's also representable that way.
|
||||||
|
debug_assert!(id <= i32::MAX as u32);
|
||||||
|
|
||||||
|
// INVARIANT: The function safety guarantees `id` is a valid CPU id.
|
||||||
|
Self(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a new [`CpuId`] from the given `id`, checking that it is valid.
|
||||||
|
pub fn from_u32(id: u32) -> Option<Self> {
|
||||||
|
if id >= nr_cpu_ids() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
// INVARIANT: `id` has just been checked as a valid CPU ID.
|
||||||
|
Some(Self(id))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns CPU number.
|
||||||
|
#[inline]
|
||||||
|
pub fn as_u32(&self) -> u32 {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<CpuId> for u32 {
|
||||||
|
fn from(id: CpuId) -> Self {
|
||||||
|
id.as_u32()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<CpuId> for i32 {
|
||||||
|
fn from(id: CpuId) -> Self {
|
||||||
|
id.as_u32() as i32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a new instance of CPU's device.
|
/// Creates a new instance of CPU's device.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
|
|
Loading…
Reference in New Issue
Block a user