DotNext by .NET Foundation and Contributors

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

 AtomicBoolean

public struct AtomicBoolean : IEquatable<bool>, ISerializable
Represents atomic boolean.
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 { [StructLayout(LayoutKind.Auto)] private readonly struct Negation : ISupplier<bool, bool> { bool ISupplier<bool, bool>.Invoke(bool value) { return !value; } } [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); } public bool NegateAndGet() { return Update(default(Negation)).NewValue; } public bool GetAndNegate() { return Update(default(Negation)).OldValue; } [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<TUpdater>(TUpdater updater) where TUpdater : struct, ISupplier<bool, bool> { bool flag2; bool flag; do { flag2 = ((ISupplier<bool, bool>)updater).Invoke(flag = ref value.VolatileRead().ToBoolean()); } while (!CompareAndSet(flag, flag2)); return (flag, flag2); } private (bool OldValue, bool NewValue) Accumulate<TAccumulator>(bool x, TAccumulator accumulator) where TAccumulator : struct, ISupplier<bool, bool, bool> { bool flag2; bool flag; do { flag2 = ((ISupplier<bool, bool, bool>)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) { return Accumulate(x, (DelegatingSupplier<bool, bool, bool>)accumulator).NewValue; } [CLSCompliant(false)] public bool AccumulateAndGet(bool x, IntPtr accumulator) { return Accumulate(x, (Supplier<bool, bool, bool>)(long)accumulator).NewValue; } [System.Runtime.CompilerServices.NullableContext(1)] public bool GetAndAccumulate(bool x, Func<bool, bool, bool> accumulator) { return Accumulate(x, (DelegatingSupplier<bool, bool, bool>)accumulator).OldValue; } [CLSCompliant(false)] public bool GetAndAccumulate(bool x, IntPtr accumulator) { return Accumulate(x, (Supplier<bool, bool, bool>)(long)accumulator).OldValue; } [System.Runtime.CompilerServices.NullableContext(1)] public bool UpdateAndGet(Func<bool, bool> updater) { return Update((DelegatingSupplier<bool, bool>)updater).NewValue; } [CLSCompliant(false)] public bool UpdateAndGet(IntPtr updater) { return Update((Supplier<bool, bool>)(long)updater).NewValue; } [System.Runtime.CompilerServices.NullableContext(1)] public bool GetAndUpdate(Func<bool, bool> updater) { return Update((DelegatingSupplier<bool, bool>)updater).OldValue; } [CLSCompliant(false)] public bool GetAndUpdate(IntPtr updater) { return Update((Supplier<bool, bool>)(long)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); } } }