Skip to content

Commit 31547c9

Browse files
y86-devojeda
authored andcommitted
rust: pin-init: remove kernel-crate dependency
In order to make pin-init a standalone crate, remove dependencies on kernel-specific code such as `ScopeGuard` and `KBox`. `ScopeGuard` is only used in the `[pin_]init_array_from_fn` functions and can easily be replaced by a primitive construct. `KBox` is only used for type variance of unsized types and can also easily be replaced. Signed-off-by: Benno Lossin <[email protected]> Reviewed-by: Fiona Behrens <[email protected]> Reviewed-by: Andreas Hindborg <[email protected]> Tested-by: Andreas Hindborg <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Miguel Ojeda <[email protected]>
1 parent 129e97b commit 31547c9

File tree

2 files changed

+18
-28
lines changed

2 files changed

+18
-28
lines changed

rust/pin-init/src/__internal.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ use super::*;
1111

1212
/// See the [nomicon] for what subtyping is. See also [this table].
1313
///
14+
/// The reason for not using `PhantomData<*mut T>` is that that type never implements [`Send`] and
15+
/// [`Sync`]. Hence `fn(*mut T) -> *mut T` is used, as that type always implements them.
16+
///
1417
/// [nomicon]: https://doc.rust-lang.org/nomicon/subtyping.html
1518
/// [this table]: https://doc.rust-lang.org/nomicon/phantom-data.html#table-of-phantomdata-patterns
1619
pub(super) type Invariant<T> = PhantomData<fn(*mut T) -> *mut T>;
@@ -105,7 +108,7 @@ pub unsafe trait InitData: Copy {
105108
}
106109
}
107110

108-
pub struct AllData<T: ?Sized>(PhantomData<fn(KBox<T>) -> KBox<T>>);
111+
pub struct AllData<T: ?Sized>(Invariant<T>);
109112

110113
impl<T: ?Sized> Clone for AllData<T> {
111114
fn clone(&self) -> Self {

rust/pin-init/src/lib.rs

+14-27
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,6 @@
212212
//! [`pin_data`]: ::macros::pin_data
213213
//! [`pin_init!`]: crate::pin_init!
214214
215-
use crate::{alloc::KBox, types::ScopeGuard};
216215
use core::{
217216
cell::UnsafeCell,
218217
convert::Infallible,
@@ -944,7 +943,7 @@ pub unsafe trait PinInit<T: ?Sized, E = Infallible>: Sized {
944943
}
945944

946945
/// An initializer returned by [`PinInit::pin_chain`].
947-
pub struct ChainPinInit<I, F, T: ?Sized, E>(I, F, __internal::Invariant<(E, KBox<T>)>);
946+
pub struct ChainPinInit<I, F, T: ?Sized, E>(I, F, __internal::Invariant<(E, T)>);
948947

949948
// SAFETY: The `__pinned_init` function is implemented such that it
950949
// - returns `Ok(())` on successful initialization,
@@ -1043,7 +1042,7 @@ pub unsafe trait Init<T: ?Sized, E = Infallible>: PinInit<T, E> {
10431042
}
10441043

10451044
/// An initializer returned by [`Init::chain`].
1046-
pub struct ChainInit<I, F, T: ?Sized, E>(I, F, __internal::Invariant<(E, KBox<T>)>);
1045+
pub struct ChainInit<I, F, T: ?Sized, E>(I, F, __internal::Invariant<(E, T)>);
10471046

10481047
// SAFETY: The `__init` function is implemented such that it
10491048
// - returns `Ok(())` on successful initialization,
@@ -1140,25 +1139,19 @@ where
11401139
{
11411140
let init = move |slot: *mut [T; N]| {
11421141
let slot = slot.cast::<T>();
1143-
// Counts the number of initialized elements and when dropped drops that many elements from
1144-
// `slot`.
1145-
let mut init_count = ScopeGuard::new_with_data(0, |i| {
1146-
// We now free every element that has been initialized before.
1147-
// SAFETY: The loop initialized exactly the values from 0..i and since we
1148-
// return `Err` below, the caller will consider the memory at `slot` as
1149-
// uninitialized.
1150-
unsafe { ptr::drop_in_place(ptr::slice_from_raw_parts_mut(slot, i)) };
1151-
});
11521142
for i in 0..N {
11531143
let init = make_init(i);
11541144
// SAFETY: Since 0 <= `i` < N, it is still in bounds of `[T; N]`.
11551145
let ptr = unsafe { slot.add(i) };
11561146
// SAFETY: The pointer is derived from `slot` and thus satisfies the `__init`
11571147
// requirements.
1158-
unsafe { init.__init(ptr) }?;
1159-
*init_count += 1;
1148+
if let Err(e) = unsafe { init.__init(ptr) } {
1149+
// SAFETY: The loop has initialized the elements `slot[0..i]` and since we return
1150+
// `Err` below, `slot` will be considered uninitialized memory.
1151+
unsafe { ptr::drop_in_place(ptr::slice_from_raw_parts_mut(slot, i)) };
1152+
return Err(e);
1153+
}
11601154
}
1161-
init_count.dismiss();
11621155
Ok(())
11631156
};
11641157
// SAFETY: The initializer above initializes every element of the array. On failure it drops
@@ -1189,25 +1182,19 @@ where
11891182
{
11901183
let init = move |slot: *mut [T; N]| {
11911184
let slot = slot.cast::<T>();
1192-
// Counts the number of initialized elements and when dropped drops that many elements from
1193-
// `slot`.
1194-
let mut init_count = ScopeGuard::new_with_data(0, |i| {
1195-
// We now free every element that has been initialized before.
1196-
// SAFETY: The loop initialized exactly the values from 0..i and since we
1197-
// return `Err` below, the caller will consider the memory at `slot` as
1198-
// uninitialized.
1199-
unsafe { ptr::drop_in_place(ptr::slice_from_raw_parts_mut(slot, i)) };
1200-
});
12011185
for i in 0..N {
12021186
let init = make_init(i);
12031187
// SAFETY: Since 0 <= `i` < N, it is still in bounds of `[T; N]`.
12041188
let ptr = unsafe { slot.add(i) };
12051189
// SAFETY: The pointer is derived from `slot` and thus satisfies the `__init`
12061190
// requirements.
1207-
unsafe { init.__pinned_init(ptr) }?;
1208-
*init_count += 1;
1191+
if let Err(e) = unsafe { init.__pinned_init(ptr) } {
1192+
// SAFETY: The loop has initialized the elements `slot[0..i]` and since we return
1193+
// `Err` below, `slot` will be considered uninitialized memory.
1194+
unsafe { ptr::drop_in_place(ptr::slice_from_raw_parts_mut(slot, i)) };
1195+
return Err(e);
1196+
}
12091197
}
1210-
init_count.dismiss();
12111198
Ok(())
12121199
};
12131200
// SAFETY: The initializer above initializes every element of the array. On failure it drops

0 commit comments

Comments
 (0)