Re: [PATCH v1 0/2] Add support for print exactly once

FUJITA Tomonori
2025-11-14T13:55:34Z

On Fri, 14 Nov 2025 09:48:46 +0000
Alice Ryhl <aliceryhl@google.com> wrote:

> On Thu, Nov 13, 2025 at 05:19:10PM -0800, Boqun Feng wrote:
>> On Fri, Nov 14, 2025 at 10:12:08AM +0900, FUJITA Tomonori wrote:
>> > On Thu, 13 Nov 2025 16:57:18 -0800
>> > Boqun Feng <boqun.feng@gmail.com> wrote:
>> >
>> > > On Fri, Nov 14, 2025 at 09:47:30AM +0900, FUJITA Tomonori wrote:
>> > > [...]
>> > >> >> Using u8 as atomic type instead of i32 would require a fair amount of
>> > >> >> work, since at the moment only i32 and i64 are supported as atomic
>> > >> >> types, right?
>> > >> >
>> > >> > Supporting u8 atomics in general is tricky, but I think *specifically*
>> > >> > load/store should not be a problem.
>> > >>
>> > >> You meant using read_volatile/write_volatile? Since we only need
>> > >> "Relaxed" order so something like the following?
>> > >>
>> > >> #[repr(transparent)]
>> > >> struct AtomicU8(UnsafeCell<u8>);
>> > >>
>> > >
>> > > Please don't. Please make it work with Atomic<T>, also store release and
>> > > load acquire should be introduced as well.
>> >
>> > I wanted to confirm what kind of u8 load/store implementation Alice
>> > has in mind, and whether it would be used only for OnceLite.
>> >
>> > Of course. If we add something like that to kernel/sync, I agree that
>> > it should be implemented in that way. If not, I'm not sure.
>> >
>>
>> Yeah, I'm afraid that you want to implement something only for OneLite,
>> and that'll introduce fragments for maintaining.
>>
>> For Atomic<T>, supporting load/store/xchg/cmpxchg is definitely the
>> plan, so appreciate if you could help while working on this pr_*_once().
>>
>> Alternatively, we can start with i32, and improve that later.
>
> I read over this discussion. Perhaps it's best that we go with i32 with
> xchg after all to avoid adding new atomic types for this feature.
>
> Still needs a load, though.
>
> /// Calls the provided function exactly once.
> pub fn call_once<F>(&self, f: F) -> bool
> where
> F: FnOnce(),
> {
> let old = self.0.load(Relaxed);
> if old == State::Complete {
> return false;
> }
>
> let old = self.0.xchg(State::Complete, Relaxed);
> if old == State::Complete {
> return false;
> }
>
> f();
> true
> }
>
> This ensures that we do not perform a write operation when we don't need
> to.

Yes, that makes sense. Let's proceed with this for now. Once support
for Atomic<u8> load/store is available, we can revisit it.