DotNext by Roman Sakno

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

 AtomicSingle

public static class AtomicSingle
Various atomic operations for Single data type accessible as extension methods.
using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; namespace DotNext.Threading { [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] public static class AtomicSingle { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float VolatileRead([In] [IsReadOnly] ref float value) { return Volatile.Read(ref Unsafe.AsRef(ref value)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void VolatileWrite(ref float value, float newValue) { Volatile.Write(ref value, newValue); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float IncrementAndGet(ref float value) { return Update(ref value, default(Increment)).NewValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float DecrementAndGet(ref float value) { return Update(ref value, default(Decrement)).NewValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float Add(ref float value, float operand) { return Accumulate(ref value, operand, default(Adder)).NewValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool Equals(float x, float y) { if (x != y) { if (float.IsNaN(x)) return float.IsNaN(y); return false; } return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool CompareAndSet(ref float value, float expected, float update) { return Equals(Interlocked.CompareExchange(ref value, update, expected), expected); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float GetAndSet(ref float value, float update) { return Interlocked.Exchange(ref value, update); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float SetAndGet(ref float value, float update) { ref value.VolatileWrite(update); return update; } [System.Runtime.CompilerServices.NullableContext(0)] private static (float OldValue, float NewValue) Update<TUpdater>(ref float value, TUpdater updater) where TUpdater : struct, ISupplier<float, float> { float num2; float num; do { num2 = ((ISupplier<float, float>)updater).Invoke(num = ref value.VolatileRead()); } while (!ref value.CompareAndSet(num, num2)); return (num, num2); } [System.Runtime.CompilerServices.NullableContext(0)] private static (float OldValue, float NewValue) Accumulate<TAccumulator>(ref float value, float x, TAccumulator accumulator) where TAccumulator : struct, ISupplier<float, float, float> { float num2; float num; do { num2 = ((ISupplier<float, float, float>)accumulator).Invoke(num = ref value.VolatileRead(), x); } while (!ref value.CompareAndSet(num, num2)); return (num, num2); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float AccumulateAndGet(ref float value, float x, Func<float, float, float> accumulator) { return Accumulate(ref value, x, (DelegatingSupplier<float, float, float>)accumulator).NewValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.CompilerServices.NullableContext(0)] [CLSCompliant(false)] public static float AccumulateAndGet(ref float value, float x, IntPtr accumulator) { return Accumulate(ref value, x, (Supplier<float, float, float>)(long)accumulator).NewValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float GetAndAccumulate(ref float value, float x, Func<float, float, float> accumulator) { return Accumulate(ref value, x, (DelegatingSupplier<float, float, float>)accumulator).OldValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.CompilerServices.NullableContext(0)] [CLSCompliant(false)] public static float GetAndAccumulate(ref float value, float x, IntPtr accumulator) { return Accumulate(ref value, x, (Supplier<float, float, float>)(long)accumulator).OldValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float UpdateAndGet(ref float value, Func<float, float> updater) { return Update(ref value, (DelegatingSupplier<float, float>)updater).NewValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.CompilerServices.NullableContext(0)] [CLSCompliant(false)] public static float UpdateAndGet(ref float value, IntPtr updater) { return Update(ref value, (Supplier<float, float>)(long)updater).NewValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float GetAndUpdate(ref float value, Func<float, float> updater) { return Update(ref value, (DelegatingSupplier<float, float>)updater).OldValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.CompilerServices.NullableContext(0)] [CLSCompliant(false)] public static float GetAndUpdate(ref float value, IntPtr updater) { return Update(ref value, (Supplier<float, float>)(long)updater).OldValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float VolatileRead(this float[] array, long index) { return ref array[index].VolatileRead(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void VolatileWrite(this float[] array, long index, float value) { ref array[index].VolatileWrite(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float IncrementAndGet(this float[] array, long index) { return ref array[index].IncrementAndGet(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float DecrementAndGet(this float[] array, long index) { return ref array[index].DecrementAndGet(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float CompareExchange(this float[] array, long index, float update, float comparand) { return Interlocked.CompareExchange(ref array[index], update, comparand); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool CompareAndSet(this float[] array, long index, float expected, float update) { return ref array[index].CompareAndSet(expected, update); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float Add(this float[] array, long index, float operand) { return ref array[index].Add(operand); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float GetAndSet(this float[] array, long index, float update) { return ref array[index].GetAndSet(update); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float SetAndGet(this float[] array, long index, float update) { array.VolatileWrite(index, update); return update; } public static float AccumulateAndGet(this float[] array, long index, float x, Func<float, float, float> accumulator) { return ref array[index].AccumulateAndGet(x, accumulator); } [System.Runtime.CompilerServices.NullableContext(0)] [CLSCompliant(false)] public static float AccumulateAndGet([System.Runtime.CompilerServices.Nullable(1)] this float[] array, long index, float x, IntPtr accumulator) { return ref array[index].AccumulateAndGet(x, accumulator); } public static float GetAndAccumulate(this float[] array, long index, float x, Func<float, float, float> accumulator) { return ref array[index].GetAndAccumulate(x, accumulator); } [System.Runtime.CompilerServices.NullableContext(0)] [CLSCompliant(false)] public static float GetAndAccumulate([System.Runtime.CompilerServices.Nullable(1)] this float[] array, long index, float x, IntPtr accumulator) { return ref array[index].GetAndAccumulate(x, accumulator); } public static float UpdateAndGet(this float[] array, long index, Func<float, float> updater) { return ref array[index].UpdateAndGet(updater); } [System.Runtime.CompilerServices.NullableContext(0)] [CLSCompliant(false)] public static float UpdateAndGet([System.Runtime.CompilerServices.Nullable(1)] this float[] array, long index, IntPtr updater) { return ref array[index].UpdateAndGet(updater); } public static float GetAndUpdate(this float[] array, long index, Func<float, float> updater) { return ref array[index].GetAndUpdate(updater); } [System.Runtime.CompilerServices.NullableContext(0)] [CLSCompliant(false)] public static float GetAndUpdate([System.Runtime.CompilerServices.Nullable(1)] this float[] array, long index, IntPtr updater) { return ref array[index].GetAndUpdate(updater); } } }