22
22
//!
23
23
//! ## Directly creating an in-place constructor
24
24
//!
25
+ //! If you want to use [`PinInit`], then you will have to annotate your struct with [`#[pin_project]`].
26
+ //! It is a macro that uses `#[pin]` as a marker for [structurally pinned fields].
27
+ //!
25
28
//! ```rust
26
- //! # use kernel::prelude::*;
29
+ //! use kernel::{ prelude::*, sync::Mutex, new_mutex} ;
27
30
//! # use core::pin::Pin;
28
31
//! #[pin_project]
29
32
//! struct Foo {
30
- //! a: usize,
33
+ //! #[pin]
34
+ //! a: Mutex<usize>,
31
35
//! b: u32,
32
36
//! }
33
37
//!
34
38
//! let foo = pin_init!(Foo {
35
- //! a: 42 ,
39
+ //! a: new_mutex!(42, "Foo::a") ,
36
40
//! b: 24,
37
41
//! });
38
42
//! # let foo: Result<Pin<Box<Foo>>> = Box::pin_init::<core::convert::Infallible>(foo);
42
46
//! (or just the stack) to actually initialize a `Foo`:
43
47
//!
44
48
//! ```rust
45
- //! # use kernel::prelude::*;
49
+ //! # use kernel::{ prelude::*, sync::Mutex, new_mutex} ;
46
50
//! # use core::pin::Pin;
47
51
//! # #[pin_project]
48
52
//! # struct Foo {
49
- //! # a: usize,
53
+ //! # #[pin]
54
+ //! # a: Mutex<usize>,
50
55
//! # b: u32,
51
56
//! # }
52
57
//! # let foo = pin_init!(Foo {
53
- //! # a: 42 ,
58
+ //! # a: new_mutex!(42, "Foo::a") ,
54
59
//! # b: 24,
55
60
//! # });
56
61
//! let foo: Result<Pin<Box<Foo>>> = Box::pin_init::<core::convert::Infallible>(foo);
91
96
//!
92
97
//! [sync]: ../sync/index.html
93
98
//! [pinning]: https://doc.rust-lang.org/std/pin/index.html
99
+ //! [structurally pinned fields]: https://doc.rust-lang.org/std/pin/index.html#pinning-is-structural-for-field
94
100
//! [stack]: crate::stack_init
95
101
//! [`Arc<T>`]: crate::sync::Arc
96
102
@@ -111,17 +117,18 @@ use core::{
111
117
pub mod __private;
112
118
mod pin_project;
113
119
114
- /// Initialize a type on the stack.
120
+ /// Initialize a type directly on the stack.
115
121
///
116
122
/// # Examples
117
123
///
118
124
/// ```rust
119
125
/// # #![allow(clippy::blacklisted_name, clippy::new_ret_no_self)]
120
- /// # use kernel::{init, pin_init, stack_init, init::*, macros::pin_project};
126
+ /// # use kernel::{init, pin_init, stack_init, init::*, macros::pin_project, sync::Mutex, new_mutex };
121
127
/// # use core::pin::Pin;
122
128
/// #[pin_project]
123
129
/// struct Foo {
124
- /// a: usize,
130
+ /// #[pin]
131
+ /// a: Mutex<usize>,
125
132
/// b: Bar,
126
133
/// }
127
134
///
@@ -130,7 +137,7 @@ mod pin_project;
130
137
/// x: u32,
131
138
/// }
132
139
///
133
- /// let a = 42 ;
140
+ /// let a = new_mutex!(42, "Foo::a") ;
134
141
///
135
142
/// stack_init!(let foo = pin_init!(Foo {
136
143
/// a,
@@ -514,18 +521,29 @@ macro_rules! init {
514
521
} }
515
522
}
516
523
517
- //include!("init/pin_project.rs");
518
-
519
- /// An initializer for `T`.
524
+ /// A pinned initializer for `T`.
525
+ ///
526
+ /// To use this initializer, you will need a suitable memory location that can hold a `T`. This can
527
+ /// be [`Box<T>`], [`Arc<T>`], [`UniqueArc<T>`], or even the stack (see [`stack_init!`]). Use the
528
+ /// `pin_init` function of a smart pointer like [`Arc::pin_init`] on this.
529
+ ///
530
+ /// Also see the [module description](self).
520
531
///
521
532
/// # Safety
522
533
///
534
+ /// When implementing this type you will need to take great care. Also there are probably very few
535
+ /// cases where a manual implementation is necessary. Use [`from_value`] and
536
+ /// [`pin_init_from_closure`] where possible.
537
+ ///
523
538
/// The [`PinInit::__pinned_init`] function
524
539
/// - returns `Ok(())` iff it initialized every field of slot,
525
540
/// - returns `Err(err)` iff it encountered an error and then cleaned slot, this means:
526
541
/// - slot can be deallocated without UB ocurring,
527
542
/// - slot does not need to be dropped,
528
543
/// - slot is not partially initialized.
544
+ ///
545
+ /// [`Arc<T>`]: crate::sync::Arc
546
+ /// [`Arc::pin_init`]: crate::sync::Arc::pin_init
529
547
#[ must_use = "An initializer must be used in order to create its value." ]
530
548
pub unsafe trait PinInit < T , E = Infallible > : Sized {
531
549
/// Initializes `slot`.
@@ -541,8 +559,19 @@ pub unsafe trait PinInit<T, E = Infallible>: Sized {
541
559
542
560
/// An initializer for `T`.
543
561
///
562
+ /// To use this initializer, you will need a suitable memory location that can hold a `T`. This can
563
+ /// be [`Box<T>`], [`Arc<T>`], [`UniqueArc<T>`], or even the stack (see [`stack_init!`]). Use the
564
+ /// `init` function of a smart pointer like [`Box::init`] on this. Because [`PinInit<T, E>`] is a
565
+ /// super trait, you can use every function that takes it as well.
566
+ ///
567
+ /// Also see the [module description](self).
568
+ ///
544
569
/// # Safety
545
570
///
571
+ /// When implementing this type you will need to take great care. Also there are probably very few
572
+ /// cases where a manual implementation is necessary. Use [`from_value`] and
573
+ /// [`init_from_closure`] where possible.
574
+ ///
546
575
/// The [`Init::__init`] function
547
576
/// - returns `Ok(())` iff it initialized every field of slot,
548
577
/// - returns `Err(err)` iff it encountered an error and then cleaned slot, this means:
@@ -555,6 +584,8 @@ pub unsafe trait PinInit<T, E = Infallible>: Sized {
555
584
///
556
585
/// Contrary to its supertype [`PinInit<T, E>`] the caller is allowed to
557
586
/// move the pointee after initialization.
587
+ ///
588
+ /// [`Arc<T>`]: crate::sync::Arc
558
589
#[ must_use = "An initializer must be used in order to create its value." ]
559
590
pub unsafe trait Init < T , E = Infallible > : PinInit < T , E > {
560
591
/// Initializes `slot`.
@@ -571,7 +602,25 @@ type Invariant<T> = PhantomData<fn(T) -> T>;
571
602
572
603
struct InitClosure < F , T , E > ( F , Invariant < ( T , E ) > ) ;
573
604
574
- /// Creates a new Init from the given closure
605
+ unsafe impl < T , F , E > PinInit < T , E > for InitClosure < F , T , E >
606
+ where
607
+ F : FnOnce ( * mut T ) -> Result < ( ) , E > ,
608
+ {
609
+ unsafe fn __pinned_init ( self , slot : * mut T ) -> Result < ( ) , E > {
610
+ ( self . 0 ) ( slot)
611
+ }
612
+ }
613
+
614
+ unsafe impl < T , F , E > Init < T , E > for InitClosure < F , T , E >
615
+ where
616
+ F : FnOnce ( * mut T ) -> Result < ( ) , E > ,
617
+ {
618
+ unsafe fn __init ( self , slot : * mut T ) -> Result < ( ) , E > {
619
+ ( self . 0 ) ( slot)
620
+ }
621
+ }
622
+
623
+ /// Creates a new [`Init<T, E>`] from the given closure.
575
624
///
576
625
/// # Safety
577
626
///
@@ -587,7 +636,7 @@ pub const unsafe fn init_from_closure<T, E>(
587
636
) -> impl Init < T , E > {
588
637
InitClosure ( f, PhantomData )
589
638
}
590
- /// Creates a new PinInit from the given closure
639
+ /// Creates a new [` PinInit<T, E>`] from the given closure.
591
640
///
592
641
/// # Safety
593
642
///
@@ -604,24 +653,6 @@ pub const unsafe fn pin_init_from_closure<T, E>(
604
653
InitClosure ( f, PhantomData )
605
654
}
606
655
607
- unsafe impl < T , F , E > PinInit < T , E > for InitClosure < F , T , E >
608
- where
609
- F : FnOnce ( * mut T ) -> Result < ( ) , E > ,
610
- {
611
- unsafe fn __pinned_init ( self , slot : * mut T ) -> Result < ( ) , E > {
612
- ( self . 0 ) ( slot)
613
- }
614
- }
615
-
616
- unsafe impl < T , F , E > Init < T , E > for InitClosure < F , T , E >
617
- where
618
- F : FnOnce ( * mut T ) -> Result < ( ) , E > ,
619
- {
620
- unsafe fn __init ( self , slot : * mut T ) -> Result < ( ) , E > {
621
- ( self . 0 ) ( slot)
622
- }
623
- }
624
-
625
656
/// Trait facilitating pinned destruction.
626
657
///
627
658
/// Use [`pinned_drop`] to implement this trait safely:
@@ -648,10 +679,14 @@ where
648
679
///
649
680
/// [`pinned_drop`]: kernel::macros::pinned_drop
650
681
pub unsafe trait PinnedDrop {
682
+ /// Executes the pinned destructor of this type.
683
+ ///
651
684
/// # Safety
652
685
///
653
686
/// Only call this from `<Self as Drop>::drop`.
654
687
unsafe fn drop ( self : Pin < & mut Self > ) ;
688
+
689
+ // used by `pinned_drop` to ensure that only safe operations are used in `drop`.
655
690
#[ doc( hidden) ]
656
691
fn __ensure_no_unsafe_op_in_drop ( self : Pin < & mut Self > ) ;
657
692
}
@@ -734,8 +769,12 @@ impl<T> InPlaceInit<T> for UniqueArc<T> {
734
769
/// The bit pattern consisting of only zeroes must be a valid bit pattern for the type.
735
770
pub unsafe trait Zeroable { }
736
771
737
- /// Create a new zeroed T
772
+ /// Create a new zeroed T.
773
+ ///
774
+ /// The returned initializer will write `0x00` to every byte of the given slot.
738
775
pub fn zeroed < T : Zeroable + Unpin > ( ) -> impl Init < T > {
776
+ // SAFETY: because `T: Zeroable`, all bytes zero is a valid bit pattern for `T`
777
+ // and because we write all zeroes, the memory is initialized.
739
778
unsafe {
740
779
init_from_closure ( |slot : * mut T | {
741
780
slot. write_bytes ( 0 , 1 ) ;
@@ -745,12 +784,18 @@ pub fn zeroed<T: Zeroable + Unpin>() -> impl Init<T> {
745
784
}
746
785
747
786
/// An initializer that leaves the memory uninitialized.
787
+ ///
788
+ /// The initializer is a no-op. The slot memory is not changed.
748
789
pub fn uninit < T > ( ) -> impl Init < MaybeUninit < T > > {
790
+ // SAFETY: The memory is allowed to be uninitialized.
749
791
unsafe { init_from_closure ( |_| Ok ( ( ) ) ) }
750
792
}
751
793
752
- /// Convert a value into an initializer
794
+ /// Convert a value into an initializer.
795
+ ///
796
+ /// Directly moves the value into the given slot.
753
797
pub fn from_value < T > ( value : T ) -> impl Init < T > {
798
+ // SAFETY: we use the value to initialize the slot.
754
799
unsafe {
755
800
init_from_closure ( move |slot : * mut T | {
756
801
slot. write ( value) ;
0 commit comments