rust/pin-init/README.md
Source file repositories/reference/linux-study-clean/rust/pin-init/README.md
File Facts
- System
- Linux kernel
- Corpus path
rust/pin-init/README.md- Extension
.md- Size
- 9844 bytes
- Lines
- 248
- Domain
- Rust Kernel Layer
- Bucket
- Rust API Membrane
- Inferred role
- Rust Kernel Layer: documentation
- Status
- atlas-only
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
struct Foostruct DriverDatafunction Err
Annotated Snippet
struct Foo {
#[pin]
a: CMutex<usize>,
b: u32,
}
let foo = pin_init!(Foo {
a <- CMutex::new(42),
b: 24,
});
```
`foo` now is of the type [`impl PinInit<Foo>`]. We can now use any smart pointer that we like
(or just the stack) to actually initialize a `Foo`:
```rust
let foo: Result<Pin<Box<Foo>>, AllocError> = Box::pin_init(foo);
```
For more information see the [`pin_init!`] macro.
### Using a custom function/macro that returns an initializer
Many types that use this library supply a function/macro that returns an initializer, because
the above method only works for types where you can access the fields.
```rust
let mtx: Result<Pin<Arc<CMutex<usize>>>, _> = Arc::pin_init(CMutex::new(42));
```
To declare an init macro/function you just return an [`impl PinInit<T, E>`]:
```rust
#[pin_data]
struct DriverData {
#[pin]
status: CMutex<i32>,
buffer: Box<[u8; 1_000_000]>,
}
impl DriverData {
fn new() -> impl PinInit<Self, Error> {
pin_init!(Self {
status <- CMutex::new(0),
buffer: Box::init(pin_init::init_zeroed())?,
}? Error)
}
}
```
### Manual creation of an initializer
Often when working with primitives the previous approaches are not sufficient. That is where
[`pin_init_from_closure()`] comes in. This `unsafe` function allows you to create a
[`impl PinInit<T, E>`] directly from a closure. Of course you have to ensure that the closure
actually does the initialization in the correct way. Here are the things to look out for
(we are calling the parameter to the closure `slot`):
- when the closure returns `Ok(())`, then it has completed the initialization successfully, so
`slot` now contains a valid bit pattern for the type `T`,
- when the closure returns `Err(e)`, then the caller may deallocate the memory at `slot`, so
you need to take care to clean up anything if your initialization fails mid-way,
- you may assume that `slot` will stay pinned even after the closure returns until `drop` of
`slot` gets called.
```rust
use pin_init::{pin_data, pinned_drop, PinInit, PinnedDrop, pin_init_from_closure};
use core::{
marker::PhantomPinned,
cell::UnsafeCell,
pin::Pin,
Annotation
- Detected declarations: `struct Foo`, `struct DriverData`, `function Err`.
- Atlas domain: Rust Kernel Layer / Rust API Membrane.
- Implementation status: atlas-only.
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.