DotNext by .NET Foundation and Contributors

<PackageReference Include="DotNext" Version="4.1.1" />

 AtomicInt64

public static class AtomicInt64
Various atomic operations for Int64 data type accessible as extension methods.
using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; namespace DotNext.Threading { public static class AtomicInt64 { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long VolatileRead([In] [IsReadOnly] ref long value) { return Volatile.Read(ref Unsafe.AsRef(ref value)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void VolatileWrite(ref long value, long newValue) { Volatile.Write(ref value, newValue); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long IncrementAndGet(ref long value) { return Interlocked.Increment(ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long DecrementAndGet(ref long value) { return Interlocked.Decrement(ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool CompareAndSet(ref long value, long expected, long update) { return Interlocked.CompareExchange(ref value, update, expected) == expected; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long AddAndGet(ref long value, long operand) { return Interlocked.Add(ref value, operand); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long GetAndAdd(ref long value, long operand) { return Accumulate(ref value, operand, default(Adder)).OldValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long GetAndBitwiseAnd(ref long value, long operand) { return Interlocked.And(ref value, operand); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long BitwiseAndAndGet(ref long value, long operand) { return Interlocked.And(ref value, operand) & operand; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long GetAndBitwiseOr(ref long value, long operand) { return Interlocked.Or(ref value, operand); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long BitwiseOrAndGet(ref long value, long operand) { return Interlocked.Or(ref value, operand) | operand; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long GetAndBitwiseXor(ref long value, long operand) { return Accumulate(ref value, operand, default(BitwiseXor)).OldValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long BitwiseXorAndGet(ref long value, long operand) { return Accumulate(ref value, operand, default(BitwiseXor)).NewValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long GetAndSet(ref long value, long update) { return Interlocked.Exchange(ref value, update); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long SetAndGet(ref long value, long update) { ref value.VolatileWrite(update); return update; } [MethodImpl(MethodImplOptions.AggressiveOptimization)] private static (long OldValue, long NewValue) Update<TUpdater>(ref long value, TUpdater updater) where TUpdater : struct, ISupplier<long, long> { long num2; long num; do { num2 = ((ISupplier<long, long>)updater).Invoke(num = ref value.VolatileRead()); } while (!ref value.CompareAndSet(num, num2)); return (num, num2); } [MethodImpl(MethodImplOptions.AggressiveOptimization)] private static (long OldValue, long NewValue) Accumulate<TAccumulator>(ref long value, long x, TAccumulator accumulator) where TAccumulator : struct, ISupplier<long, long, long> { long num2; long num; do { num2 = ((ISupplier<long, long, long>)accumulator).Invoke(num = ref value.VolatileRead(), x); } while (!ref value.CompareAndSet(num, num2)); return (num, num2); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.CompilerServices.NullableContext(1)] public static long AccumulateAndGet(ref long value, long x, Func<long, long, long> accumulator) { return Accumulate(ref value, x, (DelegatingSupplier<long, long, long>)accumulator).NewValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static long AccumulateAndGet(ref long value, long x, IntPtr accumulator) { return Accumulate(ref value, x, (Supplier<long, long, long>)(long)accumulator).NewValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.CompilerServices.NullableContext(1)] public static long GetAndAccumulate(ref long value, long x, Func<long, long, long> accumulator) { return Accumulate(ref value, x, (DelegatingSupplier<long, long, long>)accumulator).OldValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static long GetAndAccumulate(ref long value, long x, IntPtr accumulator) { return Accumulate(ref value, x, (Supplier<long, long, long>)(long)accumulator).OldValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.CompilerServices.NullableContext(1)] public static long UpdateAndGet(ref long value, Func<long, long> updater) { return Update(ref value, (DelegatingSupplier<long, long>)updater).NewValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static long UpdateAndGet(ref long value, IntPtr updater) { return Update(ref value, (Supplier<long, long>)(long)updater).NewValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.CompilerServices.NullableContext(1)] public static long GetAndUpdate(ref long value, Func<long, long> updater) { return Update(ref value, (DelegatingSupplier<long, long>)updater).OldValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public static long GetAndUpdate(ref long value, IntPtr updater) { return Update(ref value, (Supplier<long, long>)(long)updater).OldValue; } } }