Comment
Author: Admin | 2025-04-28
Current = location1; while (true) { int newValue = current & value; int oldValue = CompareExchange(ref location1, newValue, current); if (oldValue == current) { return oldValue; } current = oldValue; }}You’ll see a very similar loop any time you want to use optimistic concurrency to create a new value and substitute it for the original in an atomic manner. The actual & operation is just one line here, and to highlight that this is broadly applicable, you could create a generalized version of this method for any operation using a delegate, like this:public static int CompareExchange(ref int location1, int value, Func update){ int current = location1; while (true) { int newValue = update(current, value); int oldValue = CompareExchange(ref location1, newValue, current); if (oldValue == current) { return oldValue; } current = oldValue; }}such that And could be implemented then like:public static int And(ref int location1, int value) => CompareExchange(ref location1, value, static (current, value) => current & value)The approach employed by And is reasonable when there’s nothing better you can do, but as it turns out, modern hardware platforms have single instructions capable of performing such an interlocked and and or in a much more efficient manner. The JIT already handled this for Arm because the instructions on Arm have semantics that very closely align with the semantics of Interlocked.And and Interlocked.Or. On x86/64, however, the relevant instruction sequence (lock and or lock or) doesn’t enable accessing the original value atomically replaced, whereas And/Or require that as part of their
Add Comment