AtomicReference
Provides atomic operations for the reference type.
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Threading;
namespace DotNext.Threading
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
public static class AtomicReference
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool CompareAndSet<[System.Runtime.CompilerServices.Nullable(2)] T>(ref T value, T expected, T update) where T : class
{
return Interlocked.CompareExchange(ref value, update, expected) == expected;
}
[System.Runtime.CompilerServices.NullableContext(0)]
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1,
1
})]
private static (T OldValue, T NewValue) Update<[System.Runtime.CompilerServices.Nullable(2)] T, TUpdater>([System.Runtime.CompilerServices.Nullable(1)] ref T value, TUpdater updater) where T : class where TUpdater : struct, ISupplier<T, T>
{
T val2;
T val;
do {
val2 = ((ISupplier<T, T>)updater).Invoke(val = Volatile.Read(ref value));
} while (!CompareAndSet(ref value, val, val2));
return (val, val2);
}
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1,
1
})]
private static (T OldValue, T NewValue) Accumulate<[System.Runtime.CompilerServices.Nullable(2)] T, [System.Runtime.CompilerServices.Nullable(0)] TAccumulator>(ref T value, T x, [System.Runtime.CompilerServices.Nullable(0)] TAccumulator accumulator) where T : class where TAccumulator : struct, ISupplier<T, T, T>
{
T val2;
T val;
do {
val2 = ((ISupplier<T, T, T>)accumulator).Invoke(val = Volatile.Read(ref value), x);
} while (!CompareAndSet(ref value, val, val2));
return (val, val2);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T AccumulateAndGet<[System.Runtime.CompilerServices.Nullable(2)] T>(ref T value, T x, Func<T, T, T> accumulator) where T : class
{
return Accumulate(ref value, x, (DelegatingSupplier<T, T, T>)accumulator).NewValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[CLSCompliant(false)]
public static T AccumulateAndGet<[System.Runtime.CompilerServices.Nullable(2)] T>(ref T value, T x, [System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1,
1,
1
})] IntPtr accumulator) where T : class
{
return Accumulate(ref value, x, (Supplier<T, T, T>)(long)accumulator).NewValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[return: NotNullIfNotNull("value")]
public static T GetAndAccumulate<[System.Runtime.CompilerServices.Nullable(2)] T>(ref T value, T x, Func<T, T, T> accumulator) where T : class
{
return Accumulate(ref value, x, (DelegatingSupplier<T, T, T>)accumulator).OldValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[CLSCompliant(false)]
[return: NotNullIfNotNull("value")]
public static T GetAndAccumulate<[System.Runtime.CompilerServices.Nullable(2)] T>(ref T value, T x, [System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1,
1,
1
})] IntPtr accumulator) where T : class
{
return Accumulate(ref value, x, (Supplier<T, T, T>)(long)accumulator).OldValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T UpdateAndGet<[System.Runtime.CompilerServices.Nullable(2)] T>(ref T value, Func<T, T> updater) where T : class
{
return Update(ref value, (DelegatingSupplier<T, T>)updater).NewValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[CLSCompliant(false)]
public static T UpdateAndGet<[System.Runtime.CompilerServices.Nullable(2)] T>(ref T value, [System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1,
1
})] IntPtr updater) where T : class
{
return Update(ref value, (Supplier<T, T>)(long)updater).NewValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[return: NotNullIfNotNull("value")]
public static T GetAndUpdate<[System.Runtime.CompilerServices.Nullable(2)] T>(ref T value, Func<T, T> updater) where T : class
{
return Update(ref value, (DelegatingSupplier<T, T>)updater).OldValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[CLSCompliant(false)]
[return: NotNullIfNotNull("value")]
public static T GetAndUpdate<[System.Runtime.CompilerServices.Nullable(2)] T>(ref T value, [System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1,
1
})] IntPtr updater) where T : class
{
return Update(ref value, (Supplier<T, T>)(long)updater).OldValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T VolatileRead<[System.Runtime.CompilerServices.Nullable(2)] T>(this T[] array, long index) where T : class
{
return Volatile.Read(ref array[index]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void VolatileWrite<[System.Runtime.CompilerServices.Nullable(2)] T>(this T[] array, long index, T element) where T : class
{
Volatile.Write(ref array[index], element);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool CompareAndSet<[System.Runtime.CompilerServices.Nullable(2)] T>(this T[] array, long index, T expected, T update) where T : class
{
return CompareAndSet(ref array[index], expected, update);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T CompareExchange<[System.Runtime.CompilerServices.Nullable(2)] T>(this T[] array, long index, T update, T comparand) where T : class
{
return Interlocked.CompareExchange(ref array[index], update, comparand);
}
public static T GetAndSet<[System.Runtime.CompilerServices.Nullable(2)] T>(this T[] array, long index, T update) where T : class
{
return Interlocked.Exchange(ref array[index], update);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[return: NotNullIfNotNull("update")]
public static T SetAndGet<[System.Runtime.CompilerServices.Nullable(2)] T>(this T[] array, long index, T update) where T : class
{
array.VolatileWrite(index, update);
return update;
}
public static T AccumulateAndGet<[System.Runtime.CompilerServices.Nullable(2)] T>(this T[] array, long index, T x, Func<T, T, T> accumulator) where T : class
{
return AccumulateAndGet(ref array[index], x, accumulator);
}
[CLSCompliant(false)]
public static T AccumulateAndGet<[System.Runtime.CompilerServices.Nullable(2)] T>(this T[] array, long index, T x, [System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1,
1,
1
})] IntPtr accumulator) where T : class
{
return AccumulateAndGet(ref array[index], x, accumulator);
}
public static T GetAndAccumulate<[System.Runtime.CompilerServices.Nullable(2)] T>(this T[] array, long index, T x, Func<T, T, T> accumulator) where T : class
{
return GetAndAccumulate(ref array[index], x, accumulator);
}
[CLSCompliant(false)]
public static T GetAndAccumulate<[System.Runtime.CompilerServices.Nullable(2)] T>(this T[] array, long index, T x, [System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1,
1,
1
})] IntPtr accumulator) where T : class
{
return GetAndAccumulate(ref array[index], x, accumulator);
}
public static T UpdateAndGet<[System.Runtime.CompilerServices.Nullable(2)] T>(this T[] array, long index, Func<T, T> updater) where T : class
{
return UpdateAndGet(ref array[index], updater);
}
[CLSCompliant(false)]
public static T UpdateAndGet<[System.Runtime.CompilerServices.Nullable(2)] T>(this T[] array, long index, [System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1,
1
})] IntPtr updater) where T : class
{
return UpdateAndGet(ref array[index], updater);
}
public static T GetAndUpdate<[System.Runtime.CompilerServices.Nullable(2)] T>(this T[] array, long index, Func<T, T> updater) where T : class
{
return GetAndUpdate(ref array[index], updater);
}
[CLSCompliant(false)]
public static T GetAndUpdate<[System.Runtime.CompilerServices.Nullable(2)] T>(this T[] array, long index, [System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1,
1
})] IntPtr updater) where T : class
{
return GetAndUpdate(ref array[index], updater);
}
}
}