aboutsummaryrefslogtreecommitdiff
path: root/rust/kernel
diff options
context:
space:
mode:
authorAsahi Lina <[email protected]>2023-04-03 19:01:12 +0900
committerMiguel Ojeda <[email protected]>2023-04-12 18:41:04 +0200
commit31d95c2f99bf16e59b996cf6a227e198a64e835c (patch)
tree9e1cb837420c0bdab15e2fcdd2506c03031b44ef /rust/kernel
parent1edd03378e50ff1071004c80cb878e4bad73a68f (diff)
rust: sync: arc: Add UniqueArc<MaybeUninit<T>::assume_init()
We can already create `UniqueArc<MaybeUninit<T>>` instances with `UniqueArc::try_new_uninit()` and write to them with `write()`. Add the missing unsafe `assume_init()` function to promote it to `UniqueArc<T>`, so users can do piece-wise initialization of the contents instead of doing it all at once as long as they keep the invariants (the same requirements as `MaybeUninit::assume_init()`). This mirrors the std `Arc::assume_init()` function. In the kernel, since we have `UniqueArc`, arguably this only belongs there since most use cases will initialize it immediately after creating it, before demoting it to `Arc` to share it. [ Miguel: The "Rust pin-init API for pinned initialization of structs" patch series [1] from Benno Lossin contains a very similar patch: rust: sync: add `assume_init` to `UniqueArc` Adds the `assume_init` function to `UniqueArc<MaybeUninit<T>>` that unsafely assumes the value to be initialized and yields a value of type `UniqueArc<T>`. This function is used when manually initializing the pointee of an `UniqueArc`. To make that patch a noop and thus drop it, I adjusted the `SAFETY` comment here to be the same as in the current latest version of that series (v7). I have also brought the `Reviewed-by`s there into here, and reworded the `Co-authored-by` into `Co-developed-by`. ] Link: https://lore.kernel.org/r/[email protected] [1] Co-developed-by: Benno Lossin <[email protected]> Signed-off-by: Benno Lossin <[email protected]> Signed-off-by: Asahi Lina <[email protected]> Reviewed-by: Gary Guo <[email protected]> Reviewed-by: Wedson Almeida Filho <[email protected]> Reviewed-by: Andreas Hindborg <[email protected]> Reviewed-by: Alice Ryhl <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Miguel Ojeda <[email protected]>
Diffstat (limited to 'rust/kernel')
-rw-r--r--rust/kernel/sync/arc.rs11
1 files changed, 11 insertions, 0 deletions
diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs
index 4ab9b280cb3d..8ce6d6bf478e 100644
--- a/rust/kernel/sync/arc.rs
+++ b/rust/kernel/sync/arc.rs
@@ -492,6 +492,17 @@ impl<T> UniqueArc<MaybeUninit<T>> {
/// Converts a `UniqueArc<MaybeUninit<T>>` into a `UniqueArc<T>` by writing a value into it.
pub fn write(mut self, value: T) -> UniqueArc<T> {
self.deref_mut().write(value);
+ // SAFETY: We just wrote the value to be initialized.
+ unsafe { self.assume_init() }
+ }
+
+ /// Unsafely assume that `self` is initialized.
+ ///
+ /// # Safety
+ ///
+ /// The caller guarantees that the value behind this pointer has been initialized. It is
+ /// *immediate* UB to call this when the value is not initialized.
+ pub unsafe fn assume_init(self) -> UniqueArc<T> {
let inner = ManuallyDrop::new(self).inner.ptr;
UniqueArc {
// SAFETY: The new `Arc` is taking over `ptr` from `self.inner` (which won't be