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