DotNext by .NET Foundation and Contributors

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

 AtomicBoolean

public struct AtomicBoolean : IEquatable<bool>
Represents atomic boolean.
using DotNext.Runtime.CompilerServices; using System; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; namespace DotNext.Threading { public struct AtomicBoolean : IEquatable<bool> { [StructLayout(LayoutKind.Auto)] private readonly struct Negation : ISupplier<bool, bool>, IFunctional<Func<bool, bool>> { bool ISupplier<bool, bool>.Invoke(bool value) { return !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(); } [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 flag = Value; bool flag3; bool flag2; do { flag3 = ((ISupplier<bool, bool>)updater).Invoke(flag2 = flag); } while ((flag = CompareExchange(flag3, flag2)) != flag2); return (flag2, flag3); } private (bool OldValue, bool NewValue) Accumulate<TAccumulator>(bool x, TAccumulator accumulator) where TAccumulator : struct, ISupplier<bool, bool, bool> { bool flag = Value; bool flag3; bool flag2; do { flag3 = ((ISupplier<bool, bool, bool>)accumulator).Invoke(flag2 = flag, x); } while ((flag = CompareExchange(flag3, flag2)) != flag2); return (flag2, flag3); } [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([NotNullWhen(true)] 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; } } }