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);
}
}
}