/// <summary>Tries to dequeue an element from the queue.</summary>
public bool TryDequeue(out T item)
{
+ Slot[] slots = _slots;
+
// Loop in case of contention...
var spinner = new SpinWait();
while (true)
int slotsIndex = currentHead & _slotsMask;
// Read the sequence number for the head position.
- int sequenceNumber = Volatile.Read(ref _slots[slotsIndex].SequenceNumber);
+ int sequenceNumber = Volatile.Read(ref slots[slotsIndex].SequenceNumber);
// We can dequeue from this slot if it's been filled by an enqueuer, which
// would have left the sequence number at pos+1.
{
// Successfully reserved the slot. Note that after the above CompareExchange, other threads
// trying to dequeue from this slot will end up spinning until we do the subsequent Write.
- item = _slots[slotsIndex].Item;
+ item = slots[slotsIndex].Item;
if (!Volatile.Read(ref _preservedForObservation))
{
// If we're preserving, though, we don't zero out the slot, as we need it for
// enumerations, peeking, ToArray, etc. And we don't update the sequence number,
// so that an enqueuer will see it as full and be forced to move to a new segment.
- _slots[slotsIndex].Item = default(T);
- Volatile.Write(ref _slots[slotsIndex].SequenceNumber, currentHead + _slots.Length);
+ slots[slotsIndex].Item = default(T);
+ Volatile.Write(ref slots[slotsIndex].SequenceNumber, currentHead + slots.Length);
}
return true;
}
Interlocked.MemoryBarrier();
}
+ Slot[] slots = _slots;
+
// Loop in case of contention...
var spinner = new SpinWait();
while (true)
int slotsIndex = currentHead & _slotsMask;
// Read the sequence number for the head position.
- int sequenceNumber = Volatile.Read(ref _slots[slotsIndex].SequenceNumber);
+ int sequenceNumber = Volatile.Read(ref slots[slotsIndex].SequenceNumber);
// We can peek from this slot if it's been filled by an enqueuer, which
// would have left the sequence number at pos+1.
int diff = sequenceNumber - (currentHead + 1);
if (diff == 0)
{
- result = resultUsed ? _slots[slotsIndex].Item : default(T);
+ result = resultUsed ? slots[slotsIndex].Item : default(T);
return true;
}
else if (diff < 0)
/// </summary>
public bool TryEnqueue(T item)
{
+ Slot[] slots = _slots;
+
// Loop in case of contention...
var spinner = new SpinWait();
while (true)
int slotsIndex = currentTail & _slotsMask;
// Read the sequence number for the tail position.
- int sequenceNumber = Volatile.Read(ref _slots[slotsIndex].SequenceNumber);
+ int sequenceNumber = Volatile.Read(ref slots[slotsIndex].SequenceNumber);
// The slot is empty and ready for us to enqueue into it if its sequence
// number matches the slot.
{
// Successfully reserved the slot. Note that after the above CompareExchange, other threads
// trying to return will end up spinning until we do the subsequent Write.
- _slots[slotsIndex].Item = item;
- Volatile.Write(ref _slots[slotsIndex].SequenceNumber, currentTail + 1);
+ slots[slotsIndex].Item = item;
+ Volatile.Write(ref slots[slotsIndex].SequenceNumber, currentTail + 1);
return true;
}
}