AtomicUInt64
Various atomic operations for UInt64 data type
accessible as extension methods.
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
namespace DotNext.Threading
{
[CLSCompliant(false)]
public static class AtomicUInt64
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ulong VolatileRead([In] [IsReadOnly] ref ulong value)
{
return Volatile.Read(ref Unsafe.AsRef(ref value));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void VolatileWrite(ref ulong value, ulong newValue)
{
Volatile.Write(ref value, newValue);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ulong IncrementAndGet(ref ulong value)
{
return Interlocked.Increment(ref value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ulong DecrementAndGet(ref ulong value)
{
return Interlocked.Decrement(ref value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool CompareAndSet(ref ulong value, ulong expected, ulong update)
{
return Interlocked.CompareExchange(ref value, update, expected) == expected;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ulong AddAndGet(ref ulong value, ulong operand)
{
return Interlocked.Add(ref value, operand);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ulong GetAndAdd(ref ulong value, ulong operand)
{
return Accumulate(ref value, operand, default(Adder)).OldValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ulong GetAndBitwiseAnd(ref ulong value, ulong operand)
{
return Interlocked.And(ref value, operand);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ulong BitwiseAndAndGet(ref ulong value, ulong operand)
{
return Interlocked.And(ref value, operand) & operand;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ulong GetAndBitwiseOr(ref ulong value, ulong operand)
{
return Interlocked.Or(ref value, operand);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ulong BitwiseOrAndGet(ref ulong value, ulong operand)
{
return Interlocked.Or(ref value, operand) | operand;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ulong GetAndBitwiseXor(ref ulong value, ulong operand)
{
return Accumulate(ref value, operand, default(BitwiseXor)).OldValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ulong BitwiseXorAndGet(ref ulong value, ulong operand)
{
return Accumulate(ref value, operand, default(BitwiseXor)).NewValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ulong GetAndSet(ref ulong value, ulong update)
{
return Interlocked.Exchange(ref value, update);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ulong SetAndGet(ref ulong value, ulong update)
{
ref value.VolatileWrite(update);
return update;
}
private static (ulong OldValue, ulong NewValue) Update<TUpdater>(ref ulong value, TUpdater updater) where TUpdater : struct, ISupplier<ulong, ulong>
{
ulong num = Volatile.Read(ref value);
ulong num3;
ulong num2;
do {
num3 = ((ISupplier<ulong, ulong>)updater).Invoke(num2 = num);
} while ((num = Interlocked.CompareExchange(ref value, num3, num2)) != num2);
return (num2, num3);
}
private static (ulong OldValue, ulong NewValue) Accumulate<TAccumulator>(ref ulong value, ulong x, TAccumulator accumulator) where TAccumulator : struct, ISupplier<ulong, ulong, ulong>
{
ulong num = Volatile.Read(ref value);
ulong num3;
ulong num2;
do {
num3 = ((ISupplier<ulong, ulong, ulong>)accumulator).Invoke(num2 = num, x);
} while ((num = Interlocked.CompareExchange(ref value, num3, num2)) != num2);
return (num2, num3);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[System.Runtime.CompilerServices.NullableContext(1)]
public static ulong AccumulateAndGet(ref ulong value, ulong x, Func<ulong, ulong, ulong> accumulator)
{
return Accumulate(ref value, x, (DelegatingSupplier<ulong, ulong, ulong>)accumulator).NewValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ulong AccumulateAndGet(ref ulong value, ulong x, IntPtr accumulator)
{
return Accumulate(ref value, x, (Supplier<ulong, ulong, ulong>)(long)accumulator).NewValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[System.Runtime.CompilerServices.NullableContext(1)]
public static ulong GetAndAccumulate(ref ulong value, ulong x, Func<ulong, ulong, ulong> accumulator)
{
return Accumulate(ref value, x, (DelegatingSupplier<ulong, ulong, ulong>)accumulator).OldValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ulong GetAndAccumulate(ref ulong value, ulong x, IntPtr accumulator)
{
return Accumulate(ref value, x, (Supplier<ulong, ulong, ulong>)(long)accumulator).OldValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[System.Runtime.CompilerServices.NullableContext(1)]
public static ulong UpdateAndGet(ref ulong value, Func<ulong, ulong> updater)
{
return Update(ref value, (DelegatingSupplier<ulong, ulong>)updater).NewValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ulong UpdateAndGet(ref ulong value, IntPtr updater)
{
return Update(ref value, (Supplier<ulong, ulong>)(long)updater).NewValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[System.Runtime.CompilerServices.NullableContext(1)]
public static ulong GetAndUpdate(ref ulong value, Func<ulong, ulong> updater)
{
return Update(ref value, (DelegatingSupplier<ulong, ulong>)updater).OldValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ulong GetAndUpdate(ref ulong value, IntPtr updater)
{
return Update(ref value, (Supplier<ulong, ulong>)(long)updater).OldValue;
}
}
}