public void AtomicLongArray_Store_Should_Success(int initialValue, int storeValue, MemoryOrder order) { var atomicLongArray = new AtomicLongArray(new long[] { initialValue }, MemoryOrder.Relaxed); atomicLongArray.Store(0, storeValue, order); Assert.Equal(storeValue, atomicLongArray[0]); }
public void long_array_is_correct_with_concurrency(int total, int threadCount) { var array = new AtomicLongArray(100); var thread = new List <Thread>(); for (var i = 0; i < threadCount; i++) { thread.Add(new Thread(() => { int index = 0; for (long j = 0; j < total; j++) { array.Increment(index++); if (index == array.Length) { index = 0; } } })); } thread.ForEach(t => t.Start()); thread.ForEach(t => t.Join()); long sum = 0; for (int i = 0; i < array.Length; i++) { sum += array.GetValue(i); } sum.Should().Be(total * threadCount); }
public virtual void ShouldKeepHighest() { // GIVEN Race race = new Race(); HighestId highestId = new HighestId(); int threads = Runtime.Runtime.availableProcessors(); System.Threading.CountdownEvent latch = new System.Threading.CountdownEvent(threads); AtomicLongArray highestIds = new AtomicLongArray(threads); for (int c = 0; c < threads; c++) { int cc = c; race.AddContestant(new RunnableAnonymousInnerClass(this, highestId, latch, highestIds, cc)); } race.WithEndCondition(() => latch.CurrentCount == 0); // WHEN race.Go(); long highest = 0; for (int i = 0; i < threads; i++) { highest = max(highest, highestIds.get(i)); } assertEquals(highest, highestId.Get()); }
/** * Construct a ConcurrentHistogram given the Lowest and Highest values to be tracked and a number of significant * decimal digits. Providing a lowestDiscernibleValue is useful is situations where the units used * for the histogram's values are much smaller that the minimal accuracy required. E.g. when tracking * time values stated in nanosecond units, where the minimal accuracy required is a microsecond, the * proper value for lowestDiscernibleValue would be 1000. * * @param lowestDiscernibleValue The lowest value that can be tracked (distinguished from 0) by the histogram. * Must be a positive integer that is {@literal >=} 1. May be internally rounded * down to nearest power of 2. * @param highestTrackableValue The highest value to be tracked by the histogram. Must be a positive * integer that is {@literal >=} (2 * lowestDiscernibleValue). * @param numberOfSignificantValueDigits Specifies the precision to use. This is the number of significant * decimal digits to which the histogram will maintain value resolution * and separation. Must be a non-negative integer between 0 and 5. */ public ConcurrentHistogram(long lowestDiscernibleValue, long highestTrackableValue, int numberOfSignificantValueDigits) : base(lowestDiscernibleValue, highestTrackableValue, numberOfSignificantValueDigits, wordSizeInBytes: sizeof(long), allocateCountsArray: false, autoResize: true) { activeCounts = new AtomicLongArray(countsArrayLength); activeCountsNormalizingIndexOffset = 0; inactiveCounts = new AtomicLongArray(countsArrayLength); inactiveCountsNormalizingIndexOffset = 0; }
public void AtomicLongArray_Load_Should_Fail() { var atomicLongArray = new AtomicLongArray(new [] { 100L }); Assert.Throws <InvalidOperationException>(() => atomicLongArray.Load(0, MemoryOrder.Release)); #pragma warning disable 618 Assert.Throws <NotSupportedException>(() => atomicLongArray.Load(0, MemoryOrder.Consume)); #pragma warning restore 618 }
public RunnableAnonymousInnerClass(HighestIdTest outerInstance, [email protected] highestId, System.Threading.CountdownEvent latch, AtomicLongArray highestIds, int cc) { this.outerInstance = outerInstance; this._highestId = highestId; this._latch = latch; this._highestIds = highestIds; this._cc = cc; random = ThreadLocalRandom.current(); }
public void AtomicLongArray_Store_Should_Fail() { var atomicLongArray = new AtomicLongArray(new [] { 100L }); Assert.Throws <InvalidOperationException>(() => atomicLongArray.Store(0, int.MinValue, MemoryOrder.Acquire)); #pragma warning disable 618 Assert.Throws <NotSupportedException>(() => atomicLongArray.Store(0, int.MinValue, MemoryOrder.Consume)); #pragma warning restore 618 }
public void AtomicLongArray_Load_Should_Success() { var atomicLongArray = new AtomicLongArray(new [] { 100L }); Assert.Equal(100, atomicLongArray.Load(0, MemoryOrder.Relaxed)); Assert.Equal(100, atomicLongArray.Load(0, MemoryOrder.Acquire)); Assert.Equal(100, atomicLongArray.Load(0, MemoryOrder.AcqRel)); Assert.Equal(100, atomicLongArray.Load(0, MemoryOrder.SeqCst)); }
public void Negetive_length_throws() { Action setupAction = () => { var unused = new AtomicLongArray(-1); }; setupAction.ShouldThrow <ArgumentException>(); }
public void Can_estimate_size() { var list = new ReadOnlyCollection <long>(new List <long> { 1, 2, 3 }); var array = new AtomicLongArray(list); AtomicLongArray.GetEstimatedFootprintInBytes(array).Should().NotBe(0); }
/** * Construct a histogram with the same range settings as a given source histogram, * duplicating the source's start/end timestamps (but NOT it's contents) * @param source The source histogram to duplicate */ public ConcurrentHistogram(AbstractHistogram source) : base(source, false) { activeCounts = new AtomicLongArray(countsArrayLength); activeCountsNormalizingIndexOffset = 0; inactiveCounts = new AtomicLongArray(countsArrayLength); inactiveCountsNormalizingIndexOffset = 0; }
public void Can_get_and_add() { var array = new AtomicLongArray(1); array.Add(0, 1); var value = array.GetAndAdd(0, 2); value.Should().Be(1); array.GetValue(0).Should().Be(3); }
public void Can_get_and_increment() { var array = new AtomicLongArray(1); array.Add(0, 10); var value = array.GetAndIncrement(0, 2); value.Should().Be(10); array.GetValue(0).Should().Be(12); }
public void AtomicLongArray_CanIncrement() { var array = new AtomicLongArray(10); array.SetValue(1, 3); array.Increment(1).Should().Be(4); array.Increment(1, 4).Should().Be(8); array.GetAndIncrement(1).Should().Be(8); array.GetValue(1).Should().Be(9); }
public void Can_instiate_from_list() { var list = new ReadOnlyCollection <long>(new List <long> { 1, 2, 3 }); var array = new AtomicLongArray(list); array.Length.Should().Be(3); array.GetValue(0).Should().Be(1); array.GetValue(1).Should().Be(2); array.GetValue(2).Should().Be(3); }
public void AtomicLongArray_CanDecrement() { var array = new AtomicLongArray(10); array.SetValue(1, 10); array.Decrement(1).Should().Be(9); array.Decrement(1, 4).Should().Be(5); array.GetAndDecrement(1).Should().Be(5); array.GetValue(1).Should().Be(4); }
public void AtomicLongArray_CanCompareAndSet() { var array = new AtomicLongArray(10); array.SetValue(1, 10); array.CompareAndSwap(1, 5, 11).Should().Be(false); array.GetValue(1).Should().Be(10); array.CompareAndSwap(1, 10, 11).Should().Be(true); array.GetValue(1).Should().Be(11); }
public void can_compare_and_set() { var array = new AtomicLongArray(10); array.SetValue(1, 10); array.CompareAndSwap(1, 5, 11).Should().Be(false); array.GetValue(1).Should().Be(10); array.CompareAndSwap(1, 10, 11).Should().Be(true); array.GetValue(1).Should().Be(11); }
public void can_decrement() { var array = new AtomicLongArray(10); array.SetValue(1, 10); array.Decrement(1).Should().Be(9); array.Decrement(1, 4).Should().Be(5); array.GetAndDecrement(1).Should().Be(5); array.GetValue(1).Should().Be(4); }
public void can_increment() { var array = new AtomicLongArray(10); array.SetValue(1, 3); array.Increment(1).Should().Be(4); array.Increment(1, 4).Should().Be(8); array.GetAndIncrement(1).Should().Be(8); array.GetValue(1).Should().Be(9); }
public void AtomicLongArray_CanGetAndSetValue() { var array = new AtomicLongArray(10); array.SetValue(1, 3); array.GetValue(1).Should().Be(3); array.GetAndSet(1, 4).Should().Be(3); array.GetValue(1).Should().Be(4); array.GetAndReset(1).Should().Be(4); array.GetValue(1).Should().Be(0); }
public void can_get_and_set_value() { var array = new AtomicLongArray(10); array.SetValue(1, 3); array.GetValue(1).Should().Be(3); array.GetAndSet(1, 4).Should().Be(3); array.GetValue(1).Should().Be(4); array.GetAndReset(1).Should().Be(4); array.GetValue(1).Should().Be(0); }
public void AtomicLongArray_Items_With_Length_Ctor_Should_Be_Null(int length, MemoryOrder memoryOrder) { var ar = new AtomicLongArray(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 AtomicLongArray_Indexer_MemoryOrder_Should_Success(MemoryOrder order) { var atomicLongArray = new AtomicLongArray(new long[3], order); for (int i = 0; i < atomicLongArray.Count; i++) { Assert.Equal(0, atomicLongArray[i]); atomicLongArray[i] = i; } for (int i = 0; i < atomicLongArray.Count; i++) { Assert.Equal(i, atomicLongArray[i]); } }
public void AtomicLongArray_Load_Acquire_Should_Success(MemoryOrder order) { var atomicLongArray = new AtomicLongArray(new long[3], order); for (int i = 0; i < atomicLongArray.Count; i++) { Assert.Equal(0, atomicLongArray.Load(i, MemoryOrder.Acquire)); atomicLongArray.Store(i, i, MemoryOrder.Release); } for (int i = 0; i < atomicLongArray.Count; i++) { Assert.Equal(i, atomicLongArray.Load(i, MemoryOrder.Acquire)); } }
public void AtomicLongArray_Decrement_Should_Success(MemoryOrder memoryOrder) { var ar = new AtomicLongArray(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).Select(x => (long)x), ar); }
public void AtomicLongArray_Store_MemoryOrder_Should_Success(MemoryOrder order) { var atomicLongArray = new AtomicLongArray(new long[3], order); for (int i = 0; i < atomicLongArray.Count; i++) { atomicLongArray.Store(i, i, order); } for (int i = 0; i < atomicLongArray.Count; i++) { Assert.Equal(i, atomicLongArray.Load(i, order)); } for (int i = 0; i < atomicLongArray.Count; i++) { atomicLongArray.Store(i, i, order); } for (int i = 0; i < atomicLongArray.Count; i++) { Assert.Equal(i, atomicLongArray.Load(i, order)); } }
internal protected override void resize(long newHighestTrackableValue) { try { wrp.ReaderLock(); Debug.Assert(countsArrayLength == activeCounts.Length); Debug.Assert(countsArrayLength == inactiveCounts.Length); int newArrayLength = determineArrayLengthNeeded(newHighestTrackableValue); int countsDelta = newArrayLength - countsArrayLength; if (countsDelta <= 0) { // This resize need was already covered by a concurrent resize op. return; } int oldNormalizedZeroIndex = NormalizeIndex(0, inactiveCountsNormalizingIndexOffset, inactiveCounts.Length); // Resize the current inactiveCounts: AtomicLongArray oldInactiveCounts = inactiveCounts; inactiveCounts = new AtomicLongArray(newArrayLength); // Copy inactive contents to newly sized inactiveCounts: for (int i = 0; i < oldInactiveCounts.Length; i++) { inactiveCounts.SetValue(i, oldInactiveCounts.GetValue(i)); } if (oldNormalizedZeroIndex != 0) { // We need to shift the stuff from the zero index and up to the end of the array: int newNormalizedZeroIndex = oldNormalizedZeroIndex + countsDelta; int lengthToCopy = (newArrayLength - countsDelta) - oldNormalizedZeroIndex; int src, dst; for (src = oldNormalizedZeroIndex, dst = newNormalizedZeroIndex; src < oldNormalizedZeroIndex + lengthToCopy; src++, dst++) { inactiveCounts.SetValue(dst, oldInactiveCounts.GetValue(src)); } } // switch active and inactive: var tmp = activeCounts; var tmpOffset = activeCountsNormalizingIndexOffset; activeCounts = inactiveCounts; activeCountsNormalizingIndexOffset = inactiveCountsNormalizingIndexOffset; inactiveCounts = tmp; inactiveCountsNormalizingIndexOffset = tmpOffset; wrp.FlipPhase(); // Resize the newly inactiveCounts: oldInactiveCounts = inactiveCounts; inactiveCounts = new AtomicLongArray(newArrayLength); // Copy inactive contents to newly sized inactiveCounts: for (int i = 0; i < oldInactiveCounts.Length; i++) { inactiveCounts.SetValue(i, oldInactiveCounts.GetValue(i)); } if (oldNormalizedZeroIndex != 0) { // We need to shift the stuff from the zero index and up to the end of the array: int newNormalizedZeroIndex = oldNormalizedZeroIndex + countsDelta; int lengthToCopy = (newArrayLength - countsDelta) - oldNormalizedZeroIndex; int src, dst; for (src = oldNormalizedZeroIndex, dst = newNormalizedZeroIndex; src < oldNormalizedZeroIndex + lengthToCopy; src++, dst++) { inactiveCounts.SetValue(dst, oldInactiveCounts.GetValue(src)); } } // switch active and inactive again: tmp = activeCounts; activeCounts = inactiveCounts; inactiveCounts = tmp; wrp.FlipPhase(); // At this point, both active and inactive have been safely resized, // and the switch in each was done without any writers modifying it in flight. // We resized things. We can now make the historam establish size accordingly for future recordings: establishSize(newHighestTrackableValue); Debug.Assert(countsArrayLength == activeCounts.Length); Debug.Assert(countsArrayLength == inactiveCounts.Length); } finally { wrp.ReaderUnlock(); } }
private void setNormalizingIndexOffset( int normalizingIndexOffset, int shiftedAmount, bool lowestHalfBucketPopulated) { try { wrp.ReaderLock(); Debug.Assert(countsArrayLength == activeCounts.Length); Debug.Assert(countsArrayLength == inactiveCounts.Length); if (normalizingIndexOffset == activeCountsNormalizingIndexOffset) { return; // Nothing to do. } // Save and clear the inactive 0 value count: int zeroIndex = NormalizeIndex(0, inactiveCountsNormalizingIndexOffset, inactiveCounts.Length); long inactiveZeroValueCount = inactiveCounts.GetValue(zeroIndex); inactiveCounts.SetValue(zeroIndex, 0); // Change the normalizingIndexOffset on the current inactiveCounts: inactiveCountsNormalizingIndexOffset = normalizingIndexOffset; //inactiveCounts.setNormalizingIndexOffset(normalizingIndexOffset); // Handle the inactive lowest half bucket: if ((shiftedAmount > 0) && lowestHalfBucketPopulated) { shiftLowestInactiveHalfBucketContentsLeft(shiftedAmount); } // Restore the inactive 0 value count: zeroIndex = NormalizeIndex(0, inactiveCountsNormalizingIndexOffset, inactiveCounts.Length); inactiveCounts.SetValue(zeroIndex, inactiveZeroValueCount); // switch active and inactive: var tmp = activeCounts; var tmpOffset = activeCountsNormalizingIndexOffset; activeCounts = inactiveCounts; activeCountsNormalizingIndexOffset = inactiveCountsNormalizingIndexOffset; inactiveCounts = tmp; inactiveCountsNormalizingIndexOffset = tmpOffset; wrp.FlipPhase(); // Save and clear the newly inactive 0 value count: zeroIndex = NormalizeIndex(0, inactiveCountsNormalizingIndexOffset, inactiveCounts.Length); inactiveZeroValueCount = inactiveCounts.GetValue(zeroIndex); inactiveCounts.SetValue(zeroIndex, 0); // Change the normalizingIndexOffset on the newly inactiveCounts: inactiveCountsNormalizingIndexOffset = normalizingIndexOffset; //inactiveCounts.setNormalizingIndexOffset(normalizingIndexOffset); // Handle the newly inactive lowest half bucket: if ((shiftedAmount > 0) && lowestHalfBucketPopulated) { shiftLowestInactiveHalfBucketContentsLeft(shiftedAmount); } // Restore the newly inactive 0 value count: zeroIndex = NormalizeIndex(0, inactiveCountsNormalizingIndexOffset, inactiveCounts.Length); inactiveCounts.SetValue(zeroIndex, inactiveZeroValueCount); // switch active and inactive again: tmp = activeCounts; tmpOffset = activeCountsNormalizingIndexOffset; activeCounts = inactiveCounts; activeCountsNormalizingIndexOffset = inactiveCountsNormalizingIndexOffset; inactiveCounts = tmp; inactiveCountsNormalizingIndexOffset = tmpOffset; wrp.FlipPhase(); // At this point, both active and inactive have normalizingIndexOffset safely set, // and the switch in each was done without any writers using the wrong value in flight. } finally { wrp.ReaderUnlock(); } }
public void can_create_array() { var array = new AtomicLongArray(10); array.Length.Should().Be(10); }
/// <summary> /// Construct a <see cref="LongConcurrentHistogram"/> given the lowest and highest values to be tracked and a number of significant decimal digits. /// </summary> /// <param name="instanceId">An identifier for this instance.</param> /// <param name="lowestTrackableValue">The lowest value that can be tracked (distinguished from 0) by the histogram. /// Must be a positive integer that is >= 1. /// May be internally rounded down to nearest power of 2. /// </param> /// <param name="highestTrackableValue">The highest value to be tracked by the histogram. /// Must be a positive integer that is >= (2 * lowestTrackableValue). /// </param> /// <param name="numberOfSignificantValueDigits"> /// The number of significant decimal digits to which the histogram will maintain value resolution and separation. /// Must be a non-negative integer between 0 and 5. /// </param> /// <remarks> /// Providing a lowestTrackableValue is useful in situations where the units used for the histogram's values are much /// smaller that the minimal accuracy required. /// For example when tracking time values stated in ticks (100 nanoseconds), where the minimal accuracy required is a /// microsecond, the proper value for lowestTrackableValue would be 10. /// </remarks> public LongConcurrentHistogram(long instanceId, long lowestTrackableValue, long highestTrackableValue, int numberOfSignificantValueDigits) : base(instanceId, lowestTrackableValue, highestTrackableValue, numberOfSignificantValueDigits) { _counts = new AtomicLongArray(CountsArrayLength); }
public override void Setup() { _num = new AtomicLongArray(10); }
public void AtomicLongArray_IsLockFree_Should_Success(long initialValue, MemoryOrder order, bool isLockFree) { var atomicLongArray = new AtomicLongArray(new[] { initialValue }, order); Assert.Equal(atomicLongArray.IsLockFree, isLockFree); }
public void AtomicLongArray_CanCreateArray() { var array = new AtomicLongArray(10); array.Length.Should().Be(10); }