|  | // SPDX-License-Identifier: Apache-2.0 OR MIT | 
|  |  | 
|  | //! API to safely and fallibly initialize pinned `struct`s using in-place constructors. | 
|  | //! | 
|  | //! It also allows in-place initialization of big `struct`s that would otherwise produce a stack | 
|  | //! overflow. | 
|  | //! | 
|  | //! Most `struct`s from the [`sync`] module need to be pinned, because they contain self-referential | 
|  | //! `struct`s from C. [Pinning][pinning] is Rust's way of ensuring data does not move. | 
|  | //! | 
|  | //! # Overview | 
|  | //! | 
|  | //! To initialize a `struct` with an in-place constructor you will need two things: | 
|  | //! - an in-place constructor, | 
|  | //! - a memory location that can hold your `struct` (this can be the [stack], an [`Arc<T>`], | 
|  | //!   [`UniqueArc<T>`], [`Box<T>`] or any other smart pointer that implements [`InPlaceInit`]). | 
|  | //! | 
|  | //! To get an in-place constructor there are generally three options: | 
|  | //! - directly creating an in-place constructor using the [`pin_init!`] macro, | 
|  | //! - a custom function/macro returning an in-place constructor provided by someone else, | 
|  | //! - using the unsafe function [`pin_init_from_closure()`] to manually create an initializer. | 
|  | //! | 
|  | //! Aside from pinned initialization, this API also supports in-place construction without pinning, | 
|  | //! the macros/types/functions are generally named like the pinned variants without the `pin` | 
|  | //! prefix. | 
|  | //! | 
|  | //! # Examples | 
|  | //! | 
|  | //! ## Using the [`pin_init!`] macro | 
|  | //! | 
|  | //! If you want to use [`PinInit`], then you will have to annotate your `struct` with | 
|  | //! `#[`[`pin_data`]`]`. It is a macro that uses `#[pin]` as a marker for | 
|  | //! [structurally pinned fields]. After doing this, you can then create an in-place constructor via | 
|  | //! [`pin_init!`]. The syntax is almost the same as normal `struct` initializers. The difference is | 
|  | //! that you need to write `<-` instead of `:` for fields that you want to initialize in-place. | 
|  | //! | 
|  | //! ```rust | 
|  | //! # #![allow(clippy::disallowed_names)] | 
|  | //! use kernel::{prelude::*, sync::Mutex, new_mutex}; | 
|  | //! # use core::pin::Pin; | 
|  | //! #[pin_data] | 
|  | //! struct Foo { | 
|  | //!     #[pin] | 
|  | //!     a: Mutex<usize>, | 
|  | //!     b: u32, | 
|  | //! } | 
|  | //! | 
|  | //! let foo = pin_init!(Foo { | 
|  | //!     a <- new_mutex!(42, "Foo::a"), | 
|  | //!     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 | 
|  | //! # #![allow(clippy::disallowed_names)] | 
|  | //! # use kernel::{prelude::*, sync::Mutex, new_mutex}; | 
|  | //! # use core::pin::Pin; | 
|  | //! # #[pin_data] | 
|  | //! # struct Foo { | 
|  | //! #     #[pin] | 
|  | //! #     a: Mutex<usize>, | 
|  | //! #     b: u32, | 
|  | //! # } | 
|  | //! # let foo = pin_init!(Foo { | 
|  | //! #     a <- new_mutex!(42, "Foo::a"), | 
|  | //! #     b: 24, | 
|  | //! # }); | 
|  | //! let foo: Result<Pin<Box<Foo>>> = Box::pin_init(foo); | 
|  | //! ``` | 
|  | //! | 
|  | //! For more information see the [`pin_init!`] macro. | 
|  | //! | 
|  | //! ## Using a custom function/macro that returns an initializer | 
|  | //! | 
|  | //! Many types from the kernel supply a function/macro that returns an initializer, because the | 
|  | //! above method only works for types where you can access the fields. | 
|  | //! | 
|  | //! ```rust | 
|  | //! # use kernel::{new_mutex, sync::{Arc, Mutex}}; | 
|  | //! let mtx: Result<Arc<Mutex<usize>>> = Arc::pin_init(new_mutex!(42, "example::mtx")); | 
|  | //! ``` | 
|  | //! | 
|  | //! To declare an init macro/function you just return an [`impl PinInit<T, E>`]: | 
|  | //! | 
|  | //! ```rust | 
|  | //! # #![allow(clippy::disallowed_names)] | 
|  | //! # use kernel::{sync::Mutex, prelude::*, new_mutex, init::PinInit, try_pin_init}; | 
|  | //! #[pin_data] | 
|  | //! struct DriverData { | 
|  | //!     #[pin] | 
|  | //!     status: Mutex<i32>, | 
|  | //!     buffer: Box<[u8; 1_000_000]>, | 
|  | //! } | 
|  | //! | 
|  | //! impl DriverData { | 
|  | //!     fn new() -> impl PinInit<Self, Error> { | 
|  | //!         try_pin_init!(Self { | 
|  | //!             status <- new_mutex!(0, "DriverData::status"), | 
|  | //!             buffer: Box::init(kernel::init::zeroed())?, | 
|  | //!         }) | 
|  | //!     } | 
|  | //! } | 
|  | //! ``` | 
|  | //! | 
|  | //! ## 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 | 
|  | //! # #![allow(unreachable_pub, clippy::disallowed_names)] | 
|  | //! use kernel::{prelude::*, init, types::Opaque}; | 
|  | //! use core::{ptr::addr_of_mut, marker::PhantomPinned, pin::Pin}; | 
|  | //! # mod bindings { | 
|  | //! #     #![allow(non_camel_case_types)] | 
|  | //! #     pub struct foo; | 
|  | //! #     pub unsafe fn init_foo(_ptr: *mut foo) {} | 
|  | //! #     pub unsafe fn destroy_foo(_ptr: *mut foo) {} | 
|  | //! #     pub unsafe fn enable_foo(_ptr: *mut foo, _flags: u32) -> i32 { 0 } | 
|  | //! # } | 
|  | //! # // `Error::from_errno` is `pub(crate)` in the `kernel` crate, thus provide a workaround. | 
|  | //! # trait FromErrno { | 
|  | //! #     fn from_errno(errno: core::ffi::c_int) -> Error { | 
|  | //! #         // Dummy error that can be constructed outside the `kernel` crate. | 
|  | //! #         Error::from(core::fmt::Error) | 
|  | //! #     } | 
|  | //! # } | 
|  | //! # impl FromErrno for Error {} | 
|  | //! /// # Invariants | 
|  | //! /// | 
|  | //! /// `foo` is always initialized | 
|  | //! #[pin_data(PinnedDrop)] | 
|  | //! pub struct RawFoo { | 
|  | //!     #[pin] | 
|  | //!     foo: Opaque<bindings::foo>, | 
|  | //!     #[pin] | 
|  | //!     _p: PhantomPinned, | 
|  | //! } | 
|  | //! | 
|  | //! impl RawFoo { | 
|  | //!     pub fn new(flags: u32) -> impl PinInit<Self, Error> { | 
|  | //!         // SAFETY: | 
|  | //!         // - when the closure returns `Ok(())`, then it has successfully initialized and | 
|  | //!         //   enabled `foo`, | 
|  | //!         // - when it returns `Err(e)`, then it has cleaned up before | 
|  | //!         unsafe { | 
|  | //!             init::pin_init_from_closure(move |slot: *mut Self| { | 
|  | //!                 // `slot` contains uninit memory, avoid creating a reference. | 
|  | //!                 let foo = addr_of_mut!((*slot).foo); | 
|  | //! | 
|  | //!                 // Initialize the `foo` | 
|  | //!                 bindings::init_foo(Opaque::raw_get(foo)); | 
|  | //! | 
|  | //!                 // Try to enable it. | 
|  | //!                 let err = bindings::enable_foo(Opaque::raw_get(foo), flags); | 
|  | //!                 if err != 0 { | 
|  | //!                     // Enabling has failed, first clean up the foo and then return the error. | 
|  | //!                     bindings::destroy_foo(Opaque::raw_get(foo)); | 
|  | //!                     return Err(Error::from_errno(err)); | 
|  | //!                 } | 
|  | //! | 
|  | //!                 // All fields of `RawFoo` have been initialized, since `_p` is a ZST. | 
|  | //!                 Ok(()) | 
|  | //!             }) | 
|  | //!         } | 
|  | //!     } | 
|  | //! } | 
|  | //! | 
|  | //! #[pinned_drop] | 
|  | //! impl PinnedDrop for RawFoo { | 
|  | //!     fn drop(self: Pin<&mut Self>) { | 
|  | //!         // SAFETY: Since `foo` is initialized, destroying is safe. | 
|  | //!         unsafe { bindings::destroy_foo(self.foo.get()) }; | 
|  | //!     } | 
|  | //! } | 
|  | //! ``` | 
|  | //! | 
|  | //! For the special case where initializing a field is a single FFI-function call that cannot fail, | 
|  | //! there exist the helper function [`Opaque::ffi_init`]. This function initialize a single | 
|  | //! [`Opaque`] field by just delegating to the supplied closure. You can use these in combination | 
|  | //! with [`pin_init!`]. | 
|  | //! | 
|  | //! 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`]: 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 | 
|  | //! [`Arc<T>`]: crate::sync::Arc | 
|  | //! [`impl PinInit<Foo>`]: PinInit | 
|  | //! [`impl PinInit<T, E>`]: PinInit | 
|  | //! [`impl Init<T, E>`]: Init | 
|  | //! [`Opaque`]: kernel::types::Opaque | 
|  | //! [`Opaque::ffi_init`]: kernel::types::Opaque::ffi_init | 
|  | //! [`pin_data`]: ::macros::pin_data | 
|  | //! [`pin_init!`]: crate::pin_init! | 
|  |  | 
|  | use crate::{ | 
|  | error::{self, Error}, | 
|  | sync::UniqueArc, | 
|  | types::{Opaque, ScopeGuard}, | 
|  | }; | 
|  | use alloc::boxed::Box; | 
|  | use core::{ | 
|  | alloc::AllocError, | 
|  | cell::UnsafeCell, | 
|  | convert::Infallible, | 
|  | marker::PhantomData, | 
|  | mem::MaybeUninit, | 
|  | num::*, | 
|  | pin::Pin, | 
|  | ptr::{self, NonNull}, | 
|  | }; | 
|  |  | 
|  | #[doc(hidden)] | 
|  | pub mod __internal; | 
|  | #[doc(hidden)] | 
|  | pub mod macros; | 
|  |  | 
|  | /// Initialize and pin a type directly on the stack. | 
|  | /// | 
|  | /// # Examples | 
|  | /// | 
|  | /// ```rust | 
|  | /// # #![allow(clippy::disallowed_names)] | 
|  | /// # use kernel::{init, macros::pin_data, pin_init, stack_pin_init, init::*, sync::Mutex, new_mutex}; | 
|  | /// # use core::pin::Pin; | 
|  | /// #[pin_data] | 
|  | /// struct Foo { | 
|  | ///     #[pin] | 
|  | ///     a: Mutex<usize>, | 
|  | ///     b: Bar, | 
|  | /// } | 
|  | /// | 
|  | /// #[pin_data] | 
|  | /// struct Bar { | 
|  | ///     x: u32, | 
|  | /// } | 
|  | /// | 
|  | /// stack_pin_init!(let foo = pin_init!(Foo { | 
|  | ///     a <- new_mutex!(42), | 
|  | ///     b: Bar { | 
|  | ///         x: 64, | 
|  | ///     }, | 
|  | /// })); | 
|  | /// let foo: Pin<&mut Foo> = foo; | 
|  | /// pr_info!("a: {}", &*foo.a.lock()); | 
|  | /// ``` | 
|  | /// | 
|  | /// # Syntax | 
|  | /// | 
|  | /// A normal `let` binding with optional type annotation. The expression is expected to implement | 
|  | /// [`PinInit`]/[`Init`] with the error type [`Infallible`]. If you want to use a different error | 
|  | /// type, then use [`stack_try_pin_init!`]. | 
|  | /// | 
|  | /// [`stack_try_pin_init!`]: crate::stack_try_pin_init! | 
|  | #[macro_export] | 
|  | macro_rules! stack_pin_init { | 
|  | (let $var:ident $(: $t:ty)? = $val:expr) => { | 
|  | let val = $val; | 
|  | let mut $var = ::core::pin::pin!($crate::init::__internal::StackInit$(::<$t>)?::uninit()); | 
|  | let mut $var = match $crate::init::__internal::StackInit::init($var, val) { | 
|  | Ok(res) => res, | 
|  | Err(x) => { | 
|  | let x: ::core::convert::Infallible = x; | 
|  | match x {} | 
|  | } | 
|  | }; | 
|  | }; | 
|  | } | 
|  |  | 
|  | /// Initialize and pin a type directly on the stack. | 
|  | /// | 
|  | /// # Examples | 
|  | /// | 
|  | /// ```rust,ignore | 
|  | /// # #![allow(clippy::disallowed_names)] | 
|  | /// # use kernel::{init, pin_init, stack_try_pin_init, init::*, sync::Mutex, new_mutex}; | 
|  | /// # use macros::pin_data; | 
|  | /// # use core::{alloc::AllocError, pin::Pin}; | 
|  | /// #[pin_data] | 
|  | /// struct Foo { | 
|  | ///     #[pin] | 
|  | ///     a: Mutex<usize>, | 
|  | ///     b: Box<Bar>, | 
|  | /// } | 
|  | /// | 
|  | /// struct Bar { | 
|  | ///     x: u32, | 
|  | /// } | 
|  | /// | 
|  | /// stack_try_pin_init!(let foo: Result<Pin<&mut Foo>, AllocError> = pin_init!(Foo { | 
|  | ///     a <- new_mutex!(42), | 
|  | ///     b: Box::try_new(Bar { | 
|  | ///         x: 64, | 
|  | ///     })?, | 
|  | /// })); | 
|  | /// let foo = foo.unwrap(); | 
|  | /// pr_info!("a: {}", &*foo.a.lock()); | 
|  | /// ``` | 
|  | /// | 
|  | /// ```rust,ignore | 
|  | /// # #![allow(clippy::disallowed_names)] | 
|  | /// # use kernel::{init, pin_init, stack_try_pin_init, init::*, sync::Mutex, new_mutex}; | 
|  | /// # use macros::pin_data; | 
|  | /// # use core::{alloc::AllocError, pin::Pin}; | 
|  | /// #[pin_data] | 
|  | /// struct Foo { | 
|  | ///     #[pin] | 
|  | ///     a: Mutex<usize>, | 
|  | ///     b: Box<Bar>, | 
|  | /// } | 
|  | /// | 
|  | /// struct Bar { | 
|  | ///     x: u32, | 
|  | /// } | 
|  | /// | 
|  | /// stack_try_pin_init!(let foo: Pin<&mut Foo> =? pin_init!(Foo { | 
|  | ///     a <- new_mutex!(42), | 
|  | ///     b: Box::try_new(Bar { | 
|  | ///         x: 64, | 
|  | ///     })?, | 
|  | /// })); | 
|  | /// pr_info!("a: {}", &*foo.a.lock()); | 
|  | /// # Ok::<_, AllocError>(()) | 
|  | /// ``` | 
|  | /// | 
|  | /// # Syntax | 
|  | /// | 
|  | /// A normal `let` binding with optional type annotation. The expression is expected to implement | 
|  | /// [`PinInit`]/[`Init`]. This macro assigns a result to the given variable, adding a `?` after the | 
|  | /// `=` will propagate this error. | 
|  | #[macro_export] | 
|  | macro_rules! stack_try_pin_init { | 
|  | (let $var:ident $(: $t:ty)? = $val:expr) => { | 
|  | let val = $val; | 
|  | let mut $var = ::core::pin::pin!($crate::init::__internal::StackInit$(::<$t>)?::uninit()); | 
|  | let mut $var = $crate::init::__internal::StackInit::init($var, val); | 
|  | }; | 
|  | (let $var:ident $(: $t:ty)? =? $val:expr) => { | 
|  | let val = $val; | 
|  | let mut $var = ::core::pin::pin!($crate::init::__internal::StackInit$(::<$t>)?::uninit()); | 
|  | let mut $var = $crate::init::__internal::StackInit::init($var, val)?; | 
|  | }; | 
|  | } | 
|  |  | 
|  | /// Construct an in-place, pinned initializer for `struct`s. | 
|  | /// | 
|  | /// This macro defaults the error to [`Infallible`]. If you need [`Error`], then use | 
|  | /// [`try_pin_init!`]. | 
|  | /// | 
|  | /// The syntax is almost identical to that of a normal `struct` initializer: | 
|  | /// | 
|  | /// ```rust | 
|  | /// # #![allow(clippy::disallowed_names)] | 
|  | /// # use kernel::{init, pin_init, macros::pin_data, init::*}; | 
|  | /// # use core::pin::Pin; | 
|  | /// #[pin_data] | 
|  | /// struct Foo { | 
|  | ///     a: usize, | 
|  | ///     b: Bar, | 
|  | /// } | 
|  | /// | 
|  | /// #[pin_data] | 
|  | /// struct Bar { | 
|  | ///     x: u32, | 
|  | /// } | 
|  | /// | 
|  | /// # fn demo() -> impl PinInit<Foo> { | 
|  | /// let a = 42; | 
|  | /// | 
|  | /// let initializer = pin_init!(Foo { | 
|  | ///     a, | 
|  | ///     b: Bar { | 
|  | ///         x: 64, | 
|  | ///     }, | 
|  | /// }); | 
|  | /// # initializer } | 
|  | /// # Box::pin_init(demo()).unwrap(); | 
|  | /// ``` | 
|  | /// | 
|  | /// Arbitrary Rust expressions can be used to set the value of a variable. | 
|  | /// | 
|  | /// The fields are initialized in the order that they appear in the initializer. So it is possible | 
|  | /// to read already initialized fields using raw pointers. | 
|  | /// | 
|  | /// IMPORTANT: You are not allowed to create references to fields of the struct inside of the | 
|  | /// initializer. | 
|  | /// | 
|  | /// # Init-functions | 
|  | /// | 
|  | /// When working with this API it is often desired to let others construct your types without | 
|  | /// giving access to all fields. This is where you would normally write a plain function `new` | 
|  | /// that would return a new instance of your type. With this API that is also possible. | 
|  | /// However, there are a few extra things to keep in mind. | 
|  | /// | 
|  | /// To create an initializer function, simply declare it like this: | 
|  | /// | 
|  | /// ```rust | 
|  | /// # #![allow(clippy::disallowed_names)] | 
|  | /// # use kernel::{init, pin_init, prelude::*, init::*}; | 
|  | /// # use core::pin::Pin; | 
|  | /// # #[pin_data] | 
|  | /// # struct Foo { | 
|  | /// #     a: usize, | 
|  | /// #     b: Bar, | 
|  | /// # } | 
|  | /// # #[pin_data] | 
|  | /// # struct Bar { | 
|  | /// #     x: u32, | 
|  | /// # } | 
|  | /// impl Foo { | 
|  | ///     fn new() -> impl PinInit<Self> { | 
|  | ///         pin_init!(Self { | 
|  | ///             a: 42, | 
|  | ///             b: Bar { | 
|  | ///                 x: 64, | 
|  | ///             }, | 
|  | ///         }) | 
|  | ///     } | 
|  | /// } | 
|  | /// ``` | 
|  | /// | 
|  | /// Users of `Foo` can now create it like this: | 
|  | /// | 
|  | /// ```rust | 
|  | /// # #![allow(clippy::disallowed_names)] | 
|  | /// # use kernel::{init, pin_init, macros::pin_data, init::*}; | 
|  | /// # use core::pin::Pin; | 
|  | /// # #[pin_data] | 
|  | /// # struct Foo { | 
|  | /// #     a: usize, | 
|  | /// #     b: Bar, | 
|  | /// # } | 
|  | /// # #[pin_data] | 
|  | /// # struct Bar { | 
|  | /// #     x: u32, | 
|  | /// # } | 
|  | /// # impl Foo { | 
|  | /// #     fn new() -> impl PinInit<Self> { | 
|  | /// #         pin_init!(Self { | 
|  | /// #             a: 42, | 
|  | /// #             b: Bar { | 
|  | /// #                 x: 64, | 
|  | /// #             }, | 
|  | /// #         }) | 
|  | /// #     } | 
|  | /// # } | 
|  | /// let foo = Box::pin_init(Foo::new()); | 
|  | /// ``` | 
|  | /// | 
|  | /// They can also easily embed it into their own `struct`s: | 
|  | /// | 
|  | /// ```rust | 
|  | /// # #![allow(clippy::disallowed_names)] | 
|  | /// # use kernel::{init, pin_init, macros::pin_data, init::*}; | 
|  | /// # use core::pin::Pin; | 
|  | /// # #[pin_data] | 
|  | /// # struct Foo { | 
|  | /// #     a: usize, | 
|  | /// #     b: Bar, | 
|  | /// # } | 
|  | /// # #[pin_data] | 
|  | /// # struct Bar { | 
|  | /// #     x: u32, | 
|  | /// # } | 
|  | /// # impl Foo { | 
|  | /// #     fn new() -> impl PinInit<Self> { | 
|  | /// #         pin_init!(Self { | 
|  | /// #             a: 42, | 
|  | /// #             b: Bar { | 
|  | /// #                 x: 64, | 
|  | /// #             }, | 
|  | /// #         }) | 
|  | /// #     } | 
|  | /// # } | 
|  | /// #[pin_data] | 
|  | /// struct FooContainer { | 
|  | ///     #[pin] | 
|  | ///     foo1: Foo, | 
|  | ///     #[pin] | 
|  | ///     foo2: Foo, | 
|  | ///     other: u32, | 
|  | /// } | 
|  | /// | 
|  | /// impl FooContainer { | 
|  | ///     fn new(other: u32) -> impl PinInit<Self> { | 
|  | ///         pin_init!(Self { | 
|  | ///             foo1 <- Foo::new(), | 
|  | ///             foo2 <- Foo::new(), | 
|  | ///             other, | 
|  | ///         }) | 
|  | ///     } | 
|  | /// } | 
|  | /// ``` | 
|  | /// | 
|  | /// Here we see that when using `pin_init!` with `PinInit`, one needs to write `<-` instead of `:`. | 
|  | /// This signifies that the given field is initialized in-place. As with `struct` initializers, just | 
|  | /// writing the field (in this case `other`) without `:` or `<-` means `other: other,`. | 
|  | /// | 
|  | /// # Syntax | 
|  | /// | 
|  | /// As already mentioned in the examples above, inside of `pin_init!` a `struct` initializer with | 
|  | /// the following modifications is expected: | 
|  | /// - 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: | 
|  | /// | 
|  | /// ```rust | 
|  | /// # use kernel::{macros::{Zeroable, pin_data}, pin_init}; | 
|  | /// # use core::{ptr::addr_of_mut, marker::PhantomPinned}; | 
|  | /// #[pin_data] | 
|  | /// #[derive(Zeroable)] | 
|  | /// struct Buf { | 
|  | ///     // `ptr` points into `buf`. | 
|  | ///     ptr: *mut u8, | 
|  | ///     buf: [u8; 64], | 
|  | ///     #[pin] | 
|  | ///     pin: PhantomPinned, | 
|  | /// } | 
|  | /// pin_init!(&this in Buf { | 
|  | ///     buf: [0; 64], | 
|  | ///     ptr: unsafe { addr_of_mut!((*this.as_ptr()).buf).cast() }, | 
|  | ///     pin: PhantomPinned, | 
|  | /// }); | 
|  | /// pin_init!(Buf { | 
|  | ///     buf: [1; 64], | 
|  | ///     ..Zeroable::zeroed() | 
|  | /// }); | 
|  | /// ``` | 
|  | /// | 
|  | /// [`try_pin_init!`]: kernel::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 `init/__internal.rs`. | 
|  | #[macro_export] | 
|  | macro_rules! pin_init { | 
|  | ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { | 
|  | $($fields:tt)* | 
|  | }) => { | 
|  | $crate::__init_internal!( | 
|  | @this($($this)?), | 
|  | @typ($t $(::<$($generics),*>)?), | 
|  | @fields($($fields)*), | 
|  | @error(::core::convert::Infallible), | 
|  | @data(PinData, use_data), | 
|  | @has_data(HasPinData, __pin_data), | 
|  | @construct_closure(pin_init_from_closure), | 
|  | @munch_fields($($fields)*), | 
|  | ) | 
|  | }; | 
|  | } | 
|  |  | 
|  | /// Construct an in-place, fallible pinned initializer for `struct`s. | 
|  | /// | 
|  | /// If the initialization can complete without error (or [`Infallible`]), then use [`pin_init!`]. | 
|  | /// | 
|  | /// You can use the `?` operator or use `return Err(err)` inside the initializer to stop | 
|  | /// initialization and return the error. | 
|  | /// | 
|  | /// IMPORTANT: if you have `unsafe` code inside of the initializer you have to ensure that when | 
|  | /// initialization fails, the memory can be safely deallocated without any further modifications. | 
|  | /// | 
|  | /// This macro defaults the error to [`Error`]. | 
|  | /// | 
|  | /// The syntax is identical to [`pin_init!`] with the following exception: you can append `? $type` | 
|  | /// after the `struct` initializer to specify the error type you want to use. | 
|  | /// | 
|  | /// # Examples | 
|  | /// | 
|  | /// ```rust | 
|  | /// # #![feature(new_uninit)] | 
|  | /// use kernel::{init::{self, PinInit}, error::Error}; | 
|  | /// #[pin_data] | 
|  | /// struct BigBuf { | 
|  | ///     big: Box<[u8; 1024 * 1024 * 1024]>, | 
|  | ///     small: [u8; 1024 * 1024], | 
|  | ///     ptr: *mut u8, | 
|  | /// } | 
|  | /// | 
|  | /// impl BigBuf { | 
|  | ///     fn new() -> impl PinInit<Self, Error> { | 
|  | ///         try_pin_init!(Self { | 
|  | ///             big: Box::init(init::zeroed())?, | 
|  | ///             small: [0; 1024 * 1024], | 
|  | ///             ptr: core::ptr::null_mut(), | 
|  | ///         }? Error) | 
|  | ///     } | 
|  | /// } | 
|  | /// ``` | 
|  | // For a detailed example of how this macro works, see the module documentation of the hidden | 
|  | // module `__internal` inside of `init/__internal.rs`. | 
|  | #[macro_export] | 
|  | macro_rules! try_pin_init { | 
|  | ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { | 
|  | $($fields:tt)* | 
|  | }) => { | 
|  | $crate::__init_internal!( | 
|  | @this($($this)?), | 
|  | @typ($t $(::<$($generics),*>)? ), | 
|  | @fields($($fields)*), | 
|  | @error($crate::error::Error), | 
|  | @data(PinData, use_data), | 
|  | @has_data(HasPinData, __pin_data), | 
|  | @construct_closure(pin_init_from_closure), | 
|  | @munch_fields($($fields)*), | 
|  | ) | 
|  | }; | 
|  | ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { | 
|  | $($fields:tt)* | 
|  | }? $err:ty) => { | 
|  | $crate::__init_internal!( | 
|  | @this($($this)?), | 
|  | @typ($t $(::<$($generics),*>)? ), | 
|  | @fields($($fields)*), | 
|  | @error($err), | 
|  | @data(PinData, use_data), | 
|  | @has_data(HasPinData, __pin_data), | 
|  | @construct_closure(pin_init_from_closure), | 
|  | @munch_fields($($fields)*), | 
|  | ) | 
|  | }; | 
|  | } | 
|  |  | 
|  | /// Construct an in-place initializer for `struct`s. | 
|  | /// | 
|  | /// This macro defaults the error to [`Infallible`]. If you need [`Error`], then use | 
|  | /// [`try_init!`]. | 
|  | /// | 
|  | /// The syntax is identical to [`pin_init!`] and its safety caveats also apply: | 
|  | /// - `unsafe` code must guarantee either full initialization or return an error and allow | 
|  | ///   deallocation of the memory. | 
|  | /// - the fields are initialized in the order given in the initializer. | 
|  | /// - no references to fields are allowed to be created inside of the initializer. | 
|  | /// | 
|  | /// This initializer is for initializing data in-place that might later be moved. If you want to | 
|  | /// pin-initialize, use [`pin_init!`]. | 
|  | /// | 
|  | /// [`try_init!`]: crate::try_init! | 
|  | // For a detailed example of how this macro works, see the module documentation of the hidden | 
|  | // module `__internal` inside of `init/__internal.rs`. | 
|  | #[macro_export] | 
|  | macro_rules! init { | 
|  | ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { | 
|  | $($fields:tt)* | 
|  | }) => { | 
|  | $crate::__init_internal!( | 
|  | @this($($this)?), | 
|  | @typ($t $(::<$($generics),*>)?), | 
|  | @fields($($fields)*), | 
|  | @error(::core::convert::Infallible), | 
|  | @data(InitData, /*no use_data*/), | 
|  | @has_data(HasInitData, __init_data), | 
|  | @construct_closure(init_from_closure), | 
|  | @munch_fields($($fields)*), | 
|  | ) | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Construct an in-place fallible initializer for `struct`s. | 
|  | /// | 
|  | /// This macro defaults the error to [`Error`]. If you need [`Infallible`], then use | 
|  | /// [`init!`]. | 
|  | /// | 
|  | /// The syntax is identical to [`try_pin_init!`]. If you want to specify a custom error, | 
|  | /// append `? $type` after the `struct` initializer. | 
|  | /// The safety caveats from [`try_pin_init!`] also apply: | 
|  | /// - `unsafe` code must guarantee either full initialization or return an error and allow | 
|  | ///   deallocation of the memory. | 
|  | /// - the fields are initialized in the order given in the initializer. | 
|  | /// - no references to fields are allowed to be created inside of the initializer. | 
|  | /// | 
|  | /// # Examples | 
|  | /// | 
|  | /// ```rust | 
|  | /// use kernel::{init::{PinInit, zeroed}, error::Error}; | 
|  | /// struct BigBuf { | 
|  | ///     big: Box<[u8; 1024 * 1024 * 1024]>, | 
|  | ///     small: [u8; 1024 * 1024], | 
|  | /// } | 
|  | /// | 
|  | /// impl BigBuf { | 
|  | ///     fn new() -> impl Init<Self, Error> { | 
|  | ///         try_init!(Self { | 
|  | ///             big: Box::init(zeroed())?, | 
|  | ///             small: [0; 1024 * 1024], | 
|  | ///         }? Error) | 
|  | ///     } | 
|  | /// } | 
|  | /// ``` | 
|  | // For a detailed example of how this macro works, see the module documentation of the hidden | 
|  | // module `__internal` inside of `init/__internal.rs`. | 
|  | #[macro_export] | 
|  | macro_rules! try_init { | 
|  | ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { | 
|  | $($fields:tt)* | 
|  | }) => { | 
|  | $crate::__init_internal!( | 
|  | @this($($this)?), | 
|  | @typ($t $(::<$($generics),*>)?), | 
|  | @fields($($fields)*), | 
|  | @error($crate::error::Error), | 
|  | @data(InitData, /*no use_data*/), | 
|  | @has_data(HasInitData, __init_data), | 
|  | @construct_closure(init_from_closure), | 
|  | @munch_fields($($fields)*), | 
|  | ) | 
|  | }; | 
|  | ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? { | 
|  | $($fields:tt)* | 
|  | }? $err:ty) => { | 
|  | $crate::__init_internal!( | 
|  | @this($($this)?), | 
|  | @typ($t $(::<$($generics),*>)?), | 
|  | @fields($($fields)*), | 
|  | @error($err), | 
|  | @data(InitData, /*no use_data*/), | 
|  | @has_data(HasInitData, __init_data), | 
|  | @construct_closure(init_from_closure), | 
|  | @munch_fields($($fields)*), | 
|  | ) | 
|  | }; | 
|  | } | 
|  |  | 
|  | /// A pin-initializer for the type `T`. | 
|  | /// | 
|  | /// To use this initializer, you will need a suitable memory location that can hold a `T`. This can | 
|  | /// be [`Box<T>`], [`Arc<T>`], [`UniqueArc<T>`] or even the stack (see [`stack_pin_init!`]). Use the | 
|  | /// [`InPlaceInit::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 | 
|  | /// cases where a manual implementation is necessary. Use [`pin_init_from_closure`] where possible. | 
|  | /// | 
|  | /// 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, | 
|  | ///     - `slot` does not need to be dropped, | 
|  | ///     - `slot` is not partially initialized. | 
|  | /// - while constructing the `T` at `slot` it upholds the pinning invariants of `T`. | 
|  | /// | 
|  | /// [`Arc<T>`]: crate::sync::Arc | 
|  | /// [`Arc::pin_init`]: crate::sync::Arc::pin_init | 
|  | #[must_use = "An initializer must be used in order to create its value."] | 
|  | pub unsafe trait PinInit<T: ?Sized, E = Infallible>: Sized { | 
|  | /// Initializes `slot`. | 
|  | /// | 
|  | /// # Safety | 
|  | /// | 
|  | /// - `slot` is a valid pointer to uninitialized memory. | 
|  | /// - the caller does not touch `slot` when `Err` is returned, they are only permitted to | 
|  | ///   deallocate. | 
|  | /// - `slot` will not move until it is dropped, i.e. it will be pinned. | 
|  | unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E>; | 
|  |  | 
|  | /// First initializes the value using `self` then calls the function `f` with the initialized | 
|  | /// value. | 
|  | /// | 
|  | /// If `f` returns an error the value is dropped and the initializer will forward the error. | 
|  | /// | 
|  | /// # Examples | 
|  | /// | 
|  | /// ```rust | 
|  | /// # #![allow(clippy::disallowed_names)] | 
|  | /// use kernel::{types::Opaque, init::pin_init_from_closure}; | 
|  | /// #[repr(C)] | 
|  | /// struct RawFoo([u8; 16]); | 
|  | /// extern { | 
|  | ///     fn init_foo(_: *mut RawFoo); | 
|  | /// } | 
|  | /// | 
|  | /// #[pin_data] | 
|  | /// struct Foo { | 
|  | ///     #[pin] | 
|  | ///     raw: Opaque<RawFoo>, | 
|  | /// } | 
|  | /// | 
|  | /// impl Foo { | 
|  | ///     fn setup(self: Pin<&mut Self>) { | 
|  | ///         pr_info!("Setting up foo"); | 
|  | ///     } | 
|  | /// } | 
|  | /// | 
|  | /// let foo = pin_init!(Foo { | 
|  | ///     raw <- unsafe { | 
|  | ///         Opaque::ffi_init(|s| { | 
|  | ///             init_foo(s); | 
|  | ///         }) | 
|  | ///     }, | 
|  | /// }).pin_chain(|foo| { | 
|  | ///     foo.setup(); | 
|  | ///     Ok(()) | 
|  | /// }); | 
|  | /// ``` | 
|  | fn pin_chain<F>(self, f: F) -> ChainPinInit<Self, F, T, E> | 
|  | where | 
|  | F: FnOnce(Pin<&mut T>) -> Result<(), E>, | 
|  | { | 
|  | ChainPinInit(self, f, PhantomData) | 
|  | } | 
|  | } | 
|  |  | 
|  | /// An initializer returned by [`PinInit::pin_chain`]. | 
|  | pub struct ChainPinInit<I, F, T: ?Sized, E>(I, F, __internal::Invariant<(E, Box<T>)>); | 
|  |  | 
|  | // SAFETY: The `__pinned_init` function is implemented such that it | 
|  | // - returns `Ok(())` on successful initialization, | 
|  | // - returns `Err(err)` on error and in this case `slot` will be dropped. | 
|  | // - considers `slot` pinned. | 
|  | unsafe impl<T: ?Sized, E, I, F> PinInit<T, E> for ChainPinInit<I, F, T, E> | 
|  | where | 
|  | I: PinInit<T, E>, | 
|  | F: FnOnce(Pin<&mut T>) -> Result<(), E>, | 
|  | { | 
|  | unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E> { | 
|  | // SAFETY: All requirements fulfilled since this function is `__pinned_init`. | 
|  | unsafe { self.0.__pinned_init(slot)? }; | 
|  | // SAFETY: The above call initialized `slot` and we still have unique access. | 
|  | let val = unsafe { &mut *slot }; | 
|  | // SAFETY: `slot` is considered pinned. | 
|  | let val = unsafe { Pin::new_unchecked(val) }; | 
|  | (self.1)(val).map_err(|e| { | 
|  | // SAFETY: `slot` was initialized above. | 
|  | unsafe { core::ptr::drop_in_place(slot) }; | 
|  | e | 
|  | }) | 
|  | } | 
|  | } | 
|  |  | 
|  | /// An initializer for `T`. | 
|  | /// | 
|  | /// To use this initializer, you will need a suitable memory location that can hold a `T`. This can | 
|  | /// be [`Box<T>`], [`Arc<T>`], [`UniqueArc<T>`] or even the stack (see [`stack_pin_init!`]). Use the | 
|  | /// [`InPlaceInit::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 | 
|  | /// cases where a manual implementation is necessary. Use [`init_from_closure`] where possible. | 
|  | /// | 
|  | /// 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, | 
|  | ///     - `slot` does not need to be dropped, | 
|  | ///     - `slot` is not partially initialized. | 
|  | /// - while constructing the `T` at `slot` it upholds the pinning invariants of `T`. | 
|  | /// | 
|  | /// The `__pinned_init` function from the supertrait [`PinInit`] needs to execute the exact same | 
|  | /// code as `__init`. | 
|  | /// | 
|  | /// Contrary to its supertype [`PinInit<T, E>`] the caller is allowed to | 
|  | /// move the pointee after initialization. | 
|  | /// | 
|  | /// [`Arc<T>`]: crate::sync::Arc | 
|  | #[must_use = "An initializer must be used in order to create its value."] | 
|  | pub unsafe trait Init<T: ?Sized, E = Infallible>: PinInit<T, E> { | 
|  | /// Initializes `slot`. | 
|  | /// | 
|  | /// # Safety | 
|  | /// | 
|  | /// - `slot` is a valid pointer to uninitialized memory. | 
|  | /// - the caller does not touch `slot` when `Err` is returned, they are only permitted to | 
|  | ///   deallocate. | 
|  | unsafe fn __init(self, slot: *mut T) -> Result<(), E>; | 
|  |  | 
|  | /// First initializes the value using `self` then calls the function `f` with the initialized | 
|  | /// value. | 
|  | /// | 
|  | /// If `f` returns an error the value is dropped and the initializer will forward the error. | 
|  | /// | 
|  | /// # Examples | 
|  | /// | 
|  | /// ```rust | 
|  | /// # #![allow(clippy::disallowed_names)] | 
|  | /// use kernel::{types::Opaque, init::{self, init_from_closure}}; | 
|  | /// struct Foo { | 
|  | ///     buf: [u8; 1_000_000], | 
|  | /// } | 
|  | /// | 
|  | /// impl Foo { | 
|  | ///     fn setup(&mut self) { | 
|  | ///         pr_info!("Setting up foo"); | 
|  | ///     } | 
|  | /// } | 
|  | /// | 
|  | /// let foo = init!(Foo { | 
|  | ///     buf <- init::zeroed() | 
|  | /// }).chain(|foo| { | 
|  | ///     foo.setup(); | 
|  | ///     Ok(()) | 
|  | /// }); | 
|  | /// ``` | 
|  | fn chain<F>(self, f: F) -> ChainInit<Self, F, T, E> | 
|  | where | 
|  | F: FnOnce(&mut T) -> Result<(), E>, | 
|  | { | 
|  | ChainInit(self, f, PhantomData) | 
|  | } | 
|  | } | 
|  |  | 
|  | /// An initializer returned by [`Init::chain`]. | 
|  | pub struct ChainInit<I, F, T: ?Sized, E>(I, F, __internal::Invariant<(E, Box<T>)>); | 
|  |  | 
|  | // SAFETY: The `__init` function is implemented such that it | 
|  | // - returns `Ok(())` on successful initialization, | 
|  | // - returns `Err(err)` on error and in this case `slot` will be dropped. | 
|  | unsafe impl<T: ?Sized, E, I, F> Init<T, E> for ChainInit<I, F, T, E> | 
|  | where | 
|  | I: Init<T, E>, | 
|  | F: FnOnce(&mut T) -> Result<(), E>, | 
|  | { | 
|  | unsafe fn __init(self, slot: *mut T) -> Result<(), E> { | 
|  | // SAFETY: All requirements fulfilled since this function is `__init`. | 
|  | unsafe { self.0.__pinned_init(slot)? }; | 
|  | // SAFETY: The above call initialized `slot` and we still have unique access. | 
|  | (self.1)(unsafe { &mut *slot }).map_err(|e| { | 
|  | // SAFETY: `slot` was initialized above. | 
|  | unsafe { core::ptr::drop_in_place(slot) }; | 
|  | e | 
|  | }) | 
|  | } | 
|  | } | 
|  |  | 
|  | // SAFETY: `__pinned_init` behaves exactly the same as `__init`. | 
|  | unsafe impl<T: ?Sized, E, I, F> PinInit<T, E> for ChainInit<I, F, T, E> | 
|  | where | 
|  | I: Init<T, E>, | 
|  | F: FnOnce(&mut T) -> Result<(), E>, | 
|  | { | 
|  | unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E> { | 
|  | // SAFETY: `__init` has less strict requirements compared to `__pinned_init`. | 
|  | unsafe { self.__init(slot) } | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Creates a new [`PinInit<T, E>`] from the given closure. | 
|  | /// | 
|  | /// # Safety | 
|  | /// | 
|  | /// The closure: | 
|  | /// - 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, | 
|  | ///     - `slot` does not need to be dropped, | 
|  | ///     - `slot` is not partially initialized. | 
|  | /// - may assume that the `slot` does not move if `T: !Unpin`, | 
|  | /// - while constructing the `T` at `slot` it upholds the pinning invariants of `T`. | 
|  | #[inline] | 
|  | pub const unsafe fn pin_init_from_closure<T: ?Sized, E>( | 
|  | f: impl FnOnce(*mut T) -> Result<(), E>, | 
|  | ) -> impl PinInit<T, E> { | 
|  | __internal::InitClosure(f, PhantomData) | 
|  | } | 
|  |  | 
|  | /// Creates a new [`Init<T, E>`] from the given closure. | 
|  | /// | 
|  | /// # Safety | 
|  | /// | 
|  | /// The closure: | 
|  | /// - 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, | 
|  | ///     - `slot` does not need to be dropped, | 
|  | ///     - `slot` is not partially initialized. | 
|  | /// - the `slot` may move after initialization. | 
|  | /// - while constructing the `T` at `slot` it upholds the pinning invariants of `T`. | 
|  | #[inline] | 
|  | pub const unsafe fn init_from_closure<T: ?Sized, E>( | 
|  | f: impl FnOnce(*mut T) -> Result<(), E>, | 
|  | ) -> impl Init<T, E> { | 
|  | __internal::InitClosure(f, PhantomData) | 
|  | } | 
|  |  | 
|  | /// An initializer that leaves the memory uninitialized. | 
|  | /// | 
|  | /// The initializer is a no-op. The `slot` memory is not changed. | 
|  | #[inline] | 
|  | pub fn uninit<T, E>() -> impl Init<MaybeUninit<T>, E> { | 
|  | // SAFETY: The memory is allowed to be uninitialized. | 
|  | unsafe { init_from_closure(|_| Ok(())) } | 
|  | } | 
|  |  | 
|  | /// Initializes an array by initializing each element via the provided initializer. | 
|  | /// | 
|  | /// # Examples | 
|  | /// | 
|  | /// ```rust | 
|  | /// use kernel::{error::Error, init::init_array_from_fn}; | 
|  | /// let array: Box<[usize; 1_000]>= Box::init::<Error>(init_array_from_fn(|i| i)).unwrap(); | 
|  | /// assert_eq!(array.len(), 1_000); | 
|  | /// ``` | 
|  | pub fn init_array_from_fn<I, const N: usize, T, E>( | 
|  | mut make_init: impl FnMut(usize) -> I, | 
|  | ) -> impl Init<[T; N], E> | 
|  | where | 
|  | I: Init<T, E>, | 
|  | { | 
|  | let init = move |slot: *mut [T; N]| { | 
|  | let slot = slot.cast::<T>(); | 
|  | // Counts the number of initialized elements and when dropped drops that many elements from | 
|  | // `slot`. | 
|  | let mut init_count = ScopeGuard::new_with_data(0, |i| { | 
|  | // We now free every element that has been initialized before: | 
|  | // SAFETY: The loop initialized exactly the values from 0..i and since we | 
|  | // return `Err` below, the caller will consider the memory at `slot` as | 
|  | // uninitialized. | 
|  | unsafe { ptr::drop_in_place(ptr::slice_from_raw_parts_mut(slot, i)) }; | 
|  | }); | 
|  | for i in 0..N { | 
|  | let init = make_init(i); | 
|  | // SAFETY: Since 0 <= `i` < N, it is still in bounds of `[T; N]`. | 
|  | let ptr = unsafe { slot.add(i) }; | 
|  | // SAFETY: The pointer is derived from `slot` and thus satisfies the `__init` | 
|  | // requirements. | 
|  | unsafe { init.__init(ptr) }?; | 
|  | *init_count += 1; | 
|  | } | 
|  | init_count.dismiss(); | 
|  | Ok(()) | 
|  | }; | 
|  | // SAFETY: The initializer above initializes every element of the array. On failure it drops | 
|  | // any initialized elements and returns `Err`. | 
|  | unsafe { init_from_closure(init) } | 
|  | } | 
|  |  | 
|  | /// Initializes an array by initializing each element via the provided initializer. | 
|  | /// | 
|  | /// # Examples | 
|  | /// | 
|  | /// ```rust | 
|  | /// use kernel::{sync::{Arc, Mutex}, init::pin_init_array_from_fn, new_mutex}; | 
|  | /// let array: Arc<[Mutex<usize>; 1_000]>= | 
|  | ///     Arc::pin_init(pin_init_array_from_fn(|i| new_mutex!(i))).unwrap(); | 
|  | /// assert_eq!(array.len(), 1_000); | 
|  | /// ``` | 
|  | pub fn pin_init_array_from_fn<I, const N: usize, T, E>( | 
|  | mut make_init: impl FnMut(usize) -> I, | 
|  | ) -> impl PinInit<[T; N], E> | 
|  | where | 
|  | I: PinInit<T, E>, | 
|  | { | 
|  | let init = move |slot: *mut [T; N]| { | 
|  | let slot = slot.cast::<T>(); | 
|  | // Counts the number of initialized elements and when dropped drops that many elements from | 
|  | // `slot`. | 
|  | let mut init_count = ScopeGuard::new_with_data(0, |i| { | 
|  | // We now free every element that has been initialized before: | 
|  | // SAFETY: The loop initialized exactly the values from 0..i and since we | 
|  | // return `Err` below, the caller will consider the memory at `slot` as | 
|  | // uninitialized. | 
|  | unsafe { ptr::drop_in_place(ptr::slice_from_raw_parts_mut(slot, i)) }; | 
|  | }); | 
|  | for i in 0..N { | 
|  | let init = make_init(i); | 
|  | // SAFETY: Since 0 <= `i` < N, it is still in bounds of `[T; N]`. | 
|  | let ptr = unsafe { slot.add(i) }; | 
|  | // SAFETY: The pointer is derived from `slot` and thus satisfies the `__init` | 
|  | // requirements. | 
|  | unsafe { init.__pinned_init(ptr) }?; | 
|  | *init_count += 1; | 
|  | } | 
|  | init_count.dismiss(); | 
|  | Ok(()) | 
|  | }; | 
|  | // SAFETY: The initializer above initializes every element of the array. On failure it drops | 
|  | // any initialized elements and returns `Err`. | 
|  | unsafe { pin_init_from_closure(init) } | 
|  | } | 
|  |  | 
|  | // SAFETY: Every type can be initialized by-value. | 
|  | unsafe impl<T, E> Init<T, E> for T { | 
|  | unsafe fn __init(self, slot: *mut T) -> Result<(), E> { | 
|  | unsafe { slot.write(self) }; | 
|  | Ok(()) | 
|  | } | 
|  | } | 
|  |  | 
|  | // SAFETY: Every type can be initialized by-value. `__pinned_init` calls `__init`. | 
|  | unsafe impl<T, E> PinInit<T, E> for T { | 
|  | unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E> { | 
|  | unsafe { self.__init(slot) } | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Smart pointer that can initialize memory in-place. | 
|  | pub trait InPlaceInit<T>: Sized { | 
|  | /// Use the given pin-initializer to pin-initialize a `T` inside of a new smart pointer of this | 
|  | /// type. | 
|  | /// | 
|  | /// If `T: !Unpin` it will not be able to move afterwards. | 
|  | fn try_pin_init<E>(init: impl PinInit<T, E>) -> Result<Pin<Self>, E> | 
|  | where | 
|  | E: From<AllocError>; | 
|  |  | 
|  | /// Use the given pin-initializer to pin-initialize a `T` inside of a new smart pointer of this | 
|  | /// type. | 
|  | /// | 
|  | /// If `T: !Unpin` it will not be able to move afterwards. | 
|  | fn pin_init<E>(init: impl PinInit<T, E>) -> error::Result<Pin<Self>> | 
|  | where | 
|  | Error: From<E>, | 
|  | { | 
|  | // SAFETY: We delegate to `init` and only change the error type. | 
|  | let init = unsafe { | 
|  | pin_init_from_closure(|slot| init.__pinned_init(slot).map_err(|e| Error::from(e))) | 
|  | }; | 
|  | Self::try_pin_init(init) | 
|  | } | 
|  |  | 
|  | /// Use the given initializer to in-place initialize a `T`. | 
|  | fn try_init<E>(init: impl Init<T, E>) -> Result<Self, E> | 
|  | where | 
|  | E: From<AllocError>; | 
|  |  | 
|  | /// Use the given initializer to in-place initialize a `T`. | 
|  | fn init<E>(init: impl Init<T, E>) -> error::Result<Self> | 
|  | where | 
|  | Error: From<E>, | 
|  | { | 
|  | // SAFETY: We delegate to `init` and only change the error type. | 
|  | let init = unsafe { | 
|  | init_from_closure(|slot| init.__pinned_init(slot).map_err(|e| Error::from(e))) | 
|  | }; | 
|  | Self::try_init(init) | 
|  | } | 
|  | } | 
|  |  | 
|  | impl<T> InPlaceInit<T> for Box<T> { | 
|  | #[inline] | 
|  | fn try_pin_init<E>(init: impl PinInit<T, E>) -> Result<Pin<Self>, E> | 
|  | where | 
|  | E: From<AllocError>, | 
|  | { | 
|  | let mut this = Box::try_new_uninit()?; | 
|  | let slot = this.as_mut_ptr(); | 
|  | // SAFETY: When init errors/panics, slot will get deallocated but not dropped, | 
|  | // slot is valid and will not be moved, because we pin it later. | 
|  | unsafe { init.__pinned_init(slot)? }; | 
|  | // SAFETY: All fields have been initialized. | 
|  | Ok(unsafe { this.assume_init() }.into()) | 
|  | } | 
|  |  | 
|  | #[inline] | 
|  | fn try_init<E>(init: impl Init<T, E>) -> Result<Self, E> | 
|  | where | 
|  | E: From<AllocError>, | 
|  | { | 
|  | let mut this = Box::try_new_uninit()?; | 
|  | let slot = this.as_mut_ptr(); | 
|  | // SAFETY: When init errors/panics, slot will get deallocated but not dropped, | 
|  | // slot is valid. | 
|  | unsafe { init.__init(slot)? }; | 
|  | // SAFETY: All fields have been initialized. | 
|  | Ok(unsafe { this.assume_init() }) | 
|  | } | 
|  | } | 
|  |  | 
|  | impl<T> InPlaceInit<T> for UniqueArc<T> { | 
|  | #[inline] | 
|  | fn try_pin_init<E>(init: impl PinInit<T, E>) -> Result<Pin<Self>, E> | 
|  | where | 
|  | E: From<AllocError>, | 
|  | { | 
|  | let mut this = UniqueArc::try_new_uninit()?; | 
|  | let slot = this.as_mut_ptr(); | 
|  | // SAFETY: When init errors/panics, slot will get deallocated but not dropped, | 
|  | // slot is valid and will not be moved, because we pin it later. | 
|  | unsafe { init.__pinned_init(slot)? }; | 
|  | // SAFETY: All fields have been initialized. | 
|  | Ok(unsafe { this.assume_init() }.into()) | 
|  | } | 
|  |  | 
|  | #[inline] | 
|  | fn try_init<E>(init: impl Init<T, E>) -> Result<Self, E> | 
|  | where | 
|  | E: From<AllocError>, | 
|  | { | 
|  | let mut this = UniqueArc::try_new_uninit()?; | 
|  | let slot = this.as_mut_ptr(); | 
|  | // SAFETY: When init errors/panics, slot will get deallocated but not dropped, | 
|  | // slot is valid. | 
|  | unsafe { init.__init(slot)? }; | 
|  | // SAFETY: All fields have been initialized. | 
|  | Ok(unsafe { this.assume_init() }) | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Trait facilitating pinned destruction. | 
|  | /// | 
|  | /// Use [`pinned_drop`] to implement this trait safely: | 
|  | /// | 
|  | /// ```rust | 
|  | /// # use kernel::sync::Mutex; | 
|  | /// use kernel::macros::pinned_drop; | 
|  | /// use core::pin::Pin; | 
|  | /// #[pin_data(PinnedDrop)] | 
|  | /// struct Foo { | 
|  | ///     #[pin] | 
|  | ///     mtx: Mutex<usize>, | 
|  | /// } | 
|  | /// | 
|  | /// #[pinned_drop] | 
|  | /// impl PinnedDrop for Foo { | 
|  | ///     fn drop(self: Pin<&mut Self>) { | 
|  | ///         pr_info!("Foo is being dropped!"); | 
|  | ///     } | 
|  | /// } | 
|  | /// ``` | 
|  | /// | 
|  | /// # Safety | 
|  | /// | 
|  | /// This trait must be implemented via the [`pinned_drop`] proc-macro attribute on the impl. | 
|  | /// | 
|  | /// [`pinned_drop`]: kernel::macros::pinned_drop | 
|  | pub unsafe trait PinnedDrop: __internal::HasPinData { | 
|  | /// Executes the pinned destructor of this type. | 
|  | /// | 
|  | /// While this function is marked safe, it is actually unsafe to call it manually. For this | 
|  | /// reason it takes an additional parameter. This type can only be constructed by `unsafe` code | 
|  | /// and thus prevents this function from being called where it should not. | 
|  | /// | 
|  | /// This extra parameter will be generated by the `#[pinned_drop]` proc-macro attribute | 
|  | /// automatically. | 
|  | fn drop(self: Pin<&mut Self>, only_call_from_drop: __internal::OnlyCallFromDrop); | 
|  | } | 
|  |  | 
|  | /// Marker trait for types that can be initialized by writing just zeroes. | 
|  | /// | 
|  | /// # Safety | 
|  | /// | 
|  | /// The bit pattern consisting of only zeroes is a valid bit pattern for this type. In other words, | 
|  | /// this is not UB: | 
|  | /// | 
|  | /// ```rust,ignore | 
|  | /// let val: Self = unsafe { core::mem::zeroed() }; | 
|  | /// ``` | 
|  | pub unsafe trait Zeroable {} | 
|  |  | 
|  | /// Create a new zeroed T. | 
|  | /// | 
|  | /// The returned initializer will write `0x00` to every byte of the given `slot`. | 
|  | #[inline] | 
|  | pub fn zeroed<T: Zeroable>() -> impl Init<T> { | 
|  | // SAFETY: Because `T: Zeroable`, all bytes zero is a valid bit pattern for `T` | 
|  | // and because we write all zeroes, the memory is initialized. | 
|  | unsafe { | 
|  | init_from_closure(|slot: *mut T| { | 
|  | slot.write_bytes(0, 1); | 
|  | Ok(()) | 
|  | }) | 
|  | } | 
|  | } | 
|  |  | 
|  | macro_rules! impl_zeroable { | 
|  | ($($({$($generics:tt)*})? $t:ty, )*) => { | 
|  | $(unsafe impl$($($generics)*)? Zeroable for $t {})* | 
|  | }; | 
|  | } | 
|  |  | 
|  | impl_zeroable! { | 
|  | // SAFETY: All primitives that are allowed to be zero. | 
|  | bool, | 
|  | char, | 
|  | u8, u16, u32, u64, u128, usize, | 
|  | i8, i16, i32, i64, i128, isize, | 
|  | f32, f64, | 
|  |  | 
|  | // SAFETY: These are ZSTs, there is nothing to zero. | 
|  | {<T: ?Sized>} PhantomData<T>, core::marker::PhantomPinned, Infallible, (), | 
|  |  | 
|  | // SAFETY: Type is allowed to take any value, including all zeros. | 
|  | {<T>} MaybeUninit<T>, | 
|  | // SAFETY: Type is allowed to take any value, including all zeros. | 
|  | {<T>} Opaque<T>, | 
|  |  | 
|  | // SAFETY: `T: Zeroable` and `UnsafeCell` is `repr(transparent)`. | 
|  | {<T: ?Sized + Zeroable>} UnsafeCell<T>, | 
|  |  | 
|  | // SAFETY: All zeros is equivalent to `None` (option layout optimization guarantee). | 
|  | Option<NonZeroU8>, Option<NonZeroU16>, Option<NonZeroU32>, Option<NonZeroU64>, | 
|  | Option<NonZeroU128>, Option<NonZeroUsize>, | 
|  | Option<NonZeroI8>, Option<NonZeroI16>, Option<NonZeroI32>, Option<NonZeroI64>, | 
|  | Option<NonZeroI128>, Option<NonZeroIsize>, | 
|  |  | 
|  | // SAFETY: All zeros is equivalent to `None` (option layout optimization guarantee). | 
|  | // | 
|  | // In this case we are allowed to use `T: ?Sized`, since all zeros is the `None` variant. | 
|  | {<T: ?Sized>} Option<NonNull<T>>, | 
|  | {<T: ?Sized>} Option<Box<T>>, | 
|  |  | 
|  | // SAFETY: `null` pointer is valid. | 
|  | // | 
|  | // We cannot use `T: ?Sized`, since the VTABLE pointer part of fat pointers is not allowed to be | 
|  | // null. | 
|  | // | 
|  | // When `Pointee` gets stabilized, we could use | 
|  | // `T: ?Sized where <T as Pointee>::Metadata: Zeroable` | 
|  | {<T>} *mut T, {<T>} *const T, | 
|  |  | 
|  | // SAFETY: `null` pointer is valid and the metadata part of these fat pointers is allowed to be | 
|  | // zero. | 
|  | {<T>} *mut [T], {<T>} *const [T], *mut str, *const str, | 
|  |  | 
|  | // SAFETY: `T` is `Zeroable`. | 
|  | {<const N: usize, T: Zeroable>} [T; N], {<T: Zeroable>} Wrapping<T>, | 
|  | } | 
|  |  | 
|  | macro_rules! impl_tuple_zeroable { | 
|  | ($(,)?) => {}; | 
|  | ($first:ident, $($t:ident),* $(,)?) => { | 
|  | // SAFETY: All elements are zeroable and padding can be zero. | 
|  | unsafe impl<$first: Zeroable, $($t: Zeroable),*> Zeroable for ($first, $($t),*) {} | 
|  | impl_tuple_zeroable!($($t),* ,); | 
|  | } | 
|  | } | 
|  |  | 
|  | impl_tuple_zeroable!(A, B, C, D, E, F, G, H, I, J); |