On Mon, May 19, 2025 at 6:24 PM Burak Emir <b...@google.com> wrote: > + /// Set bit with index `index`, atomically. > + /// > + /// ATTENTION: The naming convention differs from C, where the > corresponding > + /// function is called `set_bit`. > + /// > + /// # Safety > + /// > + /// This is a relaxed atomic operation (no implied memory barriers, no > + /// ordering guarantees). The caller must ensure that this is safe, as > + /// the compiler cannot prevent code with an exclusive reference from > + /// calling atomic operations.
How can atomic operations through an exclusive reference be unsafe? You can't have a data race between two atomic operations, and an exclusive reference should anyway prevent any concurrency, right? > + /// > + /// # Panics > + /// > + /// Panics if `index` is greater than or equal to `self.nbits`. > + #[inline] > + pub unsafe fn set_bit_atomic(&self, index: usize) { > + assert!( > + index < self.nbits, > + "Bit `index` must be < {}, was {}", > + self.nbits, > + index > + ); > + // SAFETY: `index` is within bounds and the caller has ensured that > + // there is no mix of non-atomic and atomic operations. Aren't non-atomic operations only possible through a mutable reference? And doesn't the rust compiler enforce that, if someone holds a mutable reference, nobody else can hold any reference at all? You wrote yourself above: "all (non-atomic) mutating operations require a &mut reference which amounts to exclusive access." I don't understand what's going on here, unless you're saying that Rust does not enforce that an object ownership transfer between threads has proper RELEASE/ACQUIRE (or RELEASE/CONSUME) memory ordering or something like that? > + unsafe { bindings::set_bit(index as u32, self.as_ptr() as *mut > usize) }; > + }