DotNext by Roman Sakno

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

 AtomicDouble

public static class AtomicDouble
Various atomic operations for Double data type accessible as extension methods.
using DotNext.Generic; using System; using System.Runtime.CompilerServices; using System.Threading; namespace DotNext.Threading { public static class AtomicDouble { private sealed class CASProvider : Constant<CAS<double>> { public CASProvider() : base((CAS<double>)AtomicDouble.CompareAndSet) { } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double VolatileGet(ref double value) { return Volatile.Read(ref value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void VolatileSet(ref double value, double newValue) { Volatile.Write(ref value, newValue); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double IncrementAndGet(ref double value) { return ref value.UpdateAndGet((double x) => x + 1); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double DecrementAndGet(ref double value) { return ref value.UpdateAndGet((double x) => x - 1); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double Add(ref double value, double operand) { return ref value.AccumulateAndGet(operand, (double x, double y) => x + y); } public static bool CompareAndSet(ref double value, double expected, double update) { return ref Unsafe.As<double, long>(ref value).CompareAndSet(BitConverter.DoubleToInt64Bits(expected), BitConverter.DoubleToInt64Bits(update)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double GetAndSet(ref double value, double update) { return Interlocked.Exchange(ref value, update); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double SetAndGet(ref double value, double update) { ref value.VolatileSet(update); return update; } public static double AccumulateAndGet(ref double value, double x, Func<double, double, double> accumulator) { return Atomic<double, CASProvider>.Accumulute(ref value, x, accumulator).NewValue; } public static double GetAndAccumulate(ref double value, double x, Func<double, double, double> accumulator) { return Atomic<double, CASProvider>.Accumulute(ref value, x, accumulator).OldValue; } public static double UpdateAndGet(ref double value, Func<double, double> updater) { return Atomic<double, CASProvider>.Update(ref value, updater).NewValue; } public static double GetAndUpdate(ref double value, Func<double, double> updater) { return Atomic<double, CASProvider>.Update(ref value, updater).OldValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double VolatileGet(this double[] array, long index) { return ref array[index].VolatileGet(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void VolatileSet(this double[] array, long index, double value) { ref array[index].VolatileSet(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double IncrementAndGet(this double[] array, long index) { return ref array[index].IncrementAndGet(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double DecrementAndGet(this double[] array, long index) { return ref array[index].DecrementAndGet(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long CompareExchange(this long[] array, long index, long update, long comparand) { return Interlocked.CompareExchange(ref array[index], update, comparand); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool CompareAndSet(this double[] array, long index, double expected, double update) { return ref array[index].CompareAndSet(expected, update); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double Add(this double[] array, long index, double operand) { return ref array[index].Add(operand); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double GetAndSet(this double[] array, long index, double update) { return ref array[index].GetAndSet(update); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double SetAndGet(this double[] array, long index, double update) { array.VolatileSet(index, update); return update; } public static double AccumulateAndGet(this double[] array, long index, double x, Func<double, double, double> accumulator) { return ref array[index].AccumulateAndGet(x, accumulator); } public static double GetAndAccumulate(this double[] array, long index, double x, Func<double, double, double> accumulator) { return ref array[index].GetAndAccumulate(x, accumulator); } public static double UpdateAndGet(this double[] array, long index, Func<double, double> updater) { return ref array[index].UpdateAndGet(updater); } public static double GetAndUpdate(this double[] array, long index, Func<double, double> updater) { return ref array[index].GetAndUpdate(updater); } } }