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