AtomicBoolean
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;
}
}
}