Atomic<T, V, W>
using System;
using System.Runtime.CompilerServices;
namespace DotNext.Threading
{
internal static class Atomic<T, V, W> where W : struct, IAtomicWrapper<T, V>
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static V CompareExchange(ref W wrapper, ref T value, V update, V expected)
{
return wrapper.Convert(wrapper.Atomic.CompareExchange(ref value, wrapper.Convert(update), wrapper.Convert(expected)));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static bool CompareAndSet(ref W wrapper, ref T value, V expected, V update)
{
return wrapper.Atomic.CompareAndSet(ref value, wrapper.Convert(expected), wrapper.Convert(update));
}
internal static (V OldValue, V NewValue) Update(ref W wrapper, ref T value, Func<V, V> updater)
{
V val2;
V val;
do {
val2 = updater(val = wrapper.Convert(wrapper.Atomic.VolatileRead(ref value)));
} while (!CompareAndSet(ref wrapper, ref value, val, val2));
return (val, val2);
}
internal static (V OldValue, V NewValue) Accumulate(ref W wrapper, ref T value, V x, Func<V, V, V> accumulator)
{
V val2;
V val;
do {
val2 = accumulator(val = wrapper.Convert(wrapper.Atomic.VolatileRead(ref value)), x);
} while (!CompareAndSet(ref wrapper, ref value, val, val2));
return (val, val2);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static V GetAndSet(ref W wrapper, ref T value, V update)
{
return wrapper.Convert(wrapper.Atomic.Exchange(ref value, wrapper.Convert(update)));
}
}
}