DotNext by .NET Foundation and Contributors

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

 AtomicUInt64

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