Пример #1
0
        public long WaitFor(long sequence, ISequence cursor, ISequence dependentSequence, ISequenceBarrier barrier)
        {
            long availableSequence;

            if (cursor.GetValue() < sequence)
            {
                lock (_mutex)
                {
                    do
                    {
                        Interlocked.Exchange(ref _signalNeeded, 1);

                        if (cursor.GetValue() >= sequence)
                        {
                            break;
                        }

                        barrier.CheckAlert();
                        Monitor.Wait(_mutex);
                    } while (cursor.GetValue() < sequence);
                }
            }

            var spinWait = new AggressiveSpinWait();

            while ((availableSequence = dependentSequence.GetValue()) < sequence)
            {
                barrier.CheckAlert();
                spinWait.SpinOnce();
            }

            return(availableSequence);
        }
Пример #2
0
        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);
                }
            }
        }
Пример #3
0
        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 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));
        }
    }