rust/kernel/xarray.rs
Source file repositories/reference/linux-study-clean/rust/kernel/xarray.rs
File Facts
- System
- Linux kernel
- Corpus path
rust/kernel/xarray.rs- Extension
.rs- Size
- 9382 bytes
- Lines
- 284
- Domain
- Rust Kernel Layer
- Bucket
- Rust API Membrane
- Inferred role
- Rust Kernel Layer: implementation source
- Status
- source implementation candidate
Why This File Exists
Rust-side wrappers and abstractions around kernel C APIs, ownership contracts, allocation, synchronization, and module integration.
- Rust-side wrappers and abstractions around kernel C APIs, ownership contracts, allocation, synchronization, and module integration.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
- No C-style include directives detected by the generator.
Detected Declarations
function dropfunction Somefunction drop
Annotated Snippet
fn drop(self: Pin<&mut Self>) {
self.iter().for_each(|ptr| {
let ptr = ptr.as_ptr();
// SAFETY: `ptr` came from `T::into_foreign`.
//
// INVARIANT: we own the only reference to the array which is being dropped so the
// broken invariant is not observable on function exit.
drop(unsafe { T::from_foreign(ptr) })
});
// SAFETY: `self.xa` is always valid by the type invariant.
unsafe { bindings::xa_destroy(self.xa.get()) };
}
}
/// Flags passed to [`XArray::new`] to configure the array's allocation tracking behavior.
pub enum AllocKind {
/// Consider the first element to be at index 0.
Alloc,
/// Consider the first element to be at index 1.
Alloc1,
}
impl<T: ForeignOwnable> XArray<T> {
/// Creates a new initializer for this type.
pub fn new(kind: AllocKind) -> impl PinInit<Self> {
let flags = match kind {
AllocKind::Alloc => bindings::XA_FLAGS_ALLOC,
AllocKind::Alloc1 => bindings::XA_FLAGS_ALLOC1,
};
pin_init!(Self {
// SAFETY: `xa` is valid while the closure is called.
//
// INVARIANT: `xa` is initialized here to an empty, valid [`bindings::xarray`].
xa <- Opaque::ffi_init(|xa| unsafe {
bindings::xa_init_flags(xa, flags)
}),
_p: PhantomData,
})
}
fn iter(&self) -> impl Iterator<Item = NonNull<c_void>> + '_ {
let mut index = 0;
// SAFETY: `self.xa` is always valid by the type invariant.
iter::once(unsafe {
bindings::xa_find(self.xa.get(), &mut index, usize::MAX, bindings::XA_PRESENT)
})
.chain(iter::from_fn(move || {
// SAFETY: `self.xa` is always valid by the type invariant.
Some(unsafe {
bindings::xa_find_after(self.xa.get(), &mut index, usize::MAX, bindings::XA_PRESENT)
})
}))
.map_while(|ptr| NonNull::new(ptr.cast()))
}
/// Attempts to lock the [`XArray`] for exclusive access.
pub fn try_lock(&self) -> Option<Guard<'_, T>> {
// SAFETY: `self.xa` is always valid by the type invariant.
if (unsafe { bindings::xa_trylock(self.xa.get()) } != 0) {
Some(Guard {
xa: self,
_not_send: NotThreadSafe,
})
} else {
None
}
}
/// Locks the [`XArray`] for exclusive access.
pub fn lock(&self) -> Guard<'_, T> {
// SAFETY: `self.xa` is always valid by the type invariant.
unsafe { bindings::xa_lock(self.xa.get()) };
Guard {
xa: self,
_not_send: NotThreadSafe,
}
}
}
/// A lock guard.
///
/// The lock is unlocked when the guard goes out of scope.
#[must_use = "the lock unlocks immediately when the guard is unused"]
pub struct Guard<'a, T: ForeignOwnable> {
xa: &'a XArray<T>,
_not_send: NotThreadSafe,
}
Annotation
- Detected declarations: `function drop`, `function Some`, `function drop`.
- Atlas domain: Rust Kernel Layer / Rust API Membrane.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.