public void ShouldOnlyClaimWhatsAvailable() { Sequence dependentSequence = new Sequence(); Sequence[] dependentSequences = { dependentSequence }; for (int j = 0; j < 1000; j++) { int numThreads = BufferSize * 2; IClaimStrategy claimStrategy = new MultiThreadedClaimStrategy(BufferSize); Volatile4.LongArray claimed = new Volatile4.LongArray(numThreads); Barrier barrier = new Barrier(numThreads); Thread[] ts = new Thread[numThreads]; for (int i = 0; i < numThreads; i++) { ts[i] = new Thread(() => { try { barrier.SignalAndWait(); long next = claimStrategy.CheckAndIncrement(1, 1, dependentSequences); claimed.AtomicIncrementAndGet((int)next); } catch (Exception e) { } }); } foreach (Thread t in ts) { t.Start(); } foreach (Thread t in ts) { t.Join(); } for (int i = 0; i < BufferSize; i++) { Assert.AreEqual(1L, claimed.ReadFullFence(i), "j = " + j + ", i = " + i); } for (int i = BufferSize; i < numThreads; i++) { Assert.AreEqual(0L, claimed.ReadFullFence(i), "j = " + j + ", i = " + i); } } }
public void StartProcessing() { // Check the processing started flag. if (IsProcessing) { throw new InvalidOperationException(Resources.Strings.AsyncQueueStartError); } _claimStrategy = ClaimStrategy; _waitStrategy = WaitStrategy; _bufferSize = Math.Max(128, BufferSize); // Reset asynchronous queue size. Interlocked.Exchange(ref _asyncQueueSize, 0); IClaimStrategy disruptorClaimStrategy; switch (_claimStrategy) { case ClaimStrategyType.SingleThreaded: disruptorClaimStrategy = new SingleThreadedClaimStrategy(_bufferSize); break; case ClaimStrategyType.MultiThreaded: disruptorClaimStrategy = new MultiThreadedClaimStrategy(_bufferSize); break; case ClaimStrategyType.MultiThreadedLowContention: disruptorClaimStrategy = new MultiThreadedLowContentionClaimStrategy(_bufferSize); break; default: disruptorClaimStrategy = new MultiThreadedClaimStrategy(_bufferSize); break; } IWaitStrategy disruptorWaitStrategy; switch (_waitStrategy) { case WaitStrategyType.Blocking: disruptorWaitStrategy = new BlockingWaitStrategy(); break; case WaitStrategyType.BusySpin: disruptorWaitStrategy = new BusySpinWaitStrategy(); break; case WaitStrategyType.Sleeping: disruptorWaitStrategy = new SleepingWaitStrategy(); break; case WaitStrategyType.Yielding: disruptorWaitStrategy = new YieldingWaitStrategy(); break; default: disruptorWaitStrategy = new YieldingWaitStrategy(); break; } // Initialize processing consumer. _processingConsumer = new ProcessingConsumer(this); // Initialize processing disruptor. _processingDisruptor = new Disruptor <ValueEntry>(() => new ValueEntry(), disruptorClaimStrategy, disruptorWaitStrategy, TaskScheduler.Default); _processingDisruptor.HandleEventsWith(_processingConsumer); // Create ring buffer. _processingRingBuffer = _processingDisruptor.Start(); // Set the processing started flag. IsProcessing = true; // Rise asynchronous processing start event. HandleStart(); }
public void ShouldOnlyClaimWhatsAvailable() { Sequence dependentSequence = new Sequence(); Sequence[] dependentSequences = { dependentSequence }; for (int j = 0; j < 1000; j++) { int numThreads = BufferSize * 2; IClaimStrategy claimStrategy = new MultiThreadedClaimStrategy(BufferSize); Volatile4.LongArray claimed = new Volatile4.LongArray(numThreads); Barrier barrier = new Barrier(numThreads); Thread[] ts = new Thread[numThreads]; for (int i = 0; i < numThreads; i++) { ts[i] = new Thread(() => { try { barrier.SignalAndWait(); long next = claimStrategy.CheckAndIncrement(1, 1, dependentSequences); claimed.AtomicIncrementAndGet((int) next); } catch (Exception e) { } }); } foreach (Thread t in ts) { t.Start(); } foreach (Thread t in ts) { t.Join(); } for (int i = 0; i < BufferSize; i++) { Assert.AreEqual(1L, claimed.ReadFullFence(i), "j = " + j + ", i = " + i); } for (int i = BufferSize; i < numThreads; i++) { Assert.AreEqual(0L, claimed.ReadFullFence(i), "j = " + j + ", i = " + i); } } }