From: Gary Guo <gary@garyguo.net>
To: FUJITA Tomonori <fujita.tomonori@gmail.com>
Cc: alex.gaynor@gmail.com, ojeda@kernel.org, a.hindborg@kernel.org,
aliceryhl@google.com, boqun.feng@gmail.com,
bjorn3_gh@protonmail.com, dakr@kernel.org, lossin@kernel.org,
rust-for-linux@vger.kernel.org, tmgross@umich.edu
Subject: Re: [PATCH v3 1/2] rust: Add support for calling a function exactly once
Date: Tue, 23 Dec 2025 12:18:14 +0000 [thread overview]
Message-ID: <20251223121814.0b00f725.gary@garyguo.net> (raw)
In-Reply-To: <20251117002452.4068692-2-fujita.tomonori@gmail.com>
On Mon, 17 Nov 2025 09:24:51 +0900
FUJITA Tomonori <fujita.tomonori@gmail.com> wrote:
> Add the Rust equivalent of the kernel's `DO_ONCE_LITE` macro. While it
> would be possible to implement the feature entirely as a Rust macro,
> the functionality that can be implemented as regular functions has
> been extracted and implemented as the `OnceLite` struct for better
> code maintainability.
>
> Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
> ---
> rust/kernel/print.rs | 83 ++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 83 insertions(+)
>
> diff --git a/rust/kernel/print.rs b/rust/kernel/print.rs
> index 2d743d78d220..af32054be5a2 100644
> --- a/rust/kernel/print.rs
> +++ b/rust/kernel/print.rs
> @@ -11,6 +11,11 @@
> fmt,
> prelude::*,
> str::RawFormatter,
> + sync::atomic::{
> + Atomic,
> + AtomicType,
> + Relaxed, //
> + },
> };
>
> // Called from `vsprintf` with format specifier `%pA`.
> @@ -423,3 +428,81 @@ macro_rules! pr_cont (
> $crate::print_macro!($crate::print::format_strings::CONT, true, $($arg)*)
> )
> );
> +
> +/// A lightweight `call_once` primitive.
> +///
> +/// This structure provides the Rust equivalent of the kernel's `DO_ONCE_LITE` macro.
> +/// While it would be possible to implement the feature entirely as a Rust macro,
> +/// the functionality that can be implemented as regular functions has been
> +/// extracted and implemented as the `OnceLite` struct for better code maintainability.
> +pub struct OnceLite(Atomic<State>);
> +
> +#[derive(Clone, Copy, PartialEq, Eq)]
> +#[repr(i32)]
> +enum State {
> + Incomplete = 0,
> + Complete = 1,
> +}
> +
> +// SAFETY: `State` and `i32` has the same size and alignment, and it's round-trip
> +// transmutable to `i32`.
> +unsafe impl AtomicType for State {
> + type Repr = i32;
> +}
> +
> +impl OnceLite {
> + /// Creates a new [`OnceLite`] in the incomplete state.
> + #[inline(always)]
> + #[allow(clippy::new_without_default)]
Maybe put the reason too? Otherwise a reader who hasn't been following
previous discussions closely might be out of context (like me).
> + pub const fn new() -> Self {
> + OnceLite(Atomic::new(State::Incomplete))
> + }
> +
> + /// Calls the provided function exactly once.
> + ///
> + /// There is no other synchronization between two `call_once()`s
> + /// except that only one will execute `f`, in other words, callers
> + /// should not use a failed `call_once()` as a proof that another
> + /// `call_once()` has already finished and the effect is observable
> + /// to this thread.
Nice! Thanks for putting this in. If this this insn't in this will
definitely be misused (I won't be surprised that it'll be misused anyway
even with this, though)
Reviewed-by: Gary Guo <gary@garyguo.net>
Best,
Gary
> + pub fn call_once<F>(&self, f: F) -> bool
> + where
> + F: FnOnce(),
> + {
> + // Avoid expensive cmpxchg if already completed.
> + // ORDERING: `Relaxed` is used here since no synchronization is required.
> + let old = self.0.load(Relaxed);
> + if old == State::Complete {
> + return false;
> + }
> +
> + // ORDERING: `Relaxed` is used here since no synchronization is required.
> + let old = self.0.xchg(State::Complete, Relaxed);
> + if old == State::Complete {
> + return false;
> + }
> +
> + f();
> + true
> + }
> +}
next prev parent reply other threads:[~2025-12-23 12:18 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-17 0:24 [PATCH v3 0/2] Add support for print exactly once FUJITA Tomonori
2025-11-17 0:24 ` [PATCH v3 1/2] rust: Add support for calling a function " FUJITA Tomonori
2025-12-18 11:38 ` Alice Ryhl
2025-12-23 6:49 ` FUJITA Tomonori
2025-12-23 12:18 ` Gary Guo [this message]
2025-12-25 6:14 ` FUJITA Tomonori
2025-11-17 0:24 ` [PATCH v3 2/2] rust: Add pr_*_once macros FUJITA Tomonori
2025-12-23 12:06 ` Gary Guo
2025-12-25 6:29 ` FUJITA Tomonori
2026-01-13 6:52 ` FUJITA Tomonori
2025-12-18 11:18 ` [PATCH v3 0/2] Add support for print exactly once FUJITA Tomonori
2026-01-30 4:51 ` Miguel Ojeda
2026-01-30 12:34 ` FUJITA Tomonori
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251223121814.0b00f725.gary@garyguo.net \
--to=gary@garyguo.net \
--cc=a.hindborg@kernel.org \
--cc=alex.gaynor@gmail.com \
--cc=aliceryhl@google.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=dakr@kernel.org \
--cc=fujita.tomonori@gmail.com \
--cc=lossin@kernel.org \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=tmgross@umich.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.