1 // SPDX-License-Identifier: Apache-2.0 OR MIT
3 //! API to safely and fallibly initialize pinned `struct`s using in-place constructors.
5 //! It also allows in-place initialization of big `struct`s that would otherwise produce a stack
8 //! Most `struct`s from the [`sync`] module need to be pinned, because they contain self-referential
9 //! `struct`s from C. [Pinning][pinning] is Rust's way of ensuring data does not move.
13 //! To initialize a `struct` with an in-place constructor you will need two things:
14 //! - an in-place constructor,
15 //! - a memory location that can hold your `struct` (this can be the [stack], an [`Arc<T>`],
16 //! [`UniqueArc<T>`], [`Box<T>`] or any other smart pointer that implements [`InPlaceInit`]).
18 //! To get an in-place constructor there are generally three options:
19 //! - directly creating an in-place constructor using the [`pin_init!`] macro,
20 //! - a custom function/macro returning an in-place constructor provided by someone else,
21 //! - using the unsafe function [`pin_init_from_closure()`] to manually create an initializer.
23 //! Aside from pinned initialization, this API also supports in-place construction without pinning,
24 //! the macros/types/functions are generally named like the pinned variants without the `pin`
29 //! ## Using the [`pin_init!`] macro
31 //! If you want to use [`PinInit`], then you will have to annotate your `struct` with
32 //! `#[`[`pin_data`]`]`. It is a macro that uses `#[pin]` as a marker for
33 //! [structurally pinned fields]. After doing this, you can then create an in-place constructor via
34 //! [`pin_init!`]. The syntax is almost the same as normal `struct` initializers. The difference is
35 //! that you need to write `<-` instead of `:` for fields that you want to initialize in-place.
38 //! # #![allow(clippy::disallowed_names)]
39 //! use kernel::{prelude::*, sync::Mutex, new_mutex};
40 //! # use core::pin::Pin;
48 //! let foo = pin_init!(Foo {
49 //! a <- new_mutex!(42, "Foo::a"),
54 //! `foo` now is of the type [`impl PinInit<Foo>`]. We can now use any smart pointer that we like
55 //! (or just the stack) to actually initialize a `Foo`:
58 //! # #![allow(clippy::disallowed_names)]
59 //! # use kernel::{prelude::*, sync::Mutex, new_mutex};
60 //! # use core::pin::Pin;
64 //! # a: Mutex<usize>,
67 //! # let foo = pin_init!(Foo {
68 //! # a <- new_mutex!(42, "Foo::a"),
71 //! let foo: Result<Pin<Box<Foo>>> = Box::pin_init(foo);
74 //! For more information see the [`pin_init!`] macro.
76 //! ## Using a custom function/macro that returns an initializer
78 //! Many types from the kernel supply a function/macro that returns an initializer, because the
79 //! above method only works for types where you can access the fields.
82 //! # use kernel::{new_mutex, sync::{Arc, Mutex}};
83 //! let mtx: Result<Arc<Mutex<usize>>> = Arc::pin_init(new_mutex!(42, "example::mtx"));
86 //! To declare an init macro/function you just return an [`impl PinInit<T, E>`]:
89 //! # #![allow(clippy::disallowed_names)]
90 //! # use kernel::{sync::Mutex, prelude::*, new_mutex, init::PinInit, try_pin_init};
92 //! struct DriverData {
94 //! status: Mutex<i32>,
95 //! buffer: Box<[u8; 1_000_000]>,
99 //! fn new() -> impl PinInit<Self, Error> {
100 //! try_pin_init!(Self {
101 //! status <- new_mutex!(0, "DriverData::status"),
102 //! buffer: Box::init(kernel::init::zeroed())?,
108 //! ## Manual creation of an initializer
110 //! Often when working with primitives the previous approaches are not sufficient. That is where
111 //! [`pin_init_from_closure()`] comes in. This `unsafe` function allows you to create a
112 //! [`impl PinInit<T, E>`] directly from a closure. Of course you have to ensure that the closure
113 //! actually does the initialization in the correct way. Here are the things to look out for
114 //! (we are calling the parameter to the closure `slot`):
115 //! - when the closure returns `Ok(())`, then it has completed the initialization successfully, so
116 //! `slot` now contains a valid bit pattern for the type `T`,
117 //! - when the closure returns `Err(e)`, then the caller may deallocate the memory at `slot`, so
118 //! you need to take care to clean up anything if your initialization fails mid-way,
119 //! - you may assume that `slot` will stay pinned even after the closure returns until `drop` of
120 //! `slot` gets called.
123 //! # #![allow(unreachable_pub, clippy::disallowed_names)]
124 //! use kernel::{prelude::*, init, types::Opaque};
125 //! use core::{ptr::addr_of_mut, marker::PhantomPinned, pin::Pin};
127 //! # #![allow(non_camel_case_types)]
128 //! # pub struct foo;
129 //! # pub unsafe fn init_foo(_ptr: *mut foo) {}
130 //! # pub unsafe fn destroy_foo(_ptr: *mut foo) {}
131 //! # pub unsafe fn enable_foo(_ptr: *mut foo, _flags: u32) -> i32 { 0 }
133 //! # // `Error::from_errno` is `pub(crate)` in the `kernel` crate, thus provide a workaround.
134 //! # trait FromErrno {
135 //! # fn from_errno(errno: core::ffi::c_int) -> Error {
136 //! # // Dummy error that can be constructed outside the `kernel` crate.
137 //! # Error::from(core::fmt::Error)
140 //! # impl FromErrno for Error {}
143 //! /// `foo` is always initialized
144 //! #[pin_data(PinnedDrop)]
145 //! pub struct RawFoo {
147 //! foo: Opaque<bindings::foo>,
149 //! _p: PhantomPinned,
153 //! pub fn new(flags: u32) -> impl PinInit<Self, Error> {
155 //! // - when the closure returns `Ok(())`, then it has successfully initialized and
156 //! // enabled `foo`,
157 //! // - when it returns `Err(e)`, then it has cleaned up before
159 //! init::pin_init_from_closure(move |slot: *mut Self| {
160 //! // `slot` contains uninit memory, avoid creating a reference.
161 //! let foo = addr_of_mut!((*slot).foo);
163 //! // Initialize the `foo`
164 //! bindings::init_foo(Opaque::raw_get(foo));
166 //! // Try to enable it.
167 //! let err = bindings::enable_foo(Opaque::raw_get(foo), flags);
169 //! // Enabling has failed, first clean up the foo and then return the error.
170 //! bindings::destroy_foo(Opaque::raw_get(foo));
171 //! return Err(Error::from_errno(err));
174 //! // All fields of `RawFoo` have been initialized, since `_p` is a ZST.
182 //! impl PinnedDrop for RawFoo {
183 //! fn drop(self: Pin<&mut Self>) {
184 //! // SAFETY: Since `foo` is initialized, destroying is safe.
185 //! unsafe { bindings::destroy_foo(self.foo.get()) };
190 //! For the special case where initializing a field is a single FFI-function call that cannot fail,
191 //! there exist the helper function [`Opaque::ffi_init`]. This function initialize a single
192 //! [`Opaque`] field by just delegating to the supplied closure. You can use these in combination
193 //! with [`pin_init!`].
195 //! For more information on how to use [`pin_init_from_closure()`], take a look at the uses inside
196 //! the `kernel` crate. The [`sync`] module is a good starting point.
198 //! [`sync`]: kernel::sync
199 //! [pinning]: https://doc.rust-lang.org/std/pin/index.html
200 //! [structurally pinned fields]:
201 //! https://doc.rust-lang.org/std/pin/index.html#pinning-is-structural-for-field
202 //! [stack]: crate::stack_pin_init
203 //! [`Arc<T>`]: crate::sync::Arc
204 //! [`impl PinInit<Foo>`]: PinInit
205 //! [`impl PinInit<T, E>`]: PinInit
206 //! [`impl Init<T, E>`]: Init
207 //! [`Opaque`]: kernel::types::Opaque
208 //! [`Opaque::ffi_init`]: kernel::types::Opaque::ffi_init
209 //! [`pin_data`]: ::macros::pin_data
210 //! [`pin_init!`]: crate::pin_init!
213 error::{self, Error},
215 types::{Opaque, ScopeGuard},
217 use alloc::boxed::Box;
226 ptr::{self, NonNull},
234 /// Initialize and pin a type directly on the stack.
239 /// # #![allow(clippy::disallowed_names)]
240 /// # use kernel::{init, macros::pin_data, pin_init, stack_pin_init, init::*, sync::Mutex, new_mutex};
241 /// # use core::pin::Pin;
254 /// stack_pin_init!(let foo = pin_init!(Foo {
255 /// a <- new_mutex!(42),
260 /// let foo: Pin<&mut Foo> = foo;
261 /// pr_info!("a: {}", &*foo.a.lock());
266 /// A normal `let` binding with optional type annotation. The expression is expected to implement
267 /// [`PinInit`]/[`Init`] with the error type [`Infallible`]. If you want to use a different error
268 /// type, then use [`stack_try_pin_init!`].
270 /// [`stack_try_pin_init!`]: crate::stack_try_pin_init!
272 macro_rules! stack_pin_init {
273 (let $var:ident $(: $t:ty)? = $val:expr) => {
275 let mut $var = ::core::pin::pin!($crate::init::__internal::StackInit$(::<$t>)?::uninit());
276 let mut $var = match $crate::init::__internal::StackInit::init($var, val) {
279 let x: ::core::convert::Infallible = x;
286 /// Initialize and pin a type directly on the stack.
291 /// # #![allow(clippy::disallowed_names)]
292 /// # use kernel::{init, pin_init, stack_try_pin_init, init::*, sync::Mutex, new_mutex};
293 /// # use macros::pin_data;
294 /// # use core::{alloc::AllocError, pin::Pin};
306 /// stack_try_pin_init!(let foo: Result<Pin<&mut Foo>, AllocError> = pin_init!(Foo {
307 /// a <- new_mutex!(42),
308 /// b: Box::try_new(Bar {
312 /// let foo = foo.unwrap();
313 /// pr_info!("a: {}", &*foo.a.lock());
317 /// # #![allow(clippy::disallowed_names)]
318 /// # use kernel::{init, pin_init, stack_try_pin_init, init::*, sync::Mutex, new_mutex};
319 /// # use macros::pin_data;
320 /// # use core::{alloc::AllocError, pin::Pin};
332 /// stack_try_pin_init!(let foo: Pin<&mut Foo> =? pin_init!(Foo {
333 /// a <- new_mutex!(42),
334 /// b: Box::try_new(Bar {
338 /// pr_info!("a: {}", &*foo.a.lock());
339 /// # Ok::<_, AllocError>(())
344 /// A normal `let` binding with optional type annotation. The expression is expected to implement
345 /// [`PinInit`]/[`Init`]. This macro assigns a result to the given variable, adding a `?` after the
346 /// `=` will propagate this error.
348 macro_rules! stack_try_pin_init {
349 (let $var:ident $(: $t:ty)? = $val:expr) => {
351 let mut $var = ::core::pin::pin!($crate::init::__internal::StackInit$(::<$t>)?::uninit());
352 let mut $var = $crate::init::__internal::StackInit::init($var, val);
354 (let $var:ident $(: $t:ty)? =? $val:expr) => {
356 let mut $var = ::core::pin::pin!($crate::init::__internal::StackInit$(::<$t>)?::uninit());
357 let mut $var = $crate::init::__internal::StackInit::init($var, val)?;
361 /// Construct an in-place, pinned initializer for `struct`s.
363 /// This macro defaults the error to [`Infallible`]. If you need [`Error`], then use
364 /// [`try_pin_init!`].
366 /// The syntax is almost identical to that of a normal `struct` initializer:
369 /// # #![allow(clippy::disallowed_names)]
370 /// # use kernel::{init, pin_init, macros::pin_data, init::*};
371 /// # use core::pin::Pin;
383 /// # fn demo() -> impl PinInit<Foo> {
386 /// let initializer = pin_init!(Foo {
393 /// # Box::pin_init(demo()).unwrap();
396 /// Arbitrary Rust expressions can be used to set the value of a variable.
398 /// The fields are initialized in the order that they appear in the initializer. So it is possible
399 /// to read already initialized fields using raw pointers.
401 /// IMPORTANT: You are not allowed to create references to fields of the struct inside of the
406 /// When working with this API it is often desired to let others construct your types without
407 /// giving access to all fields. This is where you would normally write a plain function `new`
408 /// that would return a new instance of your type. With this API that is also possible.
409 /// However, there are a few extra things to keep in mind.
411 /// To create an initializer function, simply declare it like this:
414 /// # #![allow(clippy::disallowed_names)]
415 /// # use kernel::{init, pin_init, prelude::*, init::*};
416 /// # use core::pin::Pin;
427 /// fn new() -> impl PinInit<Self> {
438 /// Users of `Foo` can now create it like this:
441 /// # #![allow(clippy::disallowed_names)]
442 /// # use kernel::{init, pin_init, macros::pin_data, init::*};
443 /// # use core::pin::Pin;
454 /// # fn new() -> impl PinInit<Self> {
455 /// # pin_init!(Self {
463 /// let foo = Box::pin_init(Foo::new());
466 /// They can also easily embed it into their own `struct`s:
469 /// # #![allow(clippy::disallowed_names)]
470 /// # use kernel::{init, pin_init, macros::pin_data, init::*};
471 /// # use core::pin::Pin;
482 /// # fn new() -> impl PinInit<Self> {
483 /// # pin_init!(Self {
492 /// struct FooContainer {
500 /// impl FooContainer {
501 /// fn new(other: u32) -> impl PinInit<Self> {
503 /// foo1 <- Foo::new(),
504 /// foo2 <- Foo::new(),
511 /// Here we see that when using `pin_init!` with `PinInit`, one needs to write `<-` instead of `:`.
512 /// This signifies that the given field is initialized in-place. As with `struct` initializers, just
513 /// writing the field (in this case `other`) without `:` or `<-` means `other: other,`.
517 /// As already mentioned in the examples above, inside of `pin_init!` a `struct` initializer with
518 /// the following modifications is expected:
519 /// - Fields that you want to initialize in-place have to use `<-` instead of `:`.
520 /// - In front of the initializer you can write `&this in` to have access to a [`NonNull<Self>`]
521 /// pointer named `this` inside of the initializer.
522 /// - Using struct update syntax one can place `..Zeroable::zeroed()` at the very end of the
523 /// struct, this initializes every field with 0 and then runs all initializers specified in the
524 /// body. This can only be done if [`Zeroable`] is implemented for the struct.
529 /// # use kernel::{macros::{Zeroable, pin_data}, pin_init};
530 /// # use core::{ptr::addr_of_mut, marker::PhantomPinned};
532 /// #[derive(Zeroable)]
534 /// // `ptr` points into `buf`.
538 /// pin: PhantomPinned,
540 /// pin_init!(&this in Buf {
542 /// ptr: unsafe { addr_of_mut!((*this.as_ptr()).buf).cast() },
543 /// pin: PhantomPinned,
547 /// ..Zeroable::zeroed()
551 /// [`try_pin_init!`]: kernel::try_pin_init
552 /// [`NonNull<Self>`]: core::ptr::NonNull
553 // For a detailed example of how this macro works, see the module documentation of the hidden
554 // module `__internal` inside of `init/__internal.rs`.
556 macro_rules! pin_init {
557 ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {
560 $crate::__init_internal!(
562 @typ($t $(::<$($generics),*>)?),
563 @fields($($fields)*),
564 @error(::core::convert::Infallible),
565 @data(PinData, use_data),
566 @has_data(HasPinData, __pin_data),
567 @construct_closure(pin_init_from_closure),
568 @munch_fields($($fields)*),
573 /// Construct an in-place, fallible pinned initializer for `struct`s.
575 /// If the initialization can complete without error (or [`Infallible`]), then use [`pin_init!`].
577 /// You can use the `?` operator or use `return Err(err)` inside the initializer to stop
578 /// initialization and return the error.
580 /// IMPORTANT: if you have `unsafe` code inside of the initializer you have to ensure that when
581 /// initialization fails, the memory can be safely deallocated without any further modifications.
583 /// This macro defaults the error to [`Error`].
585 /// The syntax is identical to [`pin_init!`] with the following exception: you can append `? $type`
586 /// after the `struct` initializer to specify the error type you want to use.
591 /// # #![feature(new_uninit)]
592 /// use kernel::{init::{self, PinInit}, error::Error};
595 /// big: Box<[u8; 1024 * 1024 * 1024]>,
596 /// small: [u8; 1024 * 1024],
601 /// fn new() -> impl PinInit<Self, Error> {
602 /// try_pin_init!(Self {
603 /// big: Box::init(init::zeroed())?,
604 /// small: [0; 1024 * 1024],
605 /// ptr: core::ptr::null_mut(),
610 // For a detailed example of how this macro works, see the module documentation of the hidden
611 // module `__internal` inside of `init/__internal.rs`.
613 macro_rules! try_pin_init {
614 ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {
617 $crate::__init_internal!(
619 @typ($t $(::<$($generics),*>)? ),
620 @fields($($fields)*),
621 @error($crate::error::Error),
622 @data(PinData, use_data),
623 @has_data(HasPinData, __pin_data),
624 @construct_closure(pin_init_from_closure),
625 @munch_fields($($fields)*),
628 ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {
631 $crate::__init_internal!(
633 @typ($t $(::<$($generics),*>)? ),
634 @fields($($fields)*),
636 @data(PinData, use_data),
637 @has_data(HasPinData, __pin_data),
638 @construct_closure(pin_init_from_closure),
639 @munch_fields($($fields)*),
644 /// Construct an in-place initializer for `struct`s.
646 /// This macro defaults the error to [`Infallible`]. If you need [`Error`], then use
649 /// The syntax is identical to [`pin_init!`] and its safety caveats also apply:
650 /// - `unsafe` code must guarantee either full initialization or return an error and allow
651 /// deallocation of the memory.
652 /// - the fields are initialized in the order given in the initializer.
653 /// - no references to fields are allowed to be created inside of the initializer.
655 /// This initializer is for initializing data in-place that might later be moved. If you want to
656 /// pin-initialize, use [`pin_init!`].
658 /// [`try_init!`]: crate::try_init!
659 // For a detailed example of how this macro works, see the module documentation of the hidden
660 // module `__internal` inside of `init/__internal.rs`.
663 ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {
666 $crate::__init_internal!(
668 @typ($t $(::<$($generics),*>)?),
669 @fields($($fields)*),
670 @error(::core::convert::Infallible),
671 @data(InitData, /*no use_data*/),
672 @has_data(HasInitData, __init_data),
673 @construct_closure(init_from_closure),
674 @munch_fields($($fields)*),
679 /// Construct an in-place fallible initializer for `struct`s.
681 /// This macro defaults the error to [`Error`]. If you need [`Infallible`], then use
684 /// The syntax is identical to [`try_pin_init!`]. If you want to specify a custom error,
685 /// append `? $type` after the `struct` initializer.
686 /// The safety caveats from [`try_pin_init!`] also apply:
687 /// - `unsafe` code must guarantee either full initialization or return an error and allow
688 /// deallocation of the memory.
689 /// - the fields are initialized in the order given in the initializer.
690 /// - no references to fields are allowed to be created inside of the initializer.
695 /// use kernel::{init::{PinInit, zeroed}, error::Error};
697 /// big: Box<[u8; 1024 * 1024 * 1024]>,
698 /// small: [u8; 1024 * 1024],
702 /// fn new() -> impl Init<Self, Error> {
704 /// big: Box::init(zeroed())?,
705 /// small: [0; 1024 * 1024],
710 // For a detailed example of how this macro works, see the module documentation of the hidden
711 // module `__internal` inside of `init/__internal.rs`.
713 macro_rules! try_init {
714 ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {
717 $crate::__init_internal!(
719 @typ($t $(::<$($generics),*>)?),
720 @fields($($fields)*),
721 @error($crate::error::Error),
722 @data(InitData, /*no use_data*/),
723 @has_data(HasInitData, __init_data),
724 @construct_closure(init_from_closure),
725 @munch_fields($($fields)*),
728 ($(&$this:ident in)? $t:ident $(::<$($generics:ty),* $(,)?>)? {
731 $crate::__init_internal!(
733 @typ($t $(::<$($generics),*>)?),
734 @fields($($fields)*),
736 @data(InitData, /*no use_data*/),
737 @has_data(HasInitData, __init_data),
738 @construct_closure(init_from_closure),
739 @munch_fields($($fields)*),
744 /// A pin-initializer for the type `T`.
746 /// To use this initializer, you will need a suitable memory location that can hold a `T`. This can
747 /// be [`Box<T>`], [`Arc<T>`], [`UniqueArc<T>`] or even the stack (see [`stack_pin_init!`]). Use the
748 /// [`InPlaceInit::pin_init`] function of a smart pointer like [`Arc<T>`] on this.
750 /// Also see the [module description](self).
754 /// When implementing this type you will need to take great care. Also there are probably very few
755 /// cases where a manual implementation is necessary. Use [`pin_init_from_closure`] where possible.
757 /// The [`PinInit::__pinned_init`] function
758 /// - returns `Ok(())` if it initialized every field of `slot`,
759 /// - returns `Err(err)` if it encountered an error and then cleaned `slot`, this means:
760 /// - `slot` can be deallocated without UB occurring,
761 /// - `slot` does not need to be dropped,
762 /// - `slot` is not partially initialized.
763 /// - while constructing the `T` at `slot` it upholds the pinning invariants of `T`.
765 /// [`Arc<T>`]: crate::sync::Arc
766 /// [`Arc::pin_init`]: crate::sync::Arc::pin_init
767 #[must_use = "An initializer must be used in order to create its value."]
768 pub unsafe trait PinInit<T: ?Sized, E = Infallible>: Sized {
769 /// Initializes `slot`.
773 /// - `slot` is a valid pointer to uninitialized memory.
774 /// - the caller does not touch `slot` when `Err` is returned, they are only permitted to
776 /// - `slot` will not move until it is dropped, i.e. it will be pinned.
777 unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E>;
779 /// First initializes the value using `self` then calls the function `f` with the initialized
782 /// If `f` returns an error the value is dropped and the initializer will forward the error.
787 /// # #![allow(clippy::disallowed_names)]
788 /// use kernel::{types::Opaque, init::pin_init_from_closure};
790 /// struct RawFoo([u8; 16]);
792 /// fn init_foo(_: *mut RawFoo);
798 /// raw: Opaque<RawFoo>,
802 /// fn setup(self: Pin<&mut Self>) {
803 /// pr_info!("Setting up foo");
807 /// let foo = pin_init!(Foo {
809 /// Opaque::ffi_init(|s| {
813 /// }).pin_chain(|foo| {
818 fn pin_chain<F>(self, f: F) -> ChainPinInit<Self, F, T, E>
820 F: FnOnce(Pin<&mut T>) -> Result<(), E>,
822 ChainPinInit(self, f, PhantomData)
826 /// An initializer returned by [`PinInit::pin_chain`].
827 pub struct ChainPinInit<I, F, T: ?Sized, E>(I, F, __internal::Invariant<(E, Box<T>)>);
829 // SAFETY: The `__pinned_init` function is implemented such that it
830 // - returns `Ok(())` on successful initialization,
831 // - returns `Err(err)` on error and in this case `slot` will be dropped.
832 // - considers `slot` pinned.
833 unsafe impl<T: ?Sized, E, I, F> PinInit<T, E> for ChainPinInit<I, F, T, E>
836 F: FnOnce(Pin<&mut T>) -> Result<(), E>,
838 unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E> {
839 // SAFETY: All requirements fulfilled since this function is `__pinned_init`.
840 unsafe { self.0.__pinned_init(slot)? };
841 // SAFETY: The above call initialized `slot` and we still have unique access.
842 let val = unsafe { &mut *slot };
843 // SAFETY: `slot` is considered pinned.
844 let val = unsafe { Pin::new_unchecked(val) };
845 (self.1)(val).map_err(|e| {
846 // SAFETY: `slot` was initialized above.
847 unsafe { core::ptr::drop_in_place(slot) };
853 /// An initializer for `T`.
855 /// To use this initializer, you will need a suitable memory location that can hold a `T`. This can
856 /// be [`Box<T>`], [`Arc<T>`], [`UniqueArc<T>`] or even the stack (see [`stack_pin_init!`]). Use the
857 /// [`InPlaceInit::init`] function of a smart pointer like [`Arc<T>`] on this. Because
858 /// [`PinInit<T, E>`] is a super trait, you can use every function that takes it as well.
860 /// Also see the [module description](self).
864 /// When implementing this type you will need to take great care. Also there are probably very few
865 /// cases where a manual implementation is necessary. Use [`init_from_closure`] where possible.
867 /// The [`Init::__init`] function
868 /// - returns `Ok(())` if it initialized every field of `slot`,
869 /// - returns `Err(err)` if it encountered an error and then cleaned `slot`, this means:
870 /// - `slot` can be deallocated without UB occurring,
871 /// - `slot` does not need to be dropped,
872 /// - `slot` is not partially initialized.
873 /// - while constructing the `T` at `slot` it upholds the pinning invariants of `T`.
875 /// The `__pinned_init` function from the supertrait [`PinInit`] needs to execute the exact same
876 /// code as `__init`.
878 /// Contrary to its supertype [`PinInit<T, E>`] the caller is allowed to
879 /// move the pointee after initialization.
881 /// [`Arc<T>`]: crate::sync::Arc
882 #[must_use = "An initializer must be used in order to create its value."]
883 pub unsafe trait Init<T: ?Sized, E = Infallible>: PinInit<T, E> {
884 /// Initializes `slot`.
888 /// - `slot` is a valid pointer to uninitialized memory.
889 /// - the caller does not touch `slot` when `Err` is returned, they are only permitted to
891 unsafe fn __init(self, slot: *mut T) -> Result<(), E>;
893 /// First initializes the value using `self` then calls the function `f` with the initialized
896 /// If `f` returns an error the value is dropped and the initializer will forward the error.
901 /// # #![allow(clippy::disallowed_names)]
902 /// use kernel::{types::Opaque, init::{self, init_from_closure}};
904 /// buf: [u8; 1_000_000],
908 /// fn setup(&mut self) {
909 /// pr_info!("Setting up foo");
913 /// let foo = init!(Foo {
914 /// buf <- init::zeroed()
920 fn chain<F>(self, f: F) -> ChainInit<Self, F, T, E>
922 F: FnOnce(&mut T) -> Result<(), E>,
924 ChainInit(self, f, PhantomData)
928 /// An initializer returned by [`Init::chain`].
929 pub struct ChainInit<I, F, T: ?Sized, E>(I, F, __internal::Invariant<(E, Box<T>)>);
931 // SAFETY: The `__init` function is implemented such that it
932 // - returns `Ok(())` on successful initialization,
933 // - returns `Err(err)` on error and in this case `slot` will be dropped.
934 unsafe impl<T: ?Sized, E, I, F> Init<T, E> for ChainInit<I, F, T, E>
937 F: FnOnce(&mut T) -> Result<(), E>,
939 unsafe fn __init(self, slot: *mut T) -> Result<(), E> {
940 // SAFETY: All requirements fulfilled since this function is `__init`.
941 unsafe { self.0.__pinned_init(slot)? };
942 // SAFETY: The above call initialized `slot` and we still have unique access.
943 (self.1)(unsafe { &mut *slot }).map_err(|e| {
944 // SAFETY: `slot` was initialized above.
945 unsafe { core::ptr::drop_in_place(slot) };
951 // SAFETY: `__pinned_init` behaves exactly the same as `__init`.
952 unsafe impl<T: ?Sized, E, I, F> PinInit<T, E> for ChainInit<I, F, T, E>
955 F: FnOnce(&mut T) -> Result<(), E>,
957 unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E> {
958 // SAFETY: `__init` has less strict requirements compared to `__pinned_init`.
959 unsafe { self.__init(slot) }
963 /// Creates a new [`PinInit<T, E>`] from the given closure.
968 /// - returns `Ok(())` if it initialized every field of `slot`,
969 /// - returns `Err(err)` if it encountered an error and then cleaned `slot`, this means:
970 /// - `slot` can be deallocated without UB occurring,
971 /// - `slot` does not need to be dropped,
972 /// - `slot` is not partially initialized.
973 /// - may assume that the `slot` does not move if `T: !Unpin`,
974 /// - while constructing the `T` at `slot` it upholds the pinning invariants of `T`.
976 pub const unsafe fn pin_init_from_closure<T: ?Sized, E>(
977 f: impl FnOnce(*mut T) -> Result<(), E>,
978 ) -> impl PinInit<T, E> {
979 __internal::InitClosure(f, PhantomData)
982 /// Creates a new [`Init<T, E>`] from the given closure.
987 /// - returns `Ok(())` if it initialized every field of `slot`,
988 /// - returns `Err(err)` if it encountered an error and then cleaned `slot`, this means:
989 /// - `slot` can be deallocated without UB occurring,
990 /// - `slot` does not need to be dropped,
991 /// - `slot` is not partially initialized.
992 /// - the `slot` may move after initialization.
993 /// - while constructing the `T` at `slot` it upholds the pinning invariants of `T`.
995 pub const unsafe fn init_from_closure<T: ?Sized, E>(
996 f: impl FnOnce(*mut T) -> Result<(), E>,
997 ) -> impl Init<T, E> {
998 __internal::InitClosure(f, PhantomData)
1001 /// An initializer that leaves the memory uninitialized.
1003 /// The initializer is a no-op. The `slot` memory is not changed.
1005 pub fn uninit<T, E>() -> impl Init<MaybeUninit<T>, E> {
1006 // SAFETY: The memory is allowed to be uninitialized.
1007 unsafe { init_from_closure(|_| Ok(())) }
1010 /// Initializes an array by initializing each element via the provided initializer.
1015 /// use kernel::{error::Error, init::init_array_from_fn};
1016 /// let array: Box<[usize; 1_000]>= Box::init::<Error>(init_array_from_fn(|i| i)).unwrap();
1017 /// assert_eq!(array.len(), 1_000);
1019 pub fn init_array_from_fn<I, const N: usize, T, E>(
1020 mut make_init: impl FnMut(usize) -> I,
1021 ) -> impl Init<[T; N], E>
1025 let init = move |slot: *mut [T; N]| {
1026 let slot = slot.cast::<T>();
1027 // Counts the number of initialized elements and when dropped drops that many elements from
1029 let mut init_count = ScopeGuard::new_with_data(0, |i| {
1030 // We now free every element that has been initialized before:
1031 // SAFETY: The loop initialized exactly the values from 0..i and since we
1032 // return `Err` below, the caller will consider the memory at `slot` as
1034 unsafe { ptr::drop_in_place(ptr::slice_from_raw_parts_mut(slot, i)) };
1037 let init = make_init(i);
1038 // SAFETY: Since 0 <= `i` < N, it is still in bounds of `[T; N]`.
1039 let ptr = unsafe { slot.add(i) };
1040 // SAFETY: The pointer is derived from `slot` and thus satisfies the `__init`
1042 unsafe { init.__init(ptr) }?;
1045 init_count.dismiss();
1048 // SAFETY: The initializer above initializes every element of the array. On failure it drops
1049 // any initialized elements and returns `Err`.
1050 unsafe { init_from_closure(init) }
1053 /// Initializes an array by initializing each element via the provided initializer.
1058 /// use kernel::{sync::{Arc, Mutex}, init::pin_init_array_from_fn, new_mutex};
1059 /// let array: Arc<[Mutex<usize>; 1_000]>=
1060 /// Arc::pin_init(pin_init_array_from_fn(|i| new_mutex!(i))).unwrap();
1061 /// assert_eq!(array.len(), 1_000);
1063 pub fn pin_init_array_from_fn<I, const N: usize, T, E>(
1064 mut make_init: impl FnMut(usize) -> I,
1065 ) -> impl PinInit<[T; N], E>
1069 let init = move |slot: *mut [T; N]| {
1070 let slot = slot.cast::<T>();
1071 // Counts the number of initialized elements and when dropped drops that many elements from
1073 let mut init_count = ScopeGuard::new_with_data(0, |i| {
1074 // We now free every element that has been initialized before:
1075 // SAFETY: The loop initialized exactly the values from 0..i and since we
1076 // return `Err` below, the caller will consider the memory at `slot` as
1078 unsafe { ptr::drop_in_place(ptr::slice_from_raw_parts_mut(slot, i)) };
1081 let init = make_init(i);
1082 // SAFETY: Since 0 <= `i` < N, it is still in bounds of `[T; N]`.
1083 let ptr = unsafe { slot.add(i) };
1084 // SAFETY: The pointer is derived from `slot` and thus satisfies the `__init`
1086 unsafe { init.__pinned_init(ptr) }?;
1089 init_count.dismiss();
1092 // SAFETY: The initializer above initializes every element of the array. On failure it drops
1093 // any initialized elements and returns `Err`.
1094 unsafe { pin_init_from_closure(init) }
1097 // SAFETY: Every type can be initialized by-value.
1098 unsafe impl<T, E> Init<T, E> for T {
1099 unsafe fn __init(self, slot: *mut T) -> Result<(), E> {
1100 unsafe { slot.write(self) };
1105 // SAFETY: Every type can be initialized by-value. `__pinned_init` calls `__init`.
1106 unsafe impl<T, E> PinInit<T, E> for T {
1107 unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E> {
1108 unsafe { self.__init(slot) }
1112 /// Smart pointer that can initialize memory in-place.
1113 pub trait InPlaceInit<T>: Sized {
1114 /// Use the given pin-initializer to pin-initialize a `T` inside of a new smart pointer of this
1117 /// If `T: !Unpin` it will not be able to move afterwards.
1118 fn try_pin_init<E>(init: impl PinInit<T, E>) -> Result<Pin<Self>, E>
1120 E: From<AllocError>;
1122 /// Use the given pin-initializer to pin-initialize a `T` inside of a new smart pointer of this
1125 /// If `T: !Unpin` it will not be able to move afterwards.
1126 fn pin_init<E>(init: impl PinInit<T, E>) -> error::Result<Pin<Self>>
1130 // SAFETY: We delegate to `init` and only change the error type.
1132 pin_init_from_closure(|slot| init.__pinned_init(slot).map_err(|e| Error::from(e)))
1134 Self::try_pin_init(init)
1137 /// Use the given initializer to in-place initialize a `T`.
1138 fn try_init<E>(init: impl Init<T, E>) -> Result<Self, E>
1140 E: From<AllocError>;
1142 /// Use the given initializer to in-place initialize a `T`.
1143 fn init<E>(init: impl Init<T, E>) -> error::Result<Self>
1147 // SAFETY: We delegate to `init` and only change the error type.
1149 init_from_closure(|slot| init.__pinned_init(slot).map_err(|e| Error::from(e)))
1151 Self::try_init(init)
1155 impl<T> InPlaceInit<T> for Box<T> {
1157 fn try_pin_init<E>(init: impl PinInit<T, E>) -> Result<Pin<Self>, E>
1159 E: From<AllocError>,
1161 let mut this = Box::try_new_uninit()?;
1162 let slot = this.as_mut_ptr();
1163 // SAFETY: When init errors/panics, slot will get deallocated but not dropped,
1164 // slot is valid and will not be moved, because we pin it later.
1165 unsafe { init.__pinned_init(slot)? };
1166 // SAFETY: All fields have been initialized.
1167 Ok(unsafe { this.assume_init() }.into())
1171 fn try_init<E>(init: impl Init<T, E>) -> Result<Self, E>
1173 E: From<AllocError>,
1175 let mut this = Box::try_new_uninit()?;
1176 let slot = this.as_mut_ptr();
1177 // SAFETY: When init errors/panics, slot will get deallocated but not dropped,
1179 unsafe { init.__init(slot)? };
1180 // SAFETY: All fields have been initialized.
1181 Ok(unsafe { this.assume_init() })
1185 impl<T> InPlaceInit<T> for UniqueArc<T> {
1187 fn try_pin_init<E>(init: impl PinInit<T, E>) -> Result<Pin<Self>, E>
1189 E: From<AllocError>,
1191 let mut this = UniqueArc::try_new_uninit()?;
1192 let slot = this.as_mut_ptr();
1193 // SAFETY: When init errors/panics, slot will get deallocated but not dropped,
1194 // slot is valid and will not be moved, because we pin it later.
1195 unsafe { init.__pinned_init(slot)? };
1196 // SAFETY: All fields have been initialized.
1197 Ok(unsafe { this.assume_init() }.into())
1201 fn try_init<E>(init: impl Init<T, E>) -> Result<Self, E>
1203 E: From<AllocError>,
1205 let mut this = UniqueArc::try_new_uninit()?;
1206 let slot = this.as_mut_ptr();
1207 // SAFETY: When init errors/panics, slot will get deallocated but not dropped,
1209 unsafe { init.__init(slot)? };
1210 // SAFETY: All fields have been initialized.
1211 Ok(unsafe { this.assume_init() })
1215 /// Trait facilitating pinned destruction.
1217 /// Use [`pinned_drop`] to implement this trait safely:
1220 /// # use kernel::sync::Mutex;
1221 /// use kernel::macros::pinned_drop;
1222 /// use core::pin::Pin;
1223 /// #[pin_data(PinnedDrop)]
1226 /// mtx: Mutex<usize>,
1230 /// impl PinnedDrop for Foo {
1231 /// fn drop(self: Pin<&mut Self>) {
1232 /// pr_info!("Foo is being dropped!");
1239 /// This trait must be implemented via the [`pinned_drop`] proc-macro attribute on the impl.
1241 /// [`pinned_drop`]: kernel::macros::pinned_drop
1242 pub unsafe trait PinnedDrop: __internal::HasPinData {
1243 /// Executes the pinned destructor of this type.
1245 /// While this function is marked safe, it is actually unsafe to call it manually. For this
1246 /// reason it takes an additional parameter. This type can only be constructed by `unsafe` code
1247 /// and thus prevents this function from being called where it should not.
1249 /// This extra parameter will be generated by the `#[pinned_drop]` proc-macro attribute
1251 fn drop(self: Pin<&mut Self>, only_call_from_drop: __internal::OnlyCallFromDrop);
1254 /// Marker trait for types that can be initialized by writing just zeroes.
1258 /// The bit pattern consisting of only zeroes is a valid bit pattern for this type. In other words,
1262 /// let val: Self = unsafe { core::mem::zeroed() };
1264 pub unsafe trait Zeroable {}
1266 /// Create a new zeroed T.
1268 /// The returned initializer will write `0x00` to every byte of the given `slot`.
1270 pub fn zeroed<T: Zeroable>() -> impl Init<T> {
1271 // SAFETY: Because `T: Zeroable`, all bytes zero is a valid bit pattern for `T`
1272 // and because we write all zeroes, the memory is initialized.
1274 init_from_closure(|slot: *mut T| {
1275 slot.write_bytes(0, 1);
1281 macro_rules! impl_zeroable {
1282 ($($({$($generics:tt)*})? $t:ty, )*) => {
1283 $(unsafe impl$($($generics)*)? Zeroable for $t {})*
1288 // SAFETY: All primitives that are allowed to be zero.
1291 u8, u16, u32, u64, u128, usize,
1292 i8, i16, i32, i64, i128, isize,
1295 // SAFETY: These are ZSTs, there is nothing to zero.
1296 {<T: ?Sized>} PhantomData<T>, core::marker::PhantomPinned, Infallible, (),
1298 // SAFETY: Type is allowed to take any value, including all zeros.
1299 {<T>} MaybeUninit<T>,
1300 // SAFETY: Type is allowed to take any value, including all zeros.
1303 // SAFETY: `T: Zeroable` and `UnsafeCell` is `repr(transparent)`.
1304 {<T: ?Sized + Zeroable>} UnsafeCell<T>,
1306 // SAFETY: All zeros is equivalent to `None` (option layout optimization guarantee).
1307 Option<NonZeroU8>, Option<NonZeroU16>, Option<NonZeroU32>, Option<NonZeroU64>,
1308 Option<NonZeroU128>, Option<NonZeroUsize>,
1309 Option<NonZeroI8>, Option<NonZeroI16>, Option<NonZeroI32>, Option<NonZeroI64>,
1310 Option<NonZeroI128>, Option<NonZeroIsize>,
1312 // SAFETY: All zeros is equivalent to `None` (option layout optimization guarantee).
1314 // In this case we are allowed to use `T: ?Sized`, since all zeros is the `None` variant.
1315 {<T: ?Sized>} Option<NonNull<T>>,
1316 {<T: ?Sized>} Option<Box<T>>,
1318 // SAFETY: `null` pointer is valid.
1320 // We cannot use `T: ?Sized`, since the VTABLE pointer part of fat pointers is not allowed to be
1323 // When `Pointee` gets stabilized, we could use
1324 // `T: ?Sized where <T as Pointee>::Metadata: Zeroable`
1325 {<T>} *mut T, {<T>} *const T,
1327 // SAFETY: `null` pointer is valid and the metadata part of these fat pointers is allowed to be
1329 {<T>} *mut [T], {<T>} *const [T], *mut str, *const str,
1331 // SAFETY: `T` is `Zeroable`.
1332 {<const N: usize, T: Zeroable>} [T; N], {<T: Zeroable>} Wrapping<T>,
1335 macro_rules! impl_tuple_zeroable {
1337 ($first:ident, $($t:ident),* $(,)?) => {
1338 // SAFETY: All elements are zeroable and padding can be zero.
1339 unsafe impl<$first: Zeroable, $($t: Zeroable),*> Zeroable for ($first, $($t),*) {}
1340 impl_tuple_zeroable!($($t),* ,);
1344 impl_tuple_zeroable!(A, B, C, D, E, F, G, H, I, J);