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
{
public static class AtomicIntPtr
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static IntPtr VolatileRead([In] [IsReadOnly] ref IntPtr value)
{
return Volatile.Read(ref Unsafe.AsRef(ref value));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void VolatileWrite(ref IntPtr value, IntPtr newValue)
{
Volatile.Write(ref value, newValue);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static IntPtr IncrementAndGet(ref IntPtr value)
{
return Update(ref value, default(Increment)).NewValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static IntPtr DecrementAndGet(ref IntPtr value)
{
return Update(ref value, default(Decrement)).NewValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static IntPtr Add(ref IntPtr value, IntPtr operand)
{
return Accumulate(ref value, operand, default(Adder)).NewValue;
}
[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;
}
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
private static (IntPtr OldValue, IntPtr NewValue) Update<TUpdater>(ref IntPtr value, TUpdater updater) where TUpdater : struct, ISupplier<IntPtr, IntPtr>
{
IntPtr intPtr2;
IntPtr intPtr;
do {
intPtr2 = ((ISupplier<IntPtr, IntPtr>)updater).Invoke(intPtr = ref value.VolatileRead());
} while (!ref value.CompareAndSet(intPtr, intPtr2));
return (intPtr, intPtr2);
}
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
private static (IntPtr OldValue, IntPtr NewValue) Accumulate<TAccumulator>(ref IntPtr value, IntPtr x, TAccumulator accumulator) where TAccumulator : struct, ISupplier<IntPtr, IntPtr, IntPtr>
{
IntPtr intPtr2;
IntPtr intPtr;
do {
intPtr2 = ((ISupplier<IntPtr, IntPtr, IntPtr>)accumulator).Invoke(intPtr = ref value.VolatileRead(), x);
} while (!ref value.CompareAndSet(intPtr, intPtr2));
return (intPtr, intPtr2);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[System.Runtime.CompilerServices.NullableContext(1)]
public static IntPtr AccumulateAndGet(ref IntPtr value, IntPtr x, Func<IntPtr, IntPtr, IntPtr> accumulator)
{
return Accumulate(ref value, x, (DelegatingSupplier<IntPtr, IntPtr, IntPtr>)accumulator).NewValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[CLSCompliant(false)]
public static IntPtr AccumulateAndGet(ref IntPtr value, IntPtr x, IntPtr accumulator)
{
return Accumulate(ref value, x, (Supplier<IntPtr, IntPtr, IntPtr>)(long)accumulator).NewValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[System.Runtime.CompilerServices.NullableContext(1)]
public static IntPtr GetAndAccumulate(ref IntPtr value, IntPtr x, Func<IntPtr, IntPtr, IntPtr> accumulator)
{
return Accumulate(ref value, x, (DelegatingSupplier<IntPtr, IntPtr, IntPtr>)accumulator).OldValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[CLSCompliant(false)]
public static IntPtr GetAndAccumulate(ref IntPtr value, IntPtr x, IntPtr accumulator)
{
return Accumulate(ref value, x, (Supplier<IntPtr, IntPtr, IntPtr>)(long)accumulator).OldValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[System.Runtime.CompilerServices.NullableContext(1)]
public static IntPtr UpdateAndGet(ref IntPtr value, Func<IntPtr, IntPtr> updater)
{
return Update(ref value, (DelegatingSupplier<IntPtr, IntPtr>)updater).NewValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[CLSCompliant(false)]
public static IntPtr UpdateAndGet(ref IntPtr value, IntPtr updater)
{
return Update(ref value, (Supplier<IntPtr, IntPtr>)(long)updater).NewValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[System.Runtime.CompilerServices.NullableContext(1)]
public static IntPtr GetAndUpdate(ref IntPtr value, Func<IntPtr, IntPtr> updater)
{
return Update(ref value, (DelegatingSupplier<IntPtr, IntPtr>)updater).OldValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[CLSCompliant(false)]
public static IntPtr GetAndUpdate(ref IntPtr value, IntPtr updater)
{
return Update(ref value, (Supplier<IntPtr, IntPtr>)(long)updater).OldValue;
}
}
}