DotNext by Roman Sakno

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

 AtomicBoolean

public struct AtomicBoolean : IEquatable<bool>, ISerializable
using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Threading; namespace DotNext.Threading { [Serializable] public struct AtomicBoolean : IEquatable<bool>, ISerializable { [System.Runtime.CompilerServices.Nullable(1)] private const string ValueSerData = "value"; private int value; public bool Value { [MethodImpl(MethodImplOptions.AggressiveInlining)] [IsReadOnly] get { return (byte)value != 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] set { this.value = (value ? 1 : 0); } } public AtomicBoolean(bool value) { this.value = value.ToInt32(); } [System.Runtime.CompilerServices.NullableContext(1)] private AtomicBoolean(SerializationInfo info, StreamingContext context) { value = (int)info.GetValue("value", typeof(int)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool CompareExchange(bool update, bool expected) { return Interlocked.CompareExchange(ref value, update.ToInt32(), expected.ToInt32()).ToBoolean(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool CompareAndSet(bool expected, bool update) { return CompareExchange(update, expected) == expected; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool FalseToTrue() { return CompareAndSet(false, true); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool TrueToFalse() { return CompareAndSet(true, false); } private static bool Negate(bool value) { return !value; } public unsafe bool NegateAndGet() { ValueFunc<bool, bool> updater = new ValueFunc<bool, bool>((IntPtr)(void*)); return UpdateAndGet(ref updater); } public unsafe bool GetAndNegate() { ValueFunc<bool, bool> updater = new ValueFunc<bool, bool>((IntPtr)(void*)); return GetAndUpdate(ref updater); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool GetAndSet(bool update) { return ref value.GetAndSet(update.ToInt32()).ToBoolean(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool SetAndGet(bool update) { Value = update; return update; } private (bool OldValue, bool NewValue) Update([In] [IsReadOnly] ref ValueFunc<bool, bool> updater) { bool flag2; bool flag; do { flag2 = updater.Invoke(flag = ref value.VolatileRead().ToBoolean()); } while (!CompareAndSet(flag, flag2)); return (flag, flag2); } private (bool OldValue, bool NewValue) Accumulate(bool x, [In] [IsReadOnly] ref ValueFunc<bool, bool, bool> accumulator) { bool flag2; bool flag; do { flag2 = accumulator.Invoke(flag = ref value.VolatileRead().ToBoolean(), x); } while (!CompareAndSet(flag, flag2)); return (flag, flag2); } [System.Runtime.CompilerServices.NullableContext(1)] public bool AccumulateAndGet(bool x, Func<bool, bool, bool> accumulator) { ValueFunc<bool, bool, bool> accumulator2 = new ValueFunc<bool, bool, bool>(accumulator, true); return AccumulateAndGet(x, ref accumulator2); } public bool AccumulateAndGet(bool x, [In] [IsReadOnly] ref ValueFunc<bool, bool, bool> accumulator) { return Accumulate(x, ref accumulator).NewValue; } [System.Runtime.CompilerServices.NullableContext(1)] public bool GetAndAccumulate(bool x, Func<bool, bool, bool> accumulator) { ValueFunc<bool, bool, bool> accumulator2 = new ValueFunc<bool, bool, bool>(accumulator, true); return GetAndAccumulate(x, ref accumulator2); } public bool GetAndAccumulate(bool x, [In] [IsReadOnly] ref ValueFunc<bool, bool, bool> accumulator) { return Accumulate(x, ref accumulator).OldValue; } [System.Runtime.CompilerServices.NullableContext(1)] public bool UpdateAndGet(Func<bool, bool> updater) { ValueFunc<bool, bool> updater2 = new ValueFunc<bool, bool>(updater, true); return UpdateAndGet(ref updater2); } public bool UpdateAndGet([In] [IsReadOnly] ref ValueFunc<bool, bool> updater) { return Update(ref updater).NewValue; } [System.Runtime.CompilerServices.NullableContext(1)] public bool GetAndUpdate(Func<bool, bool> updater) { ValueFunc<bool, bool> updater2 = new ValueFunc<bool, bool>(updater, true); return GetAndUpdate(ref updater2); } public bool GetAndUpdate([In] [IsReadOnly] ref ValueFunc<bool, bool> updater) { return Update(ref updater).OldValue; } internal void Acquire() { SpinWait spinWait = default(SpinWait); while (CompareExchange(false, true)) { spinWait.SpinOnce(); } } internal void Release() { Value = false; } [IsReadOnly] public bool Equals(bool other) { return ref Unsafe.AsRef(ref value).VolatileRead() == other.ToInt32(); } [IsReadOnly] public override int GetHashCode() { return ref Unsafe.AsRef(ref value).VolatileRead(); } [IsReadOnly] [System.Runtime.CompilerServices.NullableContext(2)] public override bool Equals(object other) { if (!(other is bool)) { if (!(other is AtomicBoolean)) return false; AtomicBoolean atomicBoolean = (AtomicBoolean)other; return Value == atomicBoolean.Value; } bool other2 = (bool)other; return Equals(other2); } [IsReadOnly] [System.Runtime.CompilerServices.NullableContext(1)] public override string ToString() { if (!value.ToBoolean()) return bool.FalseString; return bool.TrueString; } [IsReadOnly] [System.Runtime.CompilerServices.NullableContext(1)] void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("value", value); } } }