Skip to content

Commit

Permalink
update documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
y86-dev committed Apr 14, 2024
1 parent a09147c commit b3a3393
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 42 deletions.
19 changes: 11 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

Library to safely and fallibly initialize pinned `struct`s using in-place constructors.

[Pinning][pinning] is Rust's way of ensuring data does not move.

It also allows in-place initialization of big `struct`s that would otherwise produce a stack
overflow.

Expand All @@ -27,7 +29,7 @@ This library allows you to do in-place initialization safely.
## Nightly only

This library requires unstable features and thus can only be used with a nightly compiler.
The used features are:
The internally used features are:
- `allocator_api`
- `new_uninit` (only if the `alloc` or `std` features are enabled)
- `get_mut_unchecked` (only if the `alloc` or `std` features are enabled)
Expand All @@ -53,10 +55,10 @@ prefix.

## Examples

Throught some examples we will make use of the `CMutex` type which can be found in the examples
directory of the repository. It is essentially a rebuild of the `mutex` from the Linux kernel
in userland. So it also uses a wait list and a basic spinlock. Importantly it needs to be
pinned to be locked and thus is a prime candidate for this library.
Throught some examples we will make use of the `CMutex` type which can be found in
`../examples/mutex.rs`. It is essentially a rebuild of the `mutex` from the Linux kernel in userland. So
it also uses a wait list and a basic spinlock. Importantly it needs to be pinned to be locked
and thus is a prime candidate for using this library.

### Using the [`pin_init!`] macro

Expand Down Expand Up @@ -195,10 +197,11 @@ impl PinnedDrop for RawFoo {
}
```

For more information on how to use [`pin_init_from_closure()`], you can take a look at the
uses inside the `kernel` crate from the [Rust-for-Linux] project. The `sync` module is a good
starting point.
For more information on how to use [`pin_init_from_closure()`], take a look at the uses inside
the `kernel` crate. The [`sync`] module is a good starting point.

[`sync`]: https://github.com/Rust-for-Linux/linux/tree/rust-next/rust/kernel/sync
[pinning]: https://doc.rust-lang.org/std/pin/index.html
[structurally pinned fields]: https://doc.rust-lang.org/std/pin/index.html#pinning-is-structural-for-field
[stack]: https://docs.rs/pinned-init/latest/pinned_init/macro.stack_pin_init.html
[`Arc<T>`]: https://doc.rust-lang.org/stable/alloc/sync/struct.Arc.html
Expand Down
18 changes: 13 additions & 5 deletions src/__internal.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
// SPDX-License-Identifier: Apache-2.0 OR MIT

//! This module contains library-internal items.
//! This module contains library internal items.
//!
//! These items must not be used outside of
//! - `lib.rs`
//! - `../pinned-init-macro/src/pin_data.rs`
//! These items must not be used outside of these files in the case of the kernel repository:
//! - `../kernel/init.rs`
//! - `./lib.rs`
//! - `./macros.rs`
//! - `../macros/pin_data.rs`
//! - `../macros/pinned_drop.rs`
//!
//! And in the case of the `pinned-init` repository:
//! - `./lib.rs`
//! - `./macros.rs`
//! - `../pinned-init-macro/src/pinned_drop.rs`
//! - `../pinned-init-macro/src/pin_data.rs`
use super::*;

Expand Down Expand Up @@ -151,7 +159,7 @@ impl<T> StackInit<T> {
/// Creates a new [`StackInit<T>`] that is uninitialized. Use [`stack_pin_init`] instead of this
/// primitive.
///
/// [`stack_pin_init`]: pinned_init::stack_pin_init
/// [`stack_pin_init`]: crate::stack_pin_init
#[inline]
pub fn uninit() -> Self {
Self {
Expand Down
47 changes: 22 additions & 25 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

//! Library to safely and fallibly initialize pinned `struct`s using in-place constructors.
//!
//! [Pinning][pinning] is Rust's way of ensuring data does not move.
//!
//! It also allows in-place initialization of big `struct`s that would otherwise produce a stack
//! overflow.
//!
Expand All @@ -19,7 +21,7 @@
//! # Nightly only
//!
//! This library requires unstable features and thus can only be used with a nightly compiler.
//! The used features are:
//! The internally used features are:
//! - `allocator_api`
//! - `new_uninit` (only if the `alloc` or `std` features are enabled)
//! - `get_mut_unchecked` (only if the `alloc` or `std` features are enabled)
Expand All @@ -45,10 +47,10 @@
//!
//! # Examples
//!
//! Throught some examples we will make use of the `CMutex` type which can be found in the examples
//! directory of the repository. It is essentially a rebuild of the `mutex` from the Linux kernel
//! in userland. So it also uses a wait list and a basic spinlock. Importantly it needs to be
//! pinned to be locked and thus is a prime candidate for this library.
//! Throught some examples we will make use of the `CMutex` type which can be found in
//! `../examples/mutex.rs`. It is essentially a rebuild of the `mutex` from the Linux kernel in userland. So
//! it also uses a wait list and a basic spinlock. Importantly it needs to be pinned to be locked
//! and thus is a prime candidate for using this library.
//!
//! ## Using the [`pin_init!`] macro
//!
Expand Down Expand Up @@ -217,10 +219,11 @@
//! }
//! ```
//!
//! For more information on how to use [`pin_init_from_closure()`], you can take a look at the
//! uses inside the `kernel` crate from the [Rust-for-Linux] project. The `sync` module is a good
//! starting point.
//! For more information on how to use [`pin_init_from_closure()`], take a look at the uses inside
//! the `kernel` crate. The [`sync`] module is a good starting point.
//!
//! [`sync`]: https://github.com/Rust-for-Linux/linux/tree/rust-next/rust/kernel/sync
//! [pinning]: https://doc.rust-lang.org/std/pin/index.html
//! [structurally pinned fields]:
//! https://doc.rust-lang.org/std/pin/index.html#pinning-is-structural-for-field
//! [stack]: crate::stack_pin_init
Expand Down Expand Up @@ -551,6 +554,9 @@ macro_rules! stack_try_pin_init {
/// - Fields that you want to initialize in-place have to use `<-` instead of `:`.
/// - In front of the initializer you can write `&this in` to have access to a [`NonNull<Self>`]
/// pointer named `this` inside of the initializer.
/// - Using struct update syntax one can place `..Zeroable::zeroed()` at the very end of the
/// struct, this initializes every field with 0 and then runs all initializers specified in the
/// body. This can only be done if [`Zeroable`] is implemented for the struct.
///
/// For instance:
///
Expand All @@ -575,8 +581,6 @@ macro_rules! stack_try_pin_init {
/// ```
///
/// [`NonNull<Self>`]: core::ptr::NonNull
// For a detailed example of how this macro works, see the module documentation of the hidden
// module `__internal` inside of `__internal.rs`.
#[macro_export]
macro_rules! pin_init {
($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {
Expand Down Expand Up @@ -625,8 +629,6 @@ macro_rules! pin_init {
/// }
/// # let _ = Box::pin_init(BigBuf::new());
/// ```
// For a detailed example of how this macro works, see the module documentation of the hidden
// module `__internal` inside of `__internal.rs`.
#[macro_export]
macro_rules! try_pin_init {
($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {
Expand Down Expand Up @@ -658,6 +660,7 @@ macro_rules! try_pin_init {
///
/// This initializer is for initializing data in-place that might later be moved. If you want to
/// pin-initialize, use [`pin_init!`].
///
/// # Examples
///
/// ```rust
Expand All @@ -679,8 +682,6 @@ macro_rules! try_pin_init {
/// }
/// # let _ = Box::init(BigBuf::new());
/// ```
// For a detailed example of how this macro works, see the module documentation of the hidden
// module `__internal` inside of `__internal.rs`.
#[macro_export]
macro_rules! init {
($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {
Expand Down Expand Up @@ -726,8 +727,6 @@ macro_rules! init {
/// }
/// # let _ = Box::init(BigBuf::new());
/// ```
// For a detailed example of how this macro works, see the module documentation of the hidden
// module `__internal` inside of `__internal.rs`.
#[macro_export]
macro_rules! try_init {
($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {
Expand All @@ -750,16 +749,16 @@ macro_rules! try_init {
///
/// To use this initializer, you will need a suitable memory location that can hold a `T`. This can
/// be [`Box<T>`], [`Arc<T>`] or even the stack (see [`stack_pin_init!`]). Use the
/// [`InPlaceInit::pin_init`] function of a smart pointer like [`Arc<T>`] on this.
/// [`InPlaceInit::try_pin_init`] function of a smart pointer like [`Arc<T>`] on this.
///
/// Also see the [module description](self).
///
/// # Safety
///
/// When implementing this type you will need to take great care. Also there are probably very few
/// When implementing this trait you will need to take great care. Also there are probably very few
/// cases where a manual implementation is necessary. Use [`pin_init_from_closure`] where possible.
///
/// The [`PinInit::__pinned_init`] function
/// The [`PinInit::__pinned_init`] function:
/// - returns `Ok(())` if it initialized every field of `slot`,
/// - returns `Err(err)` if it encountered an error and then cleaned `slot`, this means:
/// - `slot` can be deallocated without UB occurring,
Expand Down Expand Up @@ -837,17 +836,17 @@ where
///
/// To use this initializer, you will need a suitable memory location that can hold a `T`. This can
/// be [`Box<T>`], [`Arc<T>`] or even the stack (see [`stack_pin_init!`]). Use the
/// [`InPlaceInit::init`] function of a smart pointer like [`Arc<T>`] on this. Because
/// [`InPlaceInit::try_init`] function of a smart pointer like [`Arc<T>`] on this. Because
/// [`PinInit<T, E>`] is a super trait, you can use every function that takes it as well.
///
/// Also see the [module description](self).
///
/// # Safety
///
/// When implementing this type you will need to take great care. Also there are probably very few
/// When implementing this trait you will need to take great care. Also there are probably very few
/// cases where a manual implementation is necessary. Use [`init_from_closure`] where possible.
///
/// The [`Init::__init`] function
/// The [`Init::__init`] function:
/// - returns `Ok(())` if it initialized every field of `slot`,
/// - returns `Err(err)` if it encountered an error and then cleaned `slot`, this means:
/// - `slot` can be deallocated without UB occurring,
Expand Down Expand Up @@ -1124,6 +1123,7 @@ pub trait InPlaceInit<T>: Sized {

/// Use the given initializer to in-place initialize a `T`.
fn init(init: impl Init<T>) -> Result<Self, AllocError> {
// SAFETY: We delegate to `init` and only change the error type.
let init = unsafe {
init_from_closure(|slot| match init.__init(slot) {
Ok(()) => Ok(()),
Expand Down Expand Up @@ -1219,14 +1219,11 @@ impl<T> InPlaceInit<T> for Arc<T> {
/// println!("Foo is being dropped!");
/// }
/// }
/// # let _ = Box::pin_init(pin_init!(Foo { mtx <- CMutex::new(0) }));
/// ```
///
/// # Safety
///
/// This trait must be implemented via the [`pinned_drop`] proc-macro attribute on the impl.
///
/// [`pinned_drop`]: pinned_init_macro::pinned_drop
pub unsafe trait PinnedDrop: __internal::HasPinData {
/// Executes the pinned destructor of this type.
///
Expand Down
8 changes: 4 additions & 4 deletions src/macros.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: Apache-2.0 OR MIT

//! This module provides the macros that actually implement the proc-macros `pin_data` and
//! `pinned_drop`. It also contains `__init_internal` the implementation of the `{try_}{pin_}init!`
//! macros.
//! This module provides the macros that actually implement the proc-macros `pin_data`,
//! `pinned_drop` and the derive macro for zeroable. It also contains `__init_internal` the
//! implementation of the `{try_}{pin_}init!` macros.
//!
//! These macros should never be called directly, since they expect their input to be
//! in a certain format which is internal. If used incorrectly, these macros can lead to UB even in
Expand All @@ -17,7 +17,7 @@
//! # Macro expansion example
//!
//! This section is intended for readers trying to understand the macros in this module and the
//! `pin_init!` macros from `init.rs`.
//! `[try_][pin_]init!` macros from `lib.rs`.
//!
//! We will look at the following example:
//!
Expand Down

0 comments on commit b3a3393

Please sign in to comment.