Commit 28286620 authored by FUJITA Tomonori's avatar FUJITA Tomonori Committed by Peter Zijlstra
Browse files

rust: list: Use AtomicFlag in AtomicTracker



Make AtomicTracker use AtomicFlag instead of Atomic<bool> to avoid
slow byte-sized RMWs on architectures that don't support them.

Signed-off-by: default avatarFUJITA Tomonori <fujita.tomonori@gmail.com>
Signed-off-by: default avatarBoqun Feng <boqun@kernel.org>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: default avatarGary Guo <gary@garyguo.net>
Link: https://patch.msgid.link/20260129122622.3896144-3-tomo@aliasing.net
Link: https://patch.msgid.link/20260303201701.12204-10-boqun@kernel.org
parent ec6fc66a
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -6,7 +6,7 @@

use crate::alloc::{AllocError, Flags};
use crate::prelude::*;
use crate::sync::atomic::{ordering, Atomic};
use crate::sync::atomic::{ordering, AtomicFlag};
use crate::sync::{Arc, ArcBorrow, UniqueArc};
use core::marker::PhantomPinned;
use core::ops::Deref;
@@ -469,7 +469,7 @@ impl<T, U, const ID: u64> core::ops::DispatchFromDyn<ListArc<U, ID>> for ListArc
/// If the boolean is `false`, then there is no [`ListArc`] for this value.
#[repr(transparent)]
pub struct AtomicTracker<const ID: u64 = 0> {
    inner: Atomic<bool>,
    inner: AtomicFlag,
    // This value needs to be pinned to justify the INVARIANT: comment in `AtomicTracker::new`.
    _pin: PhantomPinned,
}
@@ -480,12 +480,12 @@ pub fn new() -> impl PinInit<Self> {
        // INVARIANT: Pin-init initializers can't be used on an existing `Arc`, so this value will
        // not be constructed in an `Arc` that already has a `ListArc`.
        Self {
            inner: Atomic::new(false),
            inner: AtomicFlag::new(false),
            _pin: PhantomPinned,
        }
    }

    fn project_inner(self: Pin<&mut Self>) -> &mut Atomic<bool> {
    fn project_inner(self: Pin<&mut Self>) -> &mut AtomicFlag {
        // SAFETY: The `inner` field is not structurally pinned, so we may obtain a mutable
        // reference to it even if we only have a pinned reference to `self`.
        unsafe { &mut Pin::into_inner_unchecked(self).inner }