On Sat, Mar 23, 2024 at 07:41:28AM -0700, Boqun Feng wrote: > On Sat, Mar 23, 2024 at 03:29:11PM +0100, Andrew Lunn wrote: > > > There are also issues like where one Rust thread does a store(.., > > > RELEASE), and a C thread does a rcu_deference(), in practice, it > > > probably works but no one works out (and no one would work out) a model > > > to describe such an interaction. > > > > Isn't that what Paul E. McKenney litmus tests are all about? > > > > Litmus tests (or herd, or any other memory model tools) works for either > LKMM or C++ memory model. But there is no model I'm aware of works for > the communication between two memory models. So for example: > > Rust thread: > > let mut foo: Box<Foo> = ...; > foo.a = 1; > let global_ptr: &AtomicPtr = ...; > global_ptr.store(foo.leak() as _, RELEASE); > > > C thread: > > rcu_read_lock(); > > foo = rcu_dereference(global_ptr); > if (foo) { > r1 = foo->a; > } > > rcu_read_unlock(); > > no tool or model yet to guarantee "r1" is 1, but yeah, in practice for > the case we care, it's probably guaranteed. But no tool or model means > challenging for code reasoning. > There are also cases where two similar APIs from C++ memory model and LKMM have different semantics, for example, a SeqCst atomic in C++ memory model doesn't imply a full barrier, while a fully ordered LKMM atomic does: Rust: a.store(1, RELAXED); x.fetch_add(1, SeqCst); b.store(2, RELAXED); // ^ writes to a and b are not ordered. C: WRITE_ONCE(*a, 1); atomic_fetch_add(x, 1); WRITE_ONCE(*b, 2); // ^ writes to a and b are ordered. So if you used to have two parts synchronizing each other with LKMM atomics, converting one side to Rust *and* using Rust atomics requires much caution. Regards, Boqun > Regards, > Boqun > > > tools/memory-model/litmus-test > > > > Andrew