Ejemplo n.º 1
0
        private bool HasAvailableCapacity(int requiredCapacity, bool doStore)
        {
            long nextValue = _nextValue;

            long wrapPoint            = (nextValue + requiredCapacity) - _bufferSize;
            long cachedGatingSequence = _cachedValue;

            if (wrapPoint > cachedGatingSequence || cachedGatingSequence > nextValue)
            {
                if (doStore)
                {
                    _cursor.SetValueVolatile(nextValue);
                }

                long minSequence = DisruptorUtil.GetMinimumSequence(Volatile.Read(ref _gatingSequences), nextValue);
                _cachedValue = minSequence;

                if (wrapPoint > minSequence)
                {
                    return(false);
                }
            }

            return(true);
        }
Ejemplo n.º 2
0
        public MultiProducerSequencer(int bufferSize, IWaitStrategy waitStrategy)
        {
            if (bufferSize < 1)
            {
                throw new ArgumentException("bufferSize must not be less than 1");
            }
            if (!bufferSize.IsPowerOf2())
            {
                throw new ArgumentException("bufferSize must be a power of 2");
            }

            _bufferSize             = bufferSize;
            _waitStrategy           = waitStrategy;
            _isBlockingWaitStrategy = !(waitStrategy is INonBlockingWaitStrategy);
#if NETCOREAPP
            _availableBuffer        = GC.AllocateArray <int>(bufferSize, pinned: true);
            _availableBufferPointer = (int *)Unsafe.AsPointer(ref _availableBuffer[0]);
#else
            _availableBuffer = new int[bufferSize];
#endif
            _indexMask  = bufferSize - 1;
            _indexShift = DisruptorUtil.Log2(bufferSize);

            InitialiseAvailableBuffer();
        }
Ejemplo n.º 3
0
        public long GetRemainingCapacity()
        {
            var consumed = DisruptorUtil.GetMinimumSequence(Volatile.Read(ref _gatingSequences), _cursor.Value);
            var produced = _cursor.Value;

            return(BufferSize - (produced - consumed));
        }
Ejemplo n.º 4
0
        private void NextInternalWrap(long nextValue, long wrapPoint)
        {
            _cursor.SetValueVolatile(nextValue);

            var  spinWait = default(AggressiveSpinWait);
            long minSequence;

            while (wrapPoint > (minSequence = DisruptorUtil.GetMinimumSequence(Volatile.Read(ref _gatingSequences), nextValue)))
            {
                spinWait.SpinOnce();
            }

            _cachedValue = minSequence;
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Wait for the <see cref="RingBuffer{T}"/> to drain of published events then halt the workers.
        /// </summary>
        public void DrainAndHalt()
        {
            var workerSequences = GetWorkerSequences();

            while (_ringBuffer.Cursor > DisruptorUtil.GetMinimumSequence(workerSequences))
            {
                Thread.Sleep(0);
            }

            foreach (var workProcessor in _workProcessors)
            {
                workProcessor.Halt();
            }

            _runState = ProcessorRunStates.Halted;
        }
Ejemplo n.º 6
0
        private bool HasAvailableCapacity(int requiredCapacity, long cursorValue)
        {
            var wrapPoint            = (cursorValue + requiredCapacity) - _bufferSize;
            var cachedGatingSequence = _gatingSequenceCache.Value;

            if (wrapPoint > cachedGatingSequence || cachedGatingSequence > cursorValue)
            {
                var minSequence = DisruptorUtil.GetMinimumSequence(Volatile.Read(ref _gatingSequences), cursorValue);
                _gatingSequenceCache.SetValue(minSequence);

                if (wrapPoint > minSequence)
                {
                    return(false);
                }
            }

            return(true);
        }
Ejemplo n.º 7
0
        internal long NextInternal(int n)
        {
            var nextSequence         = _cursor.AddAndGet(n);
            var current              = nextSequence - n;
            var wrapPoint            = nextSequence - _bufferSize;
            var cachedGatingSequence = _gatingSequenceCache.Value;

            if (wrapPoint > cachedGatingSequence || cachedGatingSequence > current)
            {
                var  spinWait = default(AggressiveSpinWait);
                long gatingSequence;

                while (wrapPoint > (gatingSequence = DisruptorUtil.GetMinimumSequence(Volatile.Read(ref _gatingSequences), current)))
                {
                    spinWait.SpinOnce();
                }

                _gatingSequenceCache.SetValue(gatingSequence);
            }

            return(nextSequence);
        }
Ejemplo n.º 8
0
 /// <summary>
 /// <see cref="ISequencer.GetMinimumSequence"/>.
 /// </summary>
 public long GetMinimumSequence()
 {
     return(DisruptorUtil.GetMinimumSequence(Volatile.Read(ref _gatingSequences), _cursor.Value));
 }