Earlier quoted context omitted.
> I suspect that if Rust continues forward with this approach it will basically end up as the code where someone goes to read the actual semantics to determine what the C code should do. That will also put it on the unfortunate position of being the place that breaks every time somebody adds a bug to the C code. Anyway, given the cultures involved, it's probably inevitable.
> That will also put it on the unfortunate position of being the place that breaks every time somebody adds a bug to the C code. Can someone explain charitably what the poster is getting at? To me, the above makes zero sense. If the Rust code is what is implemented correctly, and has the well-defined semantics, then, when the C code breaks, it's obviously the C code's problem?
Read_once(), Write_once(), but Not for Rust
31–40 of 41 posts
Re: Read_once(), Write_once(), but Not for Rust
#32Earlier quoted context omitted.
It wasn’t implemented for the same reason. Rust uses C++20 ordering.
C++20 actually [changed the semantics of consume]( https://devblogs.microsoft.com/oldnewthing/20230427-00/?p=10... ), but Rust doesn't include it. And last I remember compilers still treat it as acquire, so it's not worth the bytes it's stored in.
Re: Read_once(), Write_once(), but Not for Rust
#33Earlier quoted context omitted.
It is cheaper on ARM and POWER. But I'm not sure it is always safe. The standard has very complex rules for consume to make sure that the compiler didn't break the dependencies. edit: and those rules where so complex that compilers decided where not implementable or not worth it.
The rules were there to explain what optimizations remained possible. Here no optimization is possible at the compiler level, and only the processor retains freedom because we know it won't use it. It is nasty, but it's very similar to how Linux does it (volatile read + __asm__("") compiler barrier).
I guess in practice mainstream compilers do not do it and relaxed+signal fence works for now, but the fact that compilers have been reluctant to use it to implement consume means that they are reluctant to commit to it.
In any case I think you work on GCC, so you probably know the details better than me.
edit: it seems that ARM specifically does not respect control dependencies. But I might misreading the MM.
Re: Read_once(), Write_once(), but Not for Rust
#34Earlier quoted context omitted.
consume is trivial on alpha, it is the same as acquire (always needs a #LoadLoad). It is also the same as acquire (and relaxed) on x86 and SPARC (a plain load, #LoadLoad is always implied). The only place where consume matters is on relaxed but not too relaxed architectures like ARM and POWER, where consume relies on the implicit #LoadLoad of controls and data dependencies.
Also on alpha there's only store-store and full memory barriers. Acquire is very expensive.
Re: Read_once(), Write_once(), but Not for Rust
#35Re: Read_once(), Write_once(), but Not for Rust
#36[1]: https://www.alilleybrinker.com/mini/rusts-culture-of-semanti...
Re: Read_once(), Write_once(), but Not for Rust
#37Earlier quoted context omitted.
> That will also put it on the unfortunate position of being the place that breaks every time somebody adds a bug to the C code. Can someone explain charitably what the poster is getting at? To me, the above makes zero sense. If the Rust code is what is implemented correctly, and has the well-defined semantics, then, when the C code breaks, it's obviously the C code's problem?
I think a charitable interpretation is that given that the Rust code will be less forgiving, it will "break" C code and patterns that "used to work", albeit with latent UB or other nonobvious correctness issues. Now, obviously this is ultimately a good thing, and no developer worth their salt would seriously argue that latent bugs should stay latent, but as we've already seen, people have egos and aren't always excee…
It's not exactly that the Rust implementation will be less forgiving. But developers will have a clear picture of the operations semantics, while C developers will have a harder time understanding the operations, and consequently avoid them.
Re: Read_once(), Write_once(), but Not for Rust
#38Earlier quoted context omitted.
right, so I would expect that the equivalent of READ_ONCE is converted to an acquire in rust, even if slightly pessimal. But the article says that the suggestion is to convert them to relaxed loads. Is the expectation to YOLO it and hope that the compiler doesn't break control and data dependencies?
There is a yolo way that actually works, which would be to change it to a relaxed load followed by an acquire signal fence.
Re: Read_once(), Write_once(), but Not for Rust
#39Re: Read_once(), Write_once(), but Not for Rust
#40> There are a couple of interesting implications from this outcome, should it hold. The first of those is that, as Rust code reaches more deeply into the core kernel, its code for concurrent access to shared data will look significantly different from the equivalent C code, even though the code on both sides may be working with the same data. Understanding lockless data access is challenging enough when dealing with…
In my experience, in practice, it usually isn't that hard to figure out what people meant by a READ/WRITE_ONCE(). Most common cases I see are: 1. I'm sharing data between concurrent contexts but they are all on the same CPU (classic is sharing a percpu variable between IRQ and task). 2. I'm reading some isolated piece of data that I know can change any time, but it doesn't form part of a data structure or anything, i…