public override long GetRemainingCapacity() { long consumed = SequenceGroupManager.GetMinimumSequence(GatingSequences, Cursor.GetValue()); long produced = Cursor.GetValue(); return(BufferSize - (produced - consumed)); }
public override long Next(int n) { if (n < 1) { throw new ArgumentException($"{nameof(n)} must greater than 1."); } long nextValue = NextValue; long nextSequence = nextValue + n; long wrapPoint = nextSequence - BufferSize; long cachedGatingSequence = CachedValue; if (wrapPoint > cachedGatingSequence || cachedGatingSequence > nextValue) { Cursor.SetVolatileValue(nextValue); // StoreLoad fence long minSequence; var spinWait = default(AggressiveSpinWait); while (wrapPoint > (minSequence = SequenceGroupManager.GetMinimumSequence(GatingSequences, nextValue))) { // Use waitStrategy to spin? spinWait.SpinOnce(); } CachedValue = minSequence; } NextValue = nextSequence; return(nextSequence); }
public override long GetRemainingCapacity() { long nextValue = CachedValue; long consumed = SequenceGroupManager.GetMinimumSequence(GatingSequences, nextValue); long produced = nextValue; return(BufferSize - (produced - consumed)); }
/// <summary> /// Wait for the <see cref="RingBuffer{TEvent}"/> to drain of published events then halt the workers. /// </summary> public void DrainAndHalt() { var workerSequences = GetWorkerSequences(); while (_ringBuffer.GetCursor() > SequenceGroupManager.GetMinimumSequence(workerSequences)) { Thread.Yield(); } foreach (var processor in _workProcessors) { processor.Halt(); } _started = 0; }
private bool HasAvailableCapacity(ISequence[] gatingSequences, int requiredCapacity, long cursorValue) { long wrapPoint = (cursorValue + requiredCapacity) - BufferSize; long cachedGatingSequence = _gatingSequenceCache.GetValue(); if (wrapPoint > cachedGatingSequence || cachedGatingSequence > cursorValue) { long minSequence = SequenceGroupManager.GetMinimumSequence(gatingSequences, cursorValue); _gatingSequenceCache.SetValue(minSequence); if (wrapPoint > minSequence) { return(false); } } return(true); }
public override long Next(int n) { if (n < 1) { throw new ArgumentException($"{nameof(n)} must be > 0"); } long next; long current; var spinWait = default(AggressiveSpinWait); do { current = Cursor.GetValue(); next = current + n; var wrapPoint = next - BufferSize; var cachedGatingSequence = _gatingSequenceCache.GetValue(); if (wrapPoint > cachedGatingSequence || cachedGatingSequence > current) { var gatingSequence = SequenceGroupManager.GetMinimumSequence(GatingSequences, current); if (wrapPoint > gatingSequence) { //should we spin based on the wait strategy? spinWait.SpinOnce(); continue; } _gatingSequenceCache.SetValue(gatingSequence); } else if (Cursor.CompareAndSet(current, next)) { break; } } while (true); return(next); }
private bool HasAvailableCapacity(int requiredCapacity, bool doStore) { var nextValue = NextValue; var wrapPoint = (nextValue + requiredCapacity) - BufferSize; var cachedGatingSequence = CachedValue; if (wrapPoint > cachedGatingSequence || cachedGatingSequence > nextValue) { if (doStore) { Cursor.SetVolatileValue(nextValue); // StoreLoad fence } long minSequence = SequenceGroupManager.GetMinimumSequence(GatingSequences, nextValue); CachedValue = minSequence; if (wrapPoint > minSequence) { return(false); } } return(true); }
public long GetMinimumSequence() { return(SequenceGroupManager.GetMinimumSequence(_sequences)); }
public virtual long GetMinimumSequence() { return(SequenceGroupManager.GetMinimumSequence(GatingSequences, Cursor.GetValue())); }