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); }
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(); }
public long GetRemainingCapacity() { var consumed = DisruptorUtil.GetMinimumSequence(Volatile.Read(ref _gatingSequences), _cursor.Value); var produced = _cursor.Value; return(BufferSize - (produced - consumed)); }
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; }
/// <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; }
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); }
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); }
/// <summary> /// <see cref="ISequencer.GetMinimumSequence"/>. /// </summary> public long GetMinimumSequence() { return(DisruptorUtil.GetMinimumSequence(Volatile.Read(ref _gatingSequences), _cursor.Value)); }