Exemplo n.º 1
0
        /// <summary>
        /// Sets atomically current <see cref="Value"/> by provided setter method
        /// </summary>
        /// <param name="setter">The setter to use</param>
        /// <param name="order">The <see cref="MemoryOrder"/> to achieve</param>
        /// <returns>An updated value</returns>
        public T Set(Func <T, T> setter, MemoryOrder order)
        {
            bool lockTaken = false;

            if (order == MemoryOrder.SeqCst)
            {
                Monitor.Enter(_instanceLock, ref lockTaken);
            }
            try
            {
                T currentValue;
                T tempValue;
                do
                {
                    currentValue = _value;
                    tempValue    = setter(currentValue);
                } while (_value != currentValue || Interlocked.CompareExchange(ref _value, tempValue, currentValue) != currentValue);
                return(currentValue);
            }
            finally
            {
                if (lockTaken)
                {
                    Monitor.Exit(_instanceLock);
                }
            }
        }
        public void AtomicReferenceArray_Should_Copy_Source(MemoryOrder memoryOrder)
        {
            var item1  = new object();
            var item2  = new object();
            var source = new object[] { item1, null, item2, null };
            var ar     = new AtomicReferenceArray <object>(source, memoryOrder);

            Assert.True(source.SequenceEqual(ar));
            Assert.Null(source[1]);
            Assert.Null(ar[1]);

            source[1] = new object();

            Assert.False(source.SequenceEqual(ar));

            Assert.Null(source[3]);
            Assert.Null(ar[3]);
            Assert.Null(source[3]);
            Assert.Null(ar[3]);

            source[3] = new object();

            Assert.NotNull(source[3]);
            Assert.Null(ar[3]);
            Assert.False(source.SequenceEqual(ar));
        }
Exemplo n.º 3
0
 public Config(string description, MemoryOrder memoryOrder, bool useExchange, bool expectedToFail)
 {
     Description    = description;
     MemoryOrder    = memoryOrder;
     UseExchange    = useExchange;
     ExpectedToFail = expectedToFail;
 }
Exemplo n.º 4
0
        /// <summary>
        /// Gets the underlying value with provided <paramref name="order"/>
        /// </summary>
        /// <param name="order">The <see cref="MemoryOrder"/> to achieve</param>
        /// <returns>The underlying value with provided <paramref name="order"/></returns>
        /// <remarks>Providing <see cref="MemoryOrder.Relaxed"/> reads the value as <see cref="MemoryOrder.Acquire"/></remarks>
        public T Load(MemoryOrder order)
        {
            switch (order)
            {
            case MemoryOrder.Relaxed:
                return(this._value);

            case MemoryOrder.Consume:
                throw new NotSupportedException();

            case MemoryOrder.Acquire:
                return(this._value);

            case MemoryOrder.Release:
                throw new InvalidOperationException("Cannot get (load) value with Release semantics");

            case MemoryOrder.AcqRel:
                return(this._value);

            case MemoryOrder.SeqCst:
                return(Volatile.Read(ref _value));

            default:
                throw new ArgumentOutOfRangeException("order");
            }
        }
Exemplo n.º 5
0
        public void AtomicReferenceArray_Store_MemoryOrder_Should_Success(MemoryOrder order)
        {
            var source = Enumerable.Range(0, 3).Select(x => new object()).ToArray();
            var atomicReferenceArray = new AtomicReferenceArray <object>(source.Length, order);

            for (int i = 0; i < atomicReferenceArray.Count; i++)
            {
                atomicReferenceArray.Store(i, source[i], order);
            }

            for (int i = 0; i < atomicReferenceArray.Count; i++)
            {
                Assert.Equal(source[i], atomicReferenceArray.Load(i, order));
            }

            for (int i = 0; i < atomicReferenceArray.Count; i++)
            {
                atomicReferenceArray.Store(i, source[i], order);
            }

            for (int i = 0; i < atomicReferenceArray.Count; i++)
            {
                Assert.Equal(source[i], atomicReferenceArray.Load(i, order));
            }
        }
Exemplo n.º 6
0
            public T Load(MemoryOrder order)
            {
                if (order == MemoryOrder.Consume)
                {
                    throw new NotSupportedException();
                }
                if (order == MemoryOrder.Release)
                {
                    throw new InvalidOperationException("Cannot get (load) value with Release semantics");
                }
                switch (order)
                {
                case MemoryOrder.Relaxed:
                    return(Platform.reinterpret_cast <long, T>(ref AcqRelValue.Int64Value));

                case MemoryOrder.Acquire:
                case MemoryOrder.AcqRel:
                case MemoryOrder.SeqCst:
#if ARM_CPU
                    var tmp = Platform.reinterpret_cast <long, T>(ref AcqRelValue.Int64Value);
                    Platform.MemoryBarrier();
                    return(tmp);
#else
                    long value = Volatile.Read(ref AcqRelValue.Int64Value);
                    return(Platform.reinterpret_cast <long, T>(ref value));
#endif
                default:
                    throw new ArgumentOutOfRangeException("order");
                }
            }
Exemplo n.º 7
0
 public T Load(MemoryOrder order)
 {
     lock (_atomic._instanceLock)
     {
         return(((IAtomic <T>)_atomic).Load(order));
     }
 }
Exemplo n.º 8
0
 public void Store(ref T value, MemoryOrder order)
 {
     lock (_atomic._instanceLock)
     {
         ((IAtomic <T>)_atomic).Store(value, order);
     }
 }
Exemplo n.º 9
0
            public void Store(ref T value, MemoryOrder order)
            {
                switch (order)
                {
                case MemoryOrder.Relaxed:
                    this.AcqRelValue.Int32Value = Platform.reinterpret_cast <T, int>(ref value);
                    break;

                case MemoryOrder.Consume:
                    throw new NotSupportedException();

                case MemoryOrder.Acquire:
                    throw new InvalidOperationException("Cannot set (store) value with Acquire semantics");

                case MemoryOrder.Release:
                case MemoryOrder.AcqRel:
                    this.AcqRelValue.Int32Value = Platform.reinterpret_cast <T, int>(ref value);
                    break;

                case MemoryOrder.SeqCst:
#if ARM_CPU
                    Platform.MemoryBarrier();
                    this.AcqRelValue.Int32Value = Platform.reinterpret_cast <T, int>(ref value);
#else
                    Interlocked.Exchange(ref AcqRelValue.Int32Value, Platform.reinterpret_cast <T, int>(ref value));
#endif
                    break;

                default:
                    throw new ArgumentOutOfRangeException("order");
                }
            }
Exemplo n.º 10
0
        private void RecordStore(T data, MemoryOrder mo, ShadowThread runningThread, bool isReleaseSequence)
        {
            var storeTarget = _history.GetNext();

            storeTarget.RecordStore(runningThread.Id, runningThread.Clock, mo, data);

            bool isAtLeastRelease = mo == MemoryOrder.Release || mo == MemoryOrder.AcquireRelease || mo == MemoryOrder.SequentiallyConsistent;

            // Here 'sourceClock' is the clock that other threads must synchronize with if they read-acquire this data.
            // If this store is a release (or stronger), then those threads must synchronize with the latest clocks that
            // this thread has synchronized with (i.e. the releases it has acquired: runningThread.ReleasesAcquired).
            // Otherwise, if this store is relaxed, then those threads need only synchronize with the latest release fence of this thread
            // (i.e. runningThread.FenceReleasesAcquired)
            var sourceClock = isAtLeastRelease ? runningThread.ReleasesAcquired : runningThread.FenceReleasesAcquired;

            var previous    = _history[_history.CurrentIndex - 1];
            var targetClock = storeTarget.ReleasesToAcquire;

            if (isReleaseSequence)
            {
                targetClock.Assign(previous.ReleasesToAcquire);
                targetClock.Join(sourceClock);
            }
            else
            {
                targetClock.Assign(sourceClock);
            }
        }
Exemplo n.º 11
0
        public T Exchange(T newData, MemoryOrder mo, ShadowThread runningThread)
        {
            var oldData = _history.RecordRMWLoad(mo, runningThread);

            _history.RecordRMWStore(newData, mo, runningThread);
            return(oldData);
        }
Exemplo n.º 12
0
        void IAtomicRef <T> .Store(ref T value, MemoryOrder order)
        {
            switch (order)
            {
            case MemoryOrder.Relaxed:
                Platform.Write(ref _value, ref value);
                break;

            case MemoryOrder.Consume:
                throw new NotSupportedException();

            case MemoryOrder.Acquire:
                throw new InvalidOperationException("Cannot set (store) value with Acquire semantics");

            case MemoryOrder.Release:
            case MemoryOrder.AcqRel:
                Platform.WriteRelease(ref _value, ref value);
                break;

            case MemoryOrder.SeqCst:
                Platform.WriteSeqCst(ref _value, ref value);
                break;

            default:
                throw new ArgumentOutOfRangeException("order");
            }
        }
Exemplo n.º 13
0
        /// <summary>
        /// Creates new instance of <see cref="Atomic{T}"/>
        /// </summary>
        /// <param name="value">The value to store</param>
        /// <param name="order">Affects the way store operation occur. Default is <see cref="MemoryOrder.SeqCst"/> semantics which hurt performance</param>
        /// <param name="align">True to store the underlying value aligned, otherwise False</param>
        public Atomic(T value, MemoryOrder order = MemoryOrder.SeqCst, bool align = false)
        {
            if (!order.IsSpported())
            {
                throw new ArgumentException(string.Format("{0} is not supported", order));
            }

            _storage = GetStorage(order, align);

            if (Intrinsics != null && Intrinsics.Supports <T>())
            {
                _writer = Intrinsics;
            }
            else if (_storage as Atomic <T> == this)
            {
                _writer = this;
            }
            else if (_storage.Supports <T>())
            {
                _writer = _storage;
            }
            else
            {
                throw new NotSupportedException(string.Format("{0} type is not supported", typeof(T)));
            }

            if (object.ReferenceEquals(_storage, this) || _storage is LockBasedAtomic)
            {
                _instanceLock = new object();
            }

            _order         = order;
            _storage.Value = value;
        }
Exemplo n.º 14
0
 public Config(string description, MemoryOrder storeMemoryOrder, MemoryOrder loadMemoryOrder, bool expectedToFail)
 {
     Description      = description;
     StoreMemoryOrder = storeMemoryOrder;
     LoadMemoryOrder  = loadMemoryOrder;
     ExpectedToFail   = expectedToFail;
 }
Exemplo n.º 15
0
        public void Fence(MemoryOrder mo, VectorClock sequentiallyConsistentFence)
        {
            switch (mo) // TODO: Should this be done in Fence.Insert ?
            {
            case MemoryOrder.Acquire:
                AcquireFence();
                break;

            case MemoryOrder.Release:
                ReleaseFence();
                break;

            case MemoryOrder.AcquireRelease:
                AcquireFence();
                ReleaseFence();
                break;

            case MemoryOrder.SequentiallyConsistent:
                AcquireFence();
                sequentiallyConsistentFence.Join(ReleasesAcquired);
                ReleasesAcquired.Assign(sequentiallyConsistentFence);
                ReleaseFence();
                break;

            default:
                throw new Exception($"Unsupported memory fence order {mo}");
            }
        }
Exemplo n.º 16
0
        /// <summary>
        /// Gets an element at <paramref name="index"/> with provided <paramref name="order"/>
        /// </summary>
        /// <param name="index">The index of element from which to load</param>
        /// <param name="order">The <see cref="MemoryOrder"/> to achieve</param>
        /// <returns>The underlying value with provided <paramref name="order"/></returns>
        public long Load(int index, MemoryOrder order)
        {
            if (order == MemoryOrder.Consume)
            {
                throw new NotSupportedException();
            }
            if (order == MemoryOrder.Release)
            {
                throw new InvalidOperationException("Cannot get (load) value with Release semantics");
            }
            switch (order)
            {
            case MemoryOrder.Relaxed:
                return(this._data[index]);

            case MemoryOrder.Acquire:
            case MemoryOrder.AcqRel:
            case MemoryOrder.SeqCst:
#if ARM_CPU
                var tmp = this._data[index];
                Platform.MemoryBarrier();
                return(tmp);
#else
                return(Volatile.Read(ref this._data[index]));
#endif
            default:
                throw new ArgumentOutOfRangeException("order");
            }
        }
        public void AtomicLongArray_Should_Copy_Source(MemoryOrder memoryOrder)
        {
            var item1  = 1L;
            var item2  = 2L;
            var source = new [] { item1, 0, item2, 0 };
            var ar     = new AtomicLongArray(source, memoryOrder);

            Assert.True(source.SequenceEqual(ar));
            Assert.Equal(0, source[1]);
            Assert.Equal(0, ar[1]);

            source[1] = -1;

            Assert.False(source.SequenceEqual(ar));

            Assert.Equal(0, source[3]);
            Assert.Equal(0, ar[3]);
            Assert.Equal(0, source[3]);
            Assert.Equal(0, ar[3]);

            source[3] = -1;

            Assert.Equal(-1, source[3]);
            Assert.Equal(0, ar[3]);
            Assert.False(source.SequenceEqual(ar));
        }
Exemplo n.º 18
0
        /// <summary>
        /// Sets the underlying value with provided <paramref name="order"/>
        /// </summary>
        /// <param name="value">The value to store</param>
        /// <param name="order">The <see cref="MemoryOrder"/> to achieve</param>
        /// <remarks>Providing <see cref="MemoryOrder.Relaxed"/> writes the value as <see cref="MemoryOrder.Acquire"/></remarks>
        public void Store(T value, MemoryOrder order)
        {
            switch (order)
            {
            case MemoryOrder.Relaxed:
                this._value = value;
                break;

            case MemoryOrder.Consume:
                throw new NotSupportedException();

            case MemoryOrder.Acquire:
                throw new InvalidOperationException("Cannot set (store) value with Acquire semantics");

            case MemoryOrder.Release:
            case MemoryOrder.AcqRel:
                // ARM JIT should emit DMB
                this._value = value;
                break;

            case MemoryOrder.SeqCst:
                Interlocked.Exchange(ref _value, value);
                break;

            default:
                throw new ArgumentOutOfRangeException("order");
            }
        }
Exemplo n.º 19
0
        /// <summary>
        /// Gets the underlying value with provided <paramref name="order"/>
        /// </summary>
        /// <param name="order">The <see cref="MemoryOrder"/> to achieve</param>
        /// <returns>The underlying value with provided <paramref name="order"/></returns>
        /// <remarks>Providing <see cref="MemoryOrder.Relaxed"/> reads the value as <see cref="MemoryOrder.Acquire"/></remarks>
        public T Load(MemoryOrder order)
        {
            switch (order)
            {
            case MemoryOrder.Relaxed:
                return(this._value);

            case MemoryOrder.Consume:
                throw new NotSupportedException();

            case MemoryOrder.Acquire:
                return(this._value);

            case MemoryOrder.Release:
                throw new InvalidOperationException("Cannot get (load) value with Release semantics");

            case MemoryOrder.AcqRel:
                return(this._value);

            case MemoryOrder.SeqCst:
#if ARM_CPU
                var tmp = this._value;
                Platform.MemoryBarrier();
                return(tmp);
#else
                return(this._value);
#endif
            default:
                throw new ArgumentOutOfRangeException("order");
            }
        }
        /// <summary>
        /// Sets atomically current <see cref="Value"/> by provided setter method
        /// </summary>
        /// <param name="index">The index of element at which to store</param>
        /// <param name="setter">The setter to use</param>
        /// <param name="data">Any arbitrary value to be passed to <paramref name="setter"/></param>
        /// <param name="order">The <see cref="MemoryOrder"/> to achieve</param>
        /// <returns>An updated value</returns>
        public T Set <TData>(int index, Func <T, TData, T> setter, TData data, MemoryOrder order)
        {
            bool lockTaken = false;

            if (order == MemoryOrder.SeqCst)
            {
                Monitor.Enter(_instanceLock, ref lockTaken);
            }
            try
            {
                T currentValue;
                T tempValue;
                do
                {
                    currentValue = _data[index];
                    tempValue    = setter(currentValue, data);
                } while (_data[index] != currentValue || Interlocked.CompareExchange(ref _data[index], tempValue, currentValue) != currentValue);
                return(currentValue);
            }
            finally
            {
                if (lockTaken)
                {
                    Monitor.Exit(_instanceLock);
                }
            }
        }
        /// <summary>
        /// Sets an element at <paramref name="index"/> with provided <paramref name="order"/>
        /// </summary>
        /// <param name="index">The index of element at which to store</param>
        /// <param name="value">The value to store</param>
        /// <param name="order">The <see cref="MemoryOrder"/> to achieve</param>
        /// <remarks>Providing <see cref="MemoryOrder.Relaxed"/> writes the value as <see cref="MemoryOrder.Acquire"/></remarks>
        public void Store(int index, T value, MemoryOrder order)
        {
            switch (order)
            {
            case MemoryOrder.Relaxed:
                this._data[index] = value;
                break;

            case MemoryOrder.Consume:
                throw new NotSupportedException();

            case MemoryOrder.Acquire:
                throw new InvalidOperationException("Cannot set (store) value with Acquire semantics");

            case MemoryOrder.Release:
            case MemoryOrder.AcqRel:
#if ARM_CPU
                Platform.MemoryBarrier();
#endif
                this._data[index] = value;
                break;

            case MemoryOrder.SeqCst:
                Interlocked.Exchange(ref _data[index], value);
                break;

            default:
                throw new ArgumentOutOfRangeException("order");
            }
        }
Exemplo n.º 22
0
        public T Load(MemoryOrder mo, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
        {
            Preamble();
            var result = _memoryOrdered.Load(mo, TE.RunningThread);

            TE.RecordEvent(memberName, sourceFilePath, sourceLineNumber, $"Load ({mo}) <-- {Str(result)}");
            return(result);
        }
Exemplo n.º 23
0
        /// <summary>
        /// Creates new instance of <see cref="AtomicLong"/>
        /// </summary>
        /// <param name="initialValue">The value to store</param>
        /// <param name="order">Affects the way store operation occur. Load operations are always use <see cref="MemoryOrder.Acquire"/> semantics</param>
        public AtomicReference(T initialValue, MemoryOrder order = MemoryOrder.AcqRel)
        {
            order.ThrowIfNotSupported();

            _instanceLock = order == MemoryOrder.SeqCst ? new object() : null;
            _order        = order;
            this._value   = initialValue;
        }
Exemplo n.º 24
0
        public T Exchange(T newData, MemoryOrder mo, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
        {
            Preamble();
            var oldData = _memoryOrdered.Exchange(newData, mo, TE.RunningThread);

            TE.RecordEvent(memberName, sourceFilePath, sourceLineNumber, $"Exchange ({mo}): --> {Str(newData)} ({Str(oldData)})");
            return(oldData);
        }
Exemplo n.º 25
0
        public static void Insert(MemoryOrder mo, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
        {
            TE.MaybeSwitch();
            var runningThread = TE.RunningThread;

            runningThread.Fence(mo, TE.SequentiallyConsistentFence);
            TE.RecordEvent(memberName, sourceFilePath, sourceLineNumber, $"Fence: {mo}");
        }
Exemplo n.º 26
0
        public int Decrement(MemoryOrder mo, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
        {
            Preamble();
            var newValue = _memoryOrdered.CurrentValue - 1;
            var oldValue = _memoryOrdered.Exchange(newValue, mo, TE.RunningThread);

            TE.RecordEvent(memberName, sourceFilePath, sourceLineNumber, $"Decrement ({mo}): --> {Str(newValue)} ({Str(oldValue)})");
            return(newValue);
        }
Exemplo n.º 27
0
        /// <summary>
        /// Creates new instance of <see cref="Atomic{T}"/>
        /// </summary>
        /// <param name="value">The value to store</param>
        /// <param name="order">Affects the way store operation occur. Default is <see cref="MemoryOrder.SeqCst"/> semantics which hurt performance</param>
        /// <param name="align">True to store the underlying value aligned, otherwise False</param>
        public Atomic(T value, MemoryOrder order = MemoryOrder.SeqCst, bool align = false)
        {
            order.ThrowIfNotSupported();

            _storage = GetStorage(order, align);

            _order         = order;
            _storage.Value = value;
        }
Exemplo n.º 28
0
 public Config(string description, MemoryOrder enqueueMemoryOrder, MemoryOrder dequeueMemoryOrder, bool useEnqueueReleaseFence, bool useDequeueAcquireFence, bool expectedToFail)
 {
     Description            = description;
     EnqueueMemoryOrder     = enqueueMemoryOrder;
     DequeueMemoryOrder     = dequeueMemoryOrder;
     UseEnqueueReleaseFence = useEnqueueReleaseFence;
     UseDequeueAcquireFence = useDequeueAcquireFence;
     ExpectedToFail         = expectedToFail;
 }
Exemplo n.º 29
0
        /// <summary>
        /// Creates new instance of <see cref="AtomicLong"/>
        /// </summary>
        /// <param name="value">The value to store</param>
        /// <param name="order">Affects the way store operation occur. Load operations are always use <see cref="MemoryOrder.Acquire"/> semantics</param>
        /// <param name="align">True to store the underlying value aligned, otherwise False</param>
        public AtomicLong(long value, MemoryOrder order = MemoryOrder.SeqCst, bool align = false)
        {
            if (!order.IsSpported())
            {
                throw new ArgumentException(string.Format("{0} is not supported", order));
            }

            _order        = order;
            this._storage = BoxedInt64.Create(value, align);
        }
Exemplo n.º 30
0
        /// <summary>
        /// Creates new instance of <see cref="AtomicLong"/>
        /// </summary>
        /// <param name="initialValue">The value to store</param>
        /// <param name="order">Affects the way store operation occur. Load operations are always use <see cref="MemoryOrder.Acquire"/> semantics</param>
        public AtomicReference(T initialValue, MemoryOrder order = MemoryOrder.AcqRel)
        {
            if (!order.IsSpported())
            {
                throw new ArgumentException(string.Format("{0} is not supported", order));
            }

            _order      = order;
            this._value = initialValue;
        }
        public void AtomicIntegerArray_Load_Acquire_Should_Success(MemoryOrder order)
        {
            var atomicIntegerArray = new AtomicIntegerArray(new int[3], order);

            for (int i = 0; i < atomicIntegerArray.Count; i++)
            {
                Assert.Equal(0, atomicIntegerArray.Load(i, MemoryOrder.Acquire));
                atomicIntegerArray.Store(i, i, MemoryOrder.Release);
            }

            for (int i = 0; i < atomicIntegerArray.Count; i++)
            {
                Assert.Equal(i, atomicIntegerArray.Load(i, MemoryOrder.Acquire));
            }
        }
        public void AtomicIntegerArray_Indexer_MemoryOrder_Should_Success(MemoryOrder order)
        {
            var atomicIntegerArray = new AtomicIntegerArray(new int[3], order);

            for (int i = 0; i < atomicIntegerArray.Count; i++)
            {
                Assert.Equal(0, atomicIntegerArray[i]);
                atomicIntegerArray[i] = i;
            }

            for (int i = 0; i < atomicIntegerArray.Count; i++)
            {
                Assert.Equal(i, atomicIntegerArray[i]);
            }
        }
 public void AtomicReferenceArray_Ctor_Should_Track_Length(MemoryOrder order)
 {
     Assert.Throws<ArgumentException>(() => new AtomicReferenceArray<object>(-1, order));
     GC.KeepAlive(new AtomicReferenceArray<object>(0, order));
     GC.KeepAlive(new AtomicReferenceArray<object>(1, order));
 }
 public void AtomicIntegerArray_Store_Should_Success(int initialValue, int storeValue, MemoryOrder order)
 {
     var atomicIntegerArray = new AtomicIntegerArray(new int[] {initialValue}, MemoryOrder.Relaxed);
     atomicIntegerArray.Store(0, storeValue, order);
     Assert.Equal(storeValue, atomicIntegerArray[0]);
 }
 public void AtomicIntegerArray_IsLockFree_Should_Success(int initialValue, MemoryOrder order, bool isLockFree)
 {
     var atomicIntegerArray = new AtomicIntegerArray(new[] { initialValue }, order);
     Assert.Equal(atomicIntegerArray.IsLockFree, isLockFree);
 }
 public void AtomicLong_IsLockFree_Should_Success(long initialValue, MemoryOrder order, bool isLockFree)
 {
     var atomicLong = new AtomicLong(initialValue, order);
     Assert.Equal(atomicLong.IsLockFree, isLockFree);
 }
 public void AtomicLong_Store_Should_Success(long initialValue, long storeValue, MemoryOrder order)
 {
     var atomicLong = new AtomicLong(initialValue, MemoryOrder.Relaxed);
     atomicLong.Store(storeValue, order);
     Assert.Equal(storeValue, atomicLong.Value);
 }
        public void AtomicIntegerArray_Decrement_Should_Success(MemoryOrder memoryOrder)
        {
            var ar = new AtomicIntegerArray(10, memoryOrder);
            foreach (var o in ar)
            {
                Assert.Equal(0, o);
            }

            for (int i = 0; i < ar.Count; i++)
            {
                Assert.Equal(0, ar[i]);
            }

            for (int i = 0; i < ar.Count; i++)
            {
                ar[i] = i;
                ar.DecrementAt(i);
            }

            Assert.Equal(Enumerable.Range(-1, 10), ar);
        }
        public void AtomicIntegerArray_Store_MemoryOrder_Should_Success(MemoryOrder order)
        {
            var atomicIntegerArray = new AtomicIntegerArray(new int[3], order);

            for (int i = 0; i < atomicIntegerArray.Count; i++)
            {
                atomicIntegerArray.Store(i, i, order);
            }

            for (int i = 0; i < atomicIntegerArray.Count; i++)
            {
                Assert.Equal(i, atomicIntegerArray.Load(i, order));
            }

            for (int i = 0; i < atomicIntegerArray.Count; i++)
            {
                atomicIntegerArray.Store(i, i, order);
            }

            for (int i = 0; i < atomicIntegerArray.Count; i++)
            {
                Assert.Equal(i, atomicIntegerArray.Load(i, order));
            }
        }
 public void AtomicInteger_IsLockFree_Should_Success(int initialValue, MemoryOrder order, bool isLockFree)
 {
     var atomicInteger = new AtomicInteger(initialValue, order);
     Assert.Equal(atomicInteger.IsLockFree, isLockFree);
 }
 public void AtomicInteger_Store_Should_Success(int initialValue, int storeValue, MemoryOrder order)
 {
     var atomicInteger = new AtomicInteger(initialValue, order);
     atomicInteger.Store(storeValue, order);
     Assert.Equal(storeValue, atomicInteger.Value);
 }
 public void AtomicIntegerArray_With_Null_Source_Should_Fail(MemoryOrder memoryOrder)
 {
     Assert.Throws<ArgumentNullException>(() => new AtomicIntegerArray(null, memoryOrder));
 }
 public void AtomicIntegerArray_Ctor_Should_Track_Length(MemoryOrder order)
 {
     Assert.Throws<ArgumentException>(() => new AtomicIntegerArray(-1, order));
     GC.KeepAlive(new AtomicIntegerArray(0, order));
     GC.KeepAlive(new AtomicIntegerArray(1, order));
 }
        public void AtomicIntegerArray_Items_With_Length_Ctor_Should_Be_Null(int length, MemoryOrder memoryOrder)
        {
            var ar = new AtomicIntegerArray(length, memoryOrder);
            foreach (var o in ar)
            {
                Assert.Equal(0, o);
            }

            for (int i = 0; i < ar.Count; i++)
            {
                Assert.Equal(0, ar[i]);
            }
        }
        public void AtomicIntegerArray_Should_Copy_Source(MemoryOrder memoryOrder)
        {
            var item1 = 1;
            var item2 = 2;
            var source = new [] { item1, 0, item2, 0};
            var ar = new AtomicIntegerArray(source, memoryOrder);
            
            Assert.True(source.SequenceEqual(ar));
            Assert.Equal(0, source[1]);
            Assert.Equal(0, ar[1]);
            
            source[1] = -1;

            Assert.False(source.SequenceEqual(ar));

            Assert.Equal(0, source[3]);
            Assert.Equal(0, ar[3]);
            Assert.Equal(0, source[3]);
            Assert.Equal(0, ar[3]);

            source[3] = -1;

            Assert.Equal(-1, source[3]);
            Assert.Equal(0, ar[3]);
            Assert.False(source.SequenceEqual(ar));
        }
        public void AtomicReferenceArray_Should_Copy_Source(MemoryOrder memoryOrder)
        {
            var item1 = new object();
            var item2 = new object();
            var source = new object[] { item1, null, item2, null};
            var ar = new AtomicReferenceArray<object>(source, memoryOrder);
            
            Assert.True(source.SequenceEqual(ar));
            Assert.Null(source[1]);
            Assert.Null(ar[1]);
            
            source[1] = new object();

            Assert.False(source.SequenceEqual(ar));

            Assert.Null(source[3]);
            Assert.Null(ar[3]);
            Assert.Null(source[3]);
            Assert.Null(ar[3]);

            source[3] = new object();

            Assert.NotNull(source[3]);
            Assert.Null(ar[3]);
            Assert.False(source.SequenceEqual(ar));
        }
 public void AtomicBoolean_IsLockFree_Should_Success(bool initialValue, MemoryOrder order, bool isLockFree)
 {
     var atomicBoolean = new AtomicBoolean(initialValue, order);
     Assert.Equal(atomicBoolean.IsLockFree, isLockFree);
 }
        public void AtomicReferenceArray_Items_With_Length_Ctor_Should_Be_Null(int length, MemoryOrder memoryOrder)
        {
            var ar = new AtomicReferenceArray<object>(length, memoryOrder);
            foreach (var o in ar)
            {
                Assert.Null(o);
            }

            for (int i = 0; i < ar.Count; i++)
            {
                Assert.Null(ar[i]);
            }
        }
 public void AtomicBoolean_Store_Should_Success(bool initialValue, bool storeValue, MemoryOrder order)
 {
     var atomicBoolean = new AtomicBoolean(initialValue, order);
     atomicBoolean.Store(storeValue, order);
     Assert.Equal(storeValue, atomicBoolean.Value);
 }
 public void AtomicReferenceArray_With_Null_Source_Should_Fail(MemoryOrder memoryOrder)
 {
     Assert.Throws<ArgumentNullException>(() => new AtomicReferenceArray<object>(null, memoryOrder));
 }