4 ms·
I don’t work with Java atomics, but I really don’t like the OP’s implementation. The loadLoadFence just looks pointless and inefficient (and wrong?). Acquire s
by amluto 3y ago
I don’t work with Java atomics, but I really don’t like the OP’s implementation.
The loadLoadFence just looks pointless and inefficient (and wrong?). Acquire should be sufficient, and reasonable architectures (Aarch64 and x86 at least) have cheap acquires. But most (?) memory models don’t have any ordering between a relaxed load and a subsequent acquire, so read is simply incorrect. On x86, the right answer is to do all the loads, including the data, as acquires. On aarch64, for very large data, it’s plausibly faster to use relaxed loads and a fence, or maybe the memory model is stronger than I think it is. But the code as written appears unsafe in general.
The write function is IMO terrible. Don’t roll your own crappy spinlock! Either just declare as a precondition that there is only one writer or use an actual mutex in the library. Modern mutexes are much, much more efficient than the nasty algorithm in the OP, and saving a single word of memory by combining the sequence and the mutex is simply not worthwhile.
- bonzini 3y agoIndeed the load/load fence must be before the "final long currentVersion" load—which in turn can be a relaxed load—not after the first load. On x86 this produces optimal code because the load/load fence does not need to be compiled into a processor instruction (LFENCE and SFENCE exist but are only used in very special cases; they aren't needed for normal memory and normal load instructions).