public static GetMinimumSequence ( ISequence sequences, long minimum = long.MaxValue ) : long | ||
sequences | ISequence | sequences to compare. |
minimum | long | an initial default minimum. If the array is empty this value will returned. |
return | long |
public long RemainingCapacity() { long consumed = Util.GetMinimumSequence(_gatingSequences); long produced = _cursor.Value; return(BufferSize - (produced - consumed)); }
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 = Util.GetMinimumSequence(Volatile.Read(ref _gatingSequences), nextValue); _cachedValue = minSequence; if (wrapPoint > minSequence) { return(false); } } return(true); }
internal long NextInternal(int n) { long current; long next; var spinWait = default(AggressiveSpinWait); do { current = _cursor.Value; next = current + n; long wrapPoint = next - _bufferSize; long cachedGatingSequence = _gatingSequenceCache.Value; if (wrapPoint > cachedGatingSequence || cachedGatingSequence > current) { long gatingSequence = Util.GetMinimumSequence(Volatile.Read(ref _gatingSequences), current); if (wrapPoint > gatingSequence) { spinWait.SpinOnce(); continue; } _gatingSequenceCache.SetValue(gatingSequence); } else if (_cursor.CompareAndSet(current, next)) { break; } } while (true); return(next); }
public long GetRemainingCapacity() { var consumed = Util.GetMinimumSequence(Volatile.Read(ref _gatingSequences), _cursor.Value); var produced = _cursor.Value; return(BufferSize - (produced - consumed)); }
/// <summary> /// Wait for the given sequence to be available /// </summary> /// <param name="sequence">sequence to be waited on.</param> /// <param name="cursor">Ring buffer cursor on which to wait.</param> /// <param name="dependents">dependents further back the chain that must advance first</param> /// <param name="barrier">barrier the <see cref="IEventProcessor"/> is waiting on.</param> /// <returns>the sequence that is available which may be greater than the requested sequence.</returns> public long WaitFor(long sequence, Sequence cursor, Sequence[] dependents, ISequenceBarrier barrier) { long availableSequence; var spinWait = default(SpinWait); if (dependents.Length == 0) { while ((availableSequence = cursor.Value) < sequence) // volatile read { barrier.CheckAlert(); spinWait.SpinOnce(); if (spinWait.Count > 5000) { break; } } } else { while ((availableSequence = Util.GetMinimumSequence(dependents)) < sequence) { barrier.CheckAlert(); spinWait.SpinOnce(); if (spinWait.Count > 5000) { break; } } } return(availableSequence); }
/// <summary> /// Claim the next n events in sequence for publishing. This is for batch event producing. Using batch producing requires a little care and some math. /// <code> /// int n = 10; /// long hi = sequencer.next(n); /// long lo = hi - (n - 1); /// for (long sequence = lo; sequence <= hi; sequence++) { /// // Do work. /// } /// sequencer.publish(lo, hi); /// </code> /// </summary> /// <param name="n">the number of sequences to claim</param> /// <returns>the highest claimed sequence value</returns> public override long Next(int n) { if (n < 1) { throw new ArgumentException("n must be > 0"); } long nextValue = _fields.NextValue; long nextSequence = nextValue + n; long wrapPoint = nextSequence - _bufferSize; long cachedGatingSequence = _fields.CachedValue; if (wrapPoint > cachedGatingSequence || cachedGatingSequence > nextValue) { _cursor.SetValueVolatile(nextValue); var spinWait = default(SpinWait); long minSequence; while (wrapPoint > (minSequence = Util.GetMinimumSequence(Volatile.Read(ref _gatingSequences), nextValue))) { _waitStrategy.SignalAllWhenBlocking(); spinWait.SpinOnce(); // LockSupport.parkNanos(1L); } _fields.CachedValue = minSequence; } _fields.NextValue = nextSequence; return(nextSequence); }
public long WaitFor(IConsumer[] consumers, IRingBuffer <T> ringBuffer, IConsumerBarrier <T> barrier, long sequence) { long availableSequence; if (0 == consumers.Length) { while ((availableSequence = ringBuffer.Cursor) < sequence) { if (barrier.IsAlerted()) { throw AlertException.ALERT_EXCEPTION; } } } else { while ((availableSequence = Util.GetMinimumSequence(consumers)) < sequence) { if (barrier.IsAlerted()) { throw AlertException.ALERT_EXCEPTION; } } } return(availableSequence); }
public long NextInternal(int n) { long nextValue = _nextValue; long nextSequence = nextValue + n; long wrapPoint = nextSequence - _bufferSize; long cachedGatingSequence = _cachedValue; if (wrapPoint > cachedGatingSequence || cachedGatingSequence > nextValue) { _cursor.SetValueVolatile(nextValue); var spinWait = default(AggressiveSpinWait); long minSequence; while (wrapPoint > (minSequence = Util.GetMinimumSequence(Volatile.Read(ref _gatingSequences), nextValue))) { spinWait.SpinOnce(); } _cachedValue = minSequence; } _nextValue = nextSequence; return(nextSequence); }
/// <summary> /// Wait for the given sequence to be available with a timeout specified. /// </summary> /// <param name="sequence">sequence to be waited on.</param> /// <param name="cursor">cursor on which to wait.</param> /// <param name="dependents">dependents further back the chain that must advance first</param> /// <param name="barrier">barrier the processor is waiting on.</param> /// <param name="timeout">timeout value to abort after.</param> /// <returns>the sequence that is available which may be greater than the requested sequence.</returns> /// <exception cref="AlertException">AlertException if the status of the Disruptor has changed.</exception> public long WaitFor(long sequence, Sequence cursor, Sequence[] dependents, ISequenceBarrier barrier, TimeSpan timeout) { long availableSequence; var counter = SpinTries; var sw = Stopwatch.StartNew(); if (dependents.Length == 0) { while ((availableSequence = cursor.Value) < sequence) // volatile read { counter = ApplyWaitMethod(barrier, counter); if (sw.Elapsed > timeout) { break; } } } else { while ((availableSequence = Util.GetMinimumSequence(dependents)) < sequence) { counter = ApplyWaitMethod(barrier, counter); if (sw.Elapsed > timeout) { break; } } } return(availableSequence); }
/// <summary> /// Wait for the given sequence to be available /// </summary> /// <param name="sequence">sequence to be waited on.</param> /// <param name="cursor">Ring buffer cursor on which to wait.</param> /// <param name="dependents">dependents further back the chain that must advance first</param> /// <param name="barrier">barrier the <see cref="IEventProcessor"/> is waiting on.</param> /// <returns>the sequence that is available which may be greater than the requested sequence.</returns> public long WaitFor(long sequence, Sequence cursor, Sequence[] dependents, ISequenceBarrier barrier) { var availableSequence = cursor.Value; // volatile read if (availableSequence < sequence) { Monitor.Enter(_gate); try { ++_numWaiters; while ((availableSequence = cursor.Value) < sequence) // volatile read { barrier.CheckAlert(); Monitor.Wait(_gate); } } finally { --_numWaiters; Monitor.Exit(_gate); } } if (dependents.Length != 0) { while ((availableSequence = Util.GetMinimumSequence(dependents)) < sequence) { barrier.CheckAlert(); } } return(availableSequence); }
/// <summary> /// Wait for the given sequence to be available with a timeout specified. /// </summary> /// <param name="sequence">sequence to be waited on.</param> /// <param name="cursor">cursor on which to wait.</param> /// <param name="dependents">dependents further back the chain that must advance first</param> /// <param name="barrier">barrier the processor is waiting on.</param> /// <param name="timeout">timeout value to abort after.</param> /// <returns>the sequence that is available which may be greater than the requested sequence.</returns> /// <exception cref="AlertException">AlertException if the status of the Disruptor has changed.</exception> public long WaitFor(long sequence, Sequence cursor, Sequence[] dependents, ISequenceBarrier barrier, TimeSpan timeout) { long availableSequence; var spinWait = new SpinWait(); var sw = Stopwatch.StartNew(); if (dependents.Length == 0) { while ((availableSequence = cursor.Value) < sequence) // volatile read { barrier.CheckAlert(); spinWait.SpinOnce(); if (sw.Elapsed > timeout) { break; } } } else { while ((availableSequence = Util.GetMinimumSequence(dependents)) < sequence) { barrier.CheckAlert(); spinWait.SpinOnce(); if (sw.Elapsed > timeout) { break; } } } return(availableSequence); }
public override long RemainingCapacity() { var consumed = Util.GetMinimumSequence(sequencesRef.ReadFullFence(), cursor.Value); var produced = cursor.Value; return(GetBufferSize - (produced - consumed)); }
public override long Next(int n) { if (n < 1) { throw new ArgumentOutOfRangeException("n must be > 0"); } SpinWait spinWait = new SpinWait(); long nextValue = this.nextValue; long nextSequence = nextValue + n; long wrapPoint = nextSequence - bufferSize; long cachedGatingSequence = this.cachedValue; if (wrapPoint > cachedGatingSequence || cachedGatingSequence > nextValue) { long minSequence; while (wrapPoint > (minSequence = Util.GetMinimumSequence(/*sequencesRef.ReadFullFence()*/ sequencesRef.ReadCompilerOnlyFence(), nextValue))) { spinWait.SpinOnce(); } this.cachedValue = minSequence; } this.nextValue = nextSequence; return(nextSequence); }
public override long RemainingCapacity() { long nextValue = this.nextValue; long consumed = Util.GetMinimumSequence(/*sequencesRef.ReadFullFence()*/ sequencesRef.ReadCompilerOnlyFence(), nextValue); long produced = nextValue; return(GetBufferSize - (produced - consumed)); }
/// <summary> /// Get the remaining capacity for this sequencer. return The number of slots remaining. /// </summary> public override long GetRemainingCapacity() { var nextValue = _fields.NextValue; var consumed = Util.GetMinimumSequence(Volatile.Read(ref _gatingSequences), nextValue); var produced = nextValue; return(BufferSize - (produced - consumed)); }
private void EnsureConsumersAreInRange(long sequence) { while ((sequence - Util.GetMinimumSequence(_consumers)) >= _ringBuffer._entries.Length) { #if CSHARP30 Thread.Sleep(0); #else Thread.Yield(); #endif } }
private void NextInternalWrap(long nextValue, long wrapPoint) { _cursor.SetValueVolatile(nextValue); var spinWait = default(AggressiveSpinWait); long minSequence; while (wrapPoint > (minSequence = Util.GetMinimumSequence(Volatile.Read(ref _gatingSequences), nextValue))) { spinWait.SpinOnce(); } _cachedValue = minSequence; }
private void WaitForFreeSlotAt(long sequence, Sequence[] dependentSequences) { long wrapPoint = sequence - _bufferSize; if (wrapPoint > _minGatingSequence.Value) { long minSequence; while (wrapPoint > (minSequence = Util.GetMinimumSequence(dependentSequences))) { // TODO LockSupport.parkNanos(1L); } _minGatingSequence.Value = minSequence; } }
private void WaitForCapacity(Sequence[] dependentSequences, MutableLong minGatingSequence) { long wrapPoint = (_claimSequence.Value + 1L) - _bufferSize; if (wrapPoint > minGatingSequence.Value) { long minSequence; while (wrapPoint > (minSequence = Util.GetMinimumSequence(dependentSequences))) { //TODO LockSupport.parkNanos(1L); } minGatingSequence.Value = 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 > Util.GetMinimumSequence(workerSequences)) { Thread.Sleep(0); } foreach (var workProcessor in _workProcessors) { workProcessor.Halt(); } _running = 0; }
private void WaitForFreeSlotAt(long sequence, Sequence[] dependentSequences, MutableLong minGatingSequence) { long wrapPoint = sequence - _bufferSize; if (wrapPoint > minGatingSequence.Value) { var spinWait = default(SpinWait); long minSequence; while (wrapPoint > (minSequence = Util.GetMinimumSequence(dependentSequences))) { spinWait.SpinOnce(); //Java version uses LockSupport.parkNanos(1L); } minGatingSequence.Value = minSequence; } }
/// <summary> /// Wait for the <see cref="RingBuffer"/> to drain of published events then halt the workers. /// </summary> public void drainAndHalt() { var workerSequences = getWorkerSequences(); while (ringBuffer.GetCursor > Util.GetMinimumSequence(workerSequences)) { Thread.Sleep(0); } foreach (WorkProcessor <T> processor in workProcessors) { processor.Halt(); } started.WriteFullFence(false); }
private void WaitForCapacity(Sequence[] dependentSequences, MutableLong minGatingSequence) { long wrapPoint = (_claimSequence.ReadFullFence() + 1L) - _bufferSize; if (wrapPoint > minGatingSequence.Value) { long minSequence; var spinWait = default(SpinWait); while (wrapPoint > (minSequence = Util.GetMinimumSequence(dependentSequences))) { spinWait.SpinOnce(); //LockSupport.parkNanos(1L); } minGatingSequence.Value = minSequence; } }
private void WaitForFreeSlotAt(long sequence, Sequence[] dependentSequences) { long wrapPoint = sequence - _bufferSize; if (wrapPoint > _minGatingSequence.ReadUnfenced()) { long minSequence; var spinWait = default(SpinWait); while (wrapPoint > (minSequence = Util.GetMinimumSequence(dependentSequences))) { spinWait.SpinOnce(); // LockSupport.parkNanos(1L); } _minGatingSequence.WriteUnfenced(minSequence); } }
/// <summary> /// Wait for the <see cref="RingBuffer{T}"/> to drain of published events then halt the workers. /// </summary> public void DrainAndHalt() { var workerSequences = WorkerSequences; while (_ringBuffer.Cursor > Util.GetMinimumSequence(workerSequences)) { Thread.Sleep(0); } for (int i = 0; i < _workProcessors.Length; i++) { var workProcessor = _workProcessors[i]; workProcessor.Halt(); } _running.WriteFullFence(Stopped); }
/// <summary> /// Wait for the <see cref="RingBuffer{T}"/> to drain of published events then halt the workers. /// </summary> public void DrainAndHalt() { var workerSequences = WorkerSequences; while (_ringBuffer.Cursor > Util.GetMinimumSequence(workerSequences)) { Thread.Sleep(0); } for (int i = 0; i < _workProcessors.Length; i++) { var workProcessor = _workProcessors[i]; workProcessor.Halt(); } _started.Value = false; }
/// <summary> /// Is there available capacity in the buffer for the requested sequence. /// </summary> /// <param name="availableCapacity">availableCapacity remaining in the buffer.</param> /// <param name="dependentSequences">dependentSequences to be checked for range.</param> /// <returns>true if the buffer has capacity for the requested sequence.</returns> public bool HasAvailableCapacity(int availableCapacity, Sequence[] dependentSequences) { long wrapPoint = (_claimSequence.ReadUnfenced() + availableCapacity) - _bufferSize; if (wrapPoint > _minGatingSequence.ReadUnfenced()) { long minSequence = Util.GetMinimumSequence(dependentSequences); _minGatingSequence.WriteUnfenced(minSequence); if (wrapPoint > minSequence) { return(false); } } return(true); }
private bool HasAvailableCapacity(ISequence[] gatingSequences, int requiredCapacity, long cursorValue) { var wrapPoint = (cursorValue + requiredCapacity) - _bufferSize; var cachedGatingSequence = _gatingSequenceCache.Value; if (wrapPoint > cachedGatingSequence || cachedGatingSequence > cursorValue) { long minSequence = Util.GetMinimumSequence(gatingSequences, cursorValue); _gatingSequenceCache.SetValue(minSequence); if (wrapPoint > minSequence) { return(false); } } return(true); }
private bool HasAvailableCapacity(long sequence, int availableCapacity, Sequence[] dependentSequences) { long wrapPoint = (sequence + availableCapacity) - _bufferSize; MutableLong minGatingSequence = _minGatingSequenceThreadLocal.Value; if (wrapPoint > minGatingSequence.Value) { long minSequence = Util.GetMinimumSequence(dependentSequences); minGatingSequence.Value = minSequence; if (wrapPoint > minSequence) { return(false); } } return(true); }
private bool HasAvailableCapacity(Sequence[] gatingSequences, int requiredCapacity, long cursorValue) { var wrapPoint = (cursorValue + requiredCapacity) - bufferSize; var cachedGatingSequence = gatingSequenceCache.Value; if (wrapPoint > cachedGatingSequence || cachedGatingSequence > cursorValue) { var minSequence = Util.GetMinimumSequence(sequencesRef.ReadFullFence(), cursorValue); gatingSequenceCache.Value = minSequence; if (wrapPoint > minSequence) { return(false); } } return(true); }