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
{
public static class AtomicSingle
{
private static readonly ValueFunc<float, float, float> Sum = new ValueFunc<float, float, float>((IntPtr)(void*));
private static float SumImpl(float x, float y)
{
return x + y;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float VolatileRead(ref float value)
{
return value;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void VolatileWrite(ref float value, float newValue)
{
value = newValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float IncrementAndGet(ref float value)
{
return ref value.AccumulateAndGet(1, ref Sum);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float DecrementAndGet(ref float value)
{
return ref value.AccumulateAndGet(-1, ref Sum);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float Add(ref float value, float operand)
{
return ref value.AccumulateAndGet(operand, ref Sum);
}
[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;
}
private static (float OldValue, float NewValue) Update(ref float value, [In] [System.Runtime.CompilerServices.IsReadOnly] ref ValueFunc<float, float> updater)
{
float num2;
float num;
do {
num2 = updater.Invoke(num = ref value.VolatileRead());
} while (!ref value.CompareAndSet(num, num2));
return (num, num2);
}
private static (float OldValue, float NewValue) Accumulate(ref float value, float x, [In] [System.Runtime.CompilerServices.IsReadOnly] ref ValueFunc<float, float, float> accumulator)
{
float num2;
float num;
do {
num2 = 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)
{
ValueFunc<float, float, float> accumulator2 = new ValueFunc<float, float, float>(accumulator, true);
return ref value.AccumulateAndGet(x, ref accumulator2);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float AccumulateAndGet(ref float value, float x, [In] [System.Runtime.CompilerServices.IsReadOnly] ref ValueFunc<float, float, float> accumulator)
{
return Accumulate(ref value, x, ref accumulator).NewValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float GetAndAccumulate(ref float value, float x, Func<float, float, float> accumulator)
{
ValueFunc<float, float, float> accumulator2 = new ValueFunc<float, float, float>(accumulator, true);
return ref value.GetAndAccumulate(x, ref accumulator2);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float GetAndAccumulate(ref float value, float x, [In] [System.Runtime.CompilerServices.IsReadOnly] ref ValueFunc<float, float, float> accumulator)
{
return Accumulate(ref value, x, ref accumulator).OldValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float UpdateAndGet(ref float value, Func<float, float> updater)
{
ValueFunc<float, float> updater2 = new ValueFunc<float, float>(updater, true);
return ref value.UpdateAndGet(ref updater2);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float UpdateAndGet(ref float value, [In] [System.Runtime.CompilerServices.IsReadOnly] ref ValueFunc<float, float> updater)
{
return Update(ref value, ref updater).NewValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float GetAndUpdate(ref float value, Func<float, float> updater)
{
ValueFunc<float, float> updater2 = new ValueFunc<float, float>(updater, true);
return ref value.GetAndUpdate(ref updater2);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float GetAndUpdate(ref float value, [In] [System.Runtime.CompilerServices.IsReadOnly] ref ValueFunc<float, float> updater)
{
return Update(ref value, ref 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)
{
ValueFunc<float, float, float> accumulator2 = new ValueFunc<float, float, float>(accumulator, true);
return array.AccumulateAndGet(index, x, ref accumulator2);
}
public static float AccumulateAndGet(this float[] array, long index, float x, [In] [System.Runtime.CompilerServices.IsReadOnly] ref ValueFunc<float, float, float> accumulator)
{
return ref array[index].AccumulateAndGet(x, ref accumulator);
}
public static float GetAndAccumulate(this float[] array, long index, float x, Func<float, float, float> accumulator)
{
ValueFunc<float, float, float> accumulator2 = new ValueFunc<float, float, float>(accumulator, true);
return array.GetAndAccumulate(index, x, ref accumulator2);
}
public static float GetAndAccumulate(this float[] array, long index, float x, [In] [System.Runtime.CompilerServices.IsReadOnly] ref ValueFunc<float, float, float> accumulator)
{
return ref array[index].GetAndAccumulate(x, ref accumulator);
}
public static float UpdateAndGet(this float[] array, long index, Func<float, float> updater)
{
ValueFunc<float, float> updater2 = new ValueFunc<float, float>(updater, true);
return array.UpdateAndGet(index, ref updater2);
}
public static float UpdateAndGet(this float[] array, long index, [In] [System.Runtime.CompilerServices.IsReadOnly] ref ValueFunc<float, float> updater)
{
return ref array[index].UpdateAndGet(ref updater);
}
public static float GetAndUpdate(this float[] array, long index, Func<float, float> updater)
{
ValueFunc<float, float> updater2 = new ValueFunc<float, float>(updater, true);
return array.GetAndUpdate(index, ref updater2);
}
public static float GetAndUpdate(this float[] array, long index, [In] [System.Runtime.CompilerServices.IsReadOnly] ref ValueFunc<float, float> updater)
{
return ref array[index].GetAndUpdate(ref updater);
}
}
}