protected override void InternalEnqueue(Func <ValueTask> action) { AggressiveSpinWait spinWait = default; while (_queue.IsFull) { spinWait.SpinOnce(); } bool lockTaken = false; try { _spinLock.Enter(ref lockTaken); _queue.Enqueue(action); if (_flushPending) { return; } _flushPending = true; _taskFactory.StartNew(_flushCache); } finally { if (lockTaken) { _spinLock.Exit(false); } } }
public long WaitFor(long sequence, ISequence cursor, ISequence dependentSequence, ISequenceBarrier barrier) { if (cursor.GetValue() < sequence) { lock (mutex) { while (cursor.GetValue() < sequence) { barrier.CheckAlert(); Monitor.Wait(mutex); } } } long availableSequence; var spinWait = new AggressiveSpinWait(); while ((availableSequence = dependentSequence.GetValue()) < sequence) { barrier.CheckAlert(); spinWait.SpinOnce(); } return(availableSequence); }
public long WaitFor(long sequence, ISequence cursor, ISequence dependentSequence, ISequenceBarrier barrier) { if (cursor.GetValue() < sequence) { lock (_mutex) { do { Interlocked.Exchange(ref _signalNeeded, 1); if (cursor.GetValue() >= sequence) { break; } barrier.CheckAlert(); if (!Monitor.Wait(_mutex, _timeoutInMillis)) { throw new TimeoutException(); } } while (cursor.GetValue() < sequence); } } long availableSequence; var spinWait = new AggressiveSpinWait(); while ((availableSequence = dependentSequence.GetValue()) < sequence) { barrier.CheckAlert(); spinWait.SpinOnce(); } return(availableSequence); }
public void ShouldHandleLotsOfThreads() { var disruptor = new Disruptor <TestEvent>(TestEvent.Factory, 65_536, TaskScheduler.Current, ProducerType.Multi, new SleepingWaitStrategy()); var ringBuffer = disruptor.RingBuffer; disruptor.SetDefaultExceptionHandler(new FatalExceptionHandler <TestEvent>()); var threads = Math.Max(1, Environment.ProcessorCount / 2); const int iterations = 20_000_000; var publisherCount = threads; var handlerCount = threads; var end = new CountdownEvent(publisherCount); var start = new CountdownEvent(publisherCount); var handlers = Initialise(new TestWorkHandler[handlerCount]); var publishers = Initialise(new Publisher[publisherCount], ringBuffer, iterations, start, end); disruptor.HandleEventsWithWorkerPool(handlers); disruptor.Start(); foreach (var publisher in publishers) { Task.Factory.StartNew(publisher.Run); } end.Wait(); var spinWait = new AggressiveSpinWait(); while (ringBuffer.Cursor < (iterations - 1)) { spinWait.SpinOnce(); } disruptor.Shutdown(); foreach (var publisher in publishers) { Assert.That(publisher.Failed, Is.EqualTo(false)); } foreach (var handler in handlers) { Assert.That(handler.MessagesSeen, Is.Not.EqualTo(0)); Assert.That(handler.FailureCount, Is.EqualTo(0)); } }