DotNext by Roman Sakno

<PackageReference Include="DotNext" Version="2.11.0" />

 AtomicIntPtr

public static class AtomicIntPtr
Various atomic operations for IntPtr data type accessible as extension methods.
using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; namespace DotNext.Threading { [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] public static class AtomicIntPtr { [System.Runtime.CompilerServices.Nullable(0)] private static readonly ValueFunc<IntPtr, IntPtr, IntPtr> Sum = new ValueFunc<IntPtr, IntPtr, IntPtr>((IntPtr)(void*)); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IntPtr VolatileRead(ref IntPtr value) { return value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void VolatileWrite(ref IntPtr value, IntPtr newValue) { value = newValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IntPtr IncrementAndGet(ref IntPtr value) { return ref value.AccumulateAndGet(new IntPtr(1), ref Sum); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IntPtr DecrementAndGet(ref IntPtr value) { return ref value.AccumulateAndGet(new IntPtr(-1), ref Sum); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IntPtr Add(ref IntPtr value, IntPtr operand) { return ref value.AccumulateAndGet(operand, ref Sum); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool CompareAndSet(ref IntPtr value, IntPtr expected, IntPtr update) { return Interlocked.CompareExchange(ref value, update, expected) == expected; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IntPtr GetAndSet(ref IntPtr value, IntPtr update) { return Interlocked.Exchange(ref value, update); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IntPtr SetAndGet(ref IntPtr value, IntPtr update) { ref value.VolatileWrite(update); return update; } [System.Runtime.CompilerServices.NullableContext(0)] private static (IntPtr OldValue, IntPtr NewValue) Update(ref IntPtr value, [In] [IsReadOnly] ref ValueFunc<IntPtr, IntPtr> updater) { IntPtr intPtr2; IntPtr intPtr; do { intPtr2 = updater.Invoke(intPtr = ref value.VolatileRead()); } while (!ref value.CompareAndSet(intPtr, intPtr2)); return (intPtr, intPtr2); } [System.Runtime.CompilerServices.NullableContext(0)] private static (IntPtr OldValue, IntPtr NewValue) Accumulate(ref IntPtr value, IntPtr x, [In] [IsReadOnly] ref ValueFunc<IntPtr, IntPtr, IntPtr> accumulator) { IntPtr intPtr2; IntPtr intPtr; do { intPtr2 = accumulator.Invoke(intPtr = ref value.VolatileRead(), x); } while (!ref value.CompareAndSet(intPtr, intPtr2)); return (intPtr, intPtr2); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IntPtr AccumulateAndGet(ref IntPtr value, IntPtr x, Func<IntPtr, IntPtr, IntPtr> accumulator) { ValueFunc<IntPtr, IntPtr, IntPtr> accumulator2 = new ValueFunc<IntPtr, IntPtr, IntPtr>(accumulator, true); return ref value.AccumulateAndGet(x, ref accumulator2); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.CompilerServices.NullableContext(0)] public static IntPtr AccumulateAndGet(ref IntPtr value, IntPtr x, [In] [IsReadOnly] ref ValueFunc<IntPtr, IntPtr, IntPtr> accumulator) { return Accumulate(ref value, x, ref accumulator).NewValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IntPtr GetAndAccumulate(ref IntPtr value, IntPtr x, Func<IntPtr, IntPtr, IntPtr> accumulator) { ValueFunc<IntPtr, IntPtr, IntPtr> accumulator2 = new ValueFunc<IntPtr, IntPtr, IntPtr>(accumulator, true); return ref value.GetAndAccumulate(x, ref accumulator2); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.CompilerServices.NullableContext(0)] public static IntPtr GetAndAccumulate(ref IntPtr value, IntPtr x, [In] [IsReadOnly] ref ValueFunc<IntPtr, IntPtr, IntPtr> accumulator) { return Accumulate(ref value, x, ref accumulator).OldValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IntPtr UpdateAndGet(ref IntPtr value, Func<IntPtr, IntPtr> updater) { ValueFunc<IntPtr, IntPtr> updater2 = new ValueFunc<IntPtr, IntPtr>(updater, true); return ref value.UpdateAndGet(ref updater2); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.CompilerServices.NullableContext(0)] public static IntPtr UpdateAndGet(ref IntPtr value, [In] [IsReadOnly] ref ValueFunc<IntPtr, IntPtr> updater) { return Update(ref value, ref updater).NewValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IntPtr GetAndUpdate(ref IntPtr value, Func<IntPtr, IntPtr> updater) { ValueFunc<IntPtr, IntPtr> updater2 = new ValueFunc<IntPtr, IntPtr>(updater, true); return ref value.GetAndUpdate(ref updater2); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [System.Runtime.CompilerServices.NullableContext(0)] public static IntPtr GetAndUpdate(ref IntPtr value, [In] [IsReadOnly] ref ValueFunc<IntPtr, IntPtr> updater) { return Update(ref value, ref updater).OldValue; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IntPtr VolatileRead(this IntPtr[] array, long index) { return ref array[index].VolatileRead(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void VolatileWrite(this IntPtr[] array, long index, IntPtr value) { ref array[index].VolatileWrite(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IntPtr IncrementAndGet(this IntPtr[] array, long index) { return ref array[index].IncrementAndGet(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IntPtr DecrementAndGet(this IntPtr[] array, long index) { return ref array[index].DecrementAndGet(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IntPtr CompareExchange(this IntPtr[] array, long index, IntPtr update, IntPtr comparand) { return Interlocked.CompareExchange(ref array[index], update, comparand); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool CompareAndSet(this IntPtr[] array, long index, IntPtr expected, IntPtr update) { return ref array[index].CompareAndSet(expected, update); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IntPtr GetAndSet(this IntPtr[] array, long index, IntPtr update) { return ref array[index].GetAndSet(update); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static IntPtr SetAndGet(this IntPtr[] array, long index, IntPtr update) { array.VolatileWrite(index, update); return update; } public static IntPtr AccumulateAndGet(this IntPtr[] array, long index, IntPtr x, Func<IntPtr, IntPtr, IntPtr> accumulator) { ValueFunc<IntPtr, IntPtr, IntPtr> accumulator2 = new ValueFunc<IntPtr, IntPtr, IntPtr>(accumulator, true); return array.AccumulateAndGet(index, x, ref accumulator2); } [System.Runtime.CompilerServices.NullableContext(0)] public static IntPtr AccumulateAndGet([System.Runtime.CompilerServices.Nullable(1)] this IntPtr[] array, long index, IntPtr x, [In] [IsReadOnly] ref ValueFunc<IntPtr, IntPtr, IntPtr> accumulator) { return ref array[index].AccumulateAndGet(x, ref accumulator); } public static IntPtr GetAndAccumulate(this IntPtr[] array, long index, IntPtr x, Func<IntPtr, IntPtr, IntPtr> accumulator) { ValueFunc<IntPtr, IntPtr, IntPtr> accumulator2 = new ValueFunc<IntPtr, IntPtr, IntPtr>(accumulator, true); return array.GetAndAccumulate(index, x, ref accumulator2); } [System.Runtime.CompilerServices.NullableContext(0)] public static IntPtr GetAndAccumulate([System.Runtime.CompilerServices.Nullable(1)] this IntPtr[] array, long index, IntPtr x, [In] [IsReadOnly] ref ValueFunc<IntPtr, IntPtr, IntPtr> accumulator) { return ref array[index].GetAndAccumulate(x, ref accumulator); } public static IntPtr UpdateAndGet(this IntPtr[] array, long index, Func<IntPtr, IntPtr> updater) { ValueFunc<IntPtr, IntPtr> updater2 = new ValueFunc<IntPtr, IntPtr>(updater, true); return array.UpdateAndGet(index, ref updater2); } [System.Runtime.CompilerServices.NullableContext(0)] public static IntPtr UpdateAndGet([System.Runtime.CompilerServices.Nullable(1)] this IntPtr[] array, long index, [In] [IsReadOnly] ref ValueFunc<IntPtr, IntPtr> updater) { return ref array[index].UpdateAndGet(ref updater); } public static IntPtr GetAndUpdate(this IntPtr[] array, long index, Func<IntPtr, IntPtr> updater) { ValueFunc<IntPtr, IntPtr> updater2 = new ValueFunc<IntPtr, IntPtr>(updater, true); return array.GetAndUpdate(index, ref updater2); } [System.Runtime.CompilerServices.NullableContext(0)] public static IntPtr GetAndUpdate([System.Runtime.CompilerServices.Nullable(1)] this IntPtr[] array, long index, [In] [IsReadOnly] ref ValueFunc<IntPtr, IntPtr> updater) { return ref array[index].GetAndUpdate(ref updater); } } }