Skip to content

Commit 72473ab

Browse files
committed
Improvements to ConcurrentQueue Clear when it has a fixed-size.
1 parent e92bf0d commit 72473ab

File tree

3 files changed

+41
-7
lines changed

3 files changed

+41
-7
lines changed

Lockless-Queue/ConcurrentQueue.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -882,14 +882,19 @@ public void Clear()
882882
{
883883
_tail.EnsureFrozenForEnqueues();
884884

885-
// Ensure the same capacity is retained when we are dealing with a fixedsize queue.
886-
var segmentSize = InitialSegmentLength;
887885
if (_fixedSize)
888886
{
889-
segmentSize = _tail.Capacity;
890-
}
887+
// No need to reallocate a QueueSegment when dealing with a fixed-size Queue.
888+
// The Head and Tail should always be the same in this case.
889+
System.Diagnostics.Debug.Assert(_tail == _head);
891890

892-
_tail = _head = new ConcurrentQueueSegment<T>(segmentSize);
891+
// Reset the sequence numbers of the Slots in our only QueueSegment.
892+
_head.Reset();
893+
}
894+
else
895+
{
896+
_tail = _head = new ConcurrentQueueSegment<T>(InitialSegmentLength);
897+
}
893898
}
894899
}
895900

Lockless-Queue/ConcurrentQueueSegment.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
// The .NET Foundation licenses this file to you under the MIT license.
1010

1111
using System.Diagnostics;
12+
using System.Runtime.CompilerServices;
1213
using System.Threading;
1314

1415
namespace LocklessQueues
@@ -73,7 +74,7 @@ internal ConcurrentQueueSegment(int boundedLength)
7374
/// to a value that maps to the same slot but that won't be confused with
7475
/// any other enqueue/dequeue sequence number.
7576
/// </remarks>
76-
internal void EnsureFrozenForEnqueues()
77+
internal void EnsureFrozenForEnqueues()
7778
{
7879
if (!_frozenForEnqueues)
7980
{
@@ -275,5 +276,19 @@ public bool TryEnqueue(T item)
275276
spinner.SpinOnce();
276277
}
277278
}
279+
280+
/// <summary>
281+
/// Resets the current <see cref="ConcurrentQueueSegment{T}"/>. Should only be used when the <see cref="ConcurrentQueue{T}"/> has a fixed size!
282+
/// </summary>
283+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
284+
internal void Reset()
285+
{
286+
_headAndTail = new HeadAndTail();
287+
_preservedForObservation = default;
288+
_frozenForEnqueues = default;
289+
290+
for (int i = 0; i < _slots.Length; i++)
291+
_slots[i].SequenceNumber = i;
292+
}
278293
}
279294
}
Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,23 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
44
<TargetFramework>netstandard2.0</TargetFramework>
55
<RootNamespace>Lockless_Queue</RootNamespace>
66
<LangVersion>7.1</LangVersion>
7+
<Authors>Dennis Corvers</Authors>
8+
<RepositoryUrl>https://github.com/DennisCorvers/Lockless-Queue</RepositoryUrl>
9+
<NeutralLanguage />
10+
<Description>A collection of lockless, concurrent queues.
11+
12+
The following queue implementations are present:
13+
14+
SPSC Queue (Single Producer, Single Consumer).
15+
MPSC Queue (Multi Producer, Single Consumer).
16+
Concurrent Queue (Multi Producer, Multi Consumer).
17+
The Concurrent Queue implementation is a copy of the .Net 5.0 implementation with the added option for a fixed-size queue. This queue is lockless if/when it is instantiated as a fixed-size queue.</Description>
18+
<Copyright>Copyright (c) 2021 Dennis Corvers</Copyright>
19+
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
20+
<PackageLicenseUrl>https://github.com/DennisCorvers/Lockless-Queue/blob/master/LICENSE</PackageLicenseUrl>
721
</PropertyGroup>
822

923
</Project>

0 commit comments

Comments
 (0)