DotNext by .NET Foundation and Contributors

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

 Atomic<T>

public struct Atomic<T> : IStrongBox, ICloneable where T : struct
Provides atomic access to non-primitive data type.
using DotNext.Runtime; using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace DotNext.Threading { [StructLayout(LayoutKind.Auto)] public struct Atomic<T> : IStrongBox, ICloneable where T : struct { private interface IEqualityComparer { bool Equals([In] [IsReadOnly] T x, [In] [IsReadOnly] T y); } [StructLayout(LayoutKind.Auto)] private readonly struct BitwiseEqualityComparer : IEqualityComparer { bool IEqualityComparer.Equals([In] [IsReadOnly] T x, [In] [IsReadOnly] T y) { return BitwiseComparer<T>.Equals(ref x, ref y); } } [StructLayout(LayoutKind.Auto)] private readonly struct DelegatingEqualityComparer : IEqualityComparer { private readonly Func<T, T, bool> func; internal DelegatingEqualityComparer(Func<T, T, bool> func) { if (func == null) throw new ArgumentNullException("func"); this.func = func; } bool IEqualityComparer.Equals([In] [IsReadOnly] T x, [In] [IsReadOnly] T y) { return func(x, y); } } [StructLayout(LayoutKind.Auto)] private readonly struct EqualityComparer : IEqualityComparer { private readonly IntPtr ptr; internal unsafe EqualityComparer(IntPtr ptr) { if (ptr == (IntPtr)(void*)null) throw new ArgumentNullException("ptr"); this.ptr = ptr; } bool IEqualityComparer.Equals([In] [IsReadOnly] T x, [In] [IsReadOnly] T y) { IntPtr intPtr = ptr; return (byte) != 0; } } public delegate void Updater (ref T current); public delegate void Accumulator (ref T current, [In] [IsReadOnly] T x); private T value; private AtomicBoolean lockState; public T Value { [IsReadOnly] get { Read(out T result); return result; } set { Write(ref value); } } [System.Runtime.CompilerServices.Nullable(2)] object IStrongBox.Value { [IsReadOnly] get { return Value; } set { Value = (T)value; } } public Atomic<T> Clone() { Atomic<T> result = default(Atomic<T>); Read(out result.value); return result; } object ICloneable.Clone() { return Clone(); } [IsReadOnly] public void Read(out T result) { AtomicBoolean atomicBoolean = lockState; atomicBoolean.Acquire(); Intrinsics.Copy<T>(ref value, out result); atomicBoolean = lockState; atomicBoolean.Release(); } public void Swap(ref Atomic<T> other) { lockState.Acquire(); other.Swap(ref value); lockState.Release(); } public void Swap(ref T other) { lockState.Acquire(); Intrinsics.Swap<T>(ref value, ref other); lockState.Release(); } public void Write([In] [IsReadOnly] ref T newValue) { lockState.Acquire(); Intrinsics.Copy<T>(ref newValue, out value); lockState.Release(); } [MethodImpl(MethodImplOptions.AggressiveOptimization)] private bool CompareExchange<TComparer>(TComparer comparer, [In] [IsReadOnly] ref T update, [In] [IsReadOnly] ref T expected, out T result) where TComparer : struct, IEqualityComparer { this.lockState.Acquire(); T x = this.value; bool num = ((IEqualityComparer)comparer).Equals(ref x, ref expected); if (num) Intrinsics.Copy<T>(ref update, out this.value); Intrinsics.Copy<T>(ref x, out result); this.lockState.Release(); return num; } public bool CompareExchange([In] [IsReadOnly] ref T update, [In] [IsReadOnly] ref T expected, out T result) { return CompareExchange(default(BitwiseEqualityComparer), ref update, ref expected, out result); } public bool CompareExchange([System.Runtime.CompilerServices.Nullable(new byte[] { 1, 0, 0 })] Func<T, T, bool> comparer, [In] [IsReadOnly] ref T update, [In] [IsReadOnly] ref T expected, out T result) { return CompareExchange(new DelegatingEqualityComparer(comparer), ref update, ref expected, out result); } [CLSCompliant(false)] public bool CompareExchange(IntPtr comparer, [In] [IsReadOnly] ref T update, [In] [IsReadOnly] ref T expected, out T result) { return CompareExchange(new EqualityComparer(comparer), ref update, ref expected, out result); } [MethodImpl(MethodImplOptions.AggressiveOptimization)] private bool CompareAndSet<TComparer>(TComparer comparer, [In] [IsReadOnly] ref T expected, [In] [IsReadOnly] ref T update) where TComparer : struct, IEqualityComparer { this.lockState.Acquire(); bool num = ((IEqualityComparer)comparer).Equals(ref this.value, ref expected); if (num) Intrinsics.Copy<T>(ref update, out this.value); this.lockState.Release(); return num; } public bool CompareAndSet([In] [IsReadOnly] ref T expected, [In] [IsReadOnly] ref T update) { return CompareAndSet(default(BitwiseEqualityComparer), ref expected, ref update); } public bool CompareAndSet([System.Runtime.CompilerServices.Nullable(new byte[] { 1, 0, 0 })] Func<T, T, bool> comparer, [In] [IsReadOnly] ref T expected, [In] [IsReadOnly] ref T update) { return CompareAndSet(new DelegatingEqualityComparer(comparer), ref expected, ref update); } [CLSCompliant(false)] public bool CompareAndSet(IntPtr comparer, [In] [IsReadOnly] ref T expected, [In] [IsReadOnly] ref T update) { return CompareAndSet(new EqualityComparer(comparer), ref expected, ref update); } public void Exchange([In] [IsReadOnly] ref T update, out T previous) { lockState.Acquire(); Intrinsics.Copy<T>(ref value, out previous); Intrinsics.Copy<T>(ref update, out value); lockState.Release(); } [MethodImpl(MethodImplOptions.AggressiveOptimization)] public void UpdateAndGet([System.Runtime.CompilerServices.Nullable(new byte[] { 1, 0 })] Updater updater, out T result) { ArgumentNullException.ThrowIfNull((object)updater, "updater"); lockState.Acquire(); try { updater(ref value); Intrinsics.Copy<T>(ref value, out result); } finally { lockState.Release(); } } [MethodImpl(MethodImplOptions.AggressiveOptimization)] public void GetAndUpdate([System.Runtime.CompilerServices.Nullable(new byte[] { 1, 0 })] Updater updater, out T result) { ArgumentNullException.ThrowIfNull((object)updater, "updater"); lockState.Acquire(); T input = value; try { updater(ref value); Intrinsics.Copy<T>(ref input, out result); } finally { lockState.Release(); } } [MethodImpl(MethodImplOptions.AggressiveOptimization)] public void AccumulateAndGet([In] [IsReadOnly] ref T x, [System.Runtime.CompilerServices.Nullable(new byte[] { 1, 0 })] Accumulator accumulator, out T result) { ArgumentNullException.ThrowIfNull((object)accumulator, "accumulator"); lockState.Acquire(); try { accumulator(ref value, ref x); Intrinsics.Copy<T>(ref value, out result); } finally { lockState.Release(); } } [MethodImpl(MethodImplOptions.AggressiveOptimization)] public void GetAndAccumulate([In] [IsReadOnly] ref T x, [System.Runtime.CompilerServices.Nullable(new byte[] { 1, 0 })] Accumulator accumulator, out T result) { ArgumentNullException.ThrowIfNull((object)accumulator, "accumulator"); lockState.Acquire(); T input = value; try { accumulator(ref value, ref x); Intrinsics.Copy<T>(ref input, out result); } finally { lockState.Release(); } } [IsReadOnly] [System.Runtime.CompilerServices.NullableContext(2)] public override string ToString() { Read(out T result); return result.ToString(); } } }