AtomicBoolean
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
{
private const string ValueSerData = "value";
private int value;
public bool Value {
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get {
return (byte)value != 0;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set {
this.value = (value ? 1 : 0);
}
}
public AtomicBoolean(bool value)
{
this.value = value.ToInt32();
}
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] [System.Runtime.CompilerServices.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] [System.Runtime.CompilerServices.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);
}
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] [System.Runtime.CompilerServices.IsReadOnly] ref ValueFunc<bool, bool, bool> accumulator)
{
return Accumulate(x, ref accumulator).NewValue;
}
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] [System.Runtime.CompilerServices.IsReadOnly] ref ValueFunc<bool, bool, bool> accumulator)
{
return Accumulate(x, ref accumulator).OldValue;
}
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] [System.Runtime.CompilerServices.IsReadOnly] ref ValueFunc<bool, bool> updater)
{
return Update(ref updater).NewValue;
}
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] [System.Runtime.CompilerServices.IsReadOnly] ref ValueFunc<bool, bool> updater)
{
return Update(ref updater).OldValue;
}
internal void Acquire()
{
while (CompareExchange(false, true)) {
SpinWait spinWait = default(SpinWait);
spinWait.SpinOnce();
}
}
internal void Release()
{
Value = false;
}
public bool Equals(bool other)
{
return ref value.VolatileRead() == other.ToInt32();
}
public override int GetHashCode()
{
return ref value.VolatileRead();
}
public override bool Equals(object other)
{
if (other is bool) {
bool other2 = (bool)other;
return Equals(other2);
}
if (other is AtomicBoolean) {
AtomicBoolean atomicBoolean = (AtomicBoolean)other;
return ref atomicBoolean.value.VolatileRead() == ref value.VolatileRead();
}
return false;
}
public override string ToString()
{
if (!value.ToBoolean())
return bool.FalseString;
return bool.TrueString;
}
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("value", value);
}
}
}