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

Alice Ryhl
2025-11-14T09:48:48Z

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.

Alice