RecyclableList.IndexOf performance improvements.
This commit is contained in:
1 parent
21c82d80a2
commit
db8ee72c59
2 files changed
+74
-21
No files matched your search
@@ -3,6 +3,10 @@ namespace Recyclable.Collections.Parallel
|
||||
public sealed class IndexOfSynchronizationContext
|
||||
{
|
||||
private readonly SpinWait _participantsSpinWait = new();
|
||||
private readonly SpinLock _participantsSpinLock = new(false);
|
||||
private readonly SpinLock _indexOfSpinLock = new(false);
|
||||
private bool _indexOfLockTaken;
|
||||
|
||||
|
||||
internal bool _isItemFound;
|
||||
internal int _participants;
|
||||
@@ -10,12 +14,29 @@ namespace Recyclable.Collections.Parallel
|
||||
|
||||
public void AddParticipant()
|
||||
{
|
||||
_ = Interlocked.Increment(ref _participants);
|
||||
bool lockTaken = false;
|
||||
_participantsSpinLock.Enter(ref lockTaken);
|
||||
_participants++;
|
||||
if (lockTaken)
|
||||
{
|
||||
_participantsSpinLock.Exit(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddParticipants(int newParticipants)
|
||||
{
|
||||
_ = Interlocked.Add(ref _participants, newParticipants);
|
||||
bool lockTaken = false;
|
||||
_participantsSpinLock.Enter(ref lockTaken);
|
||||
_participants += newParticipants;
|
||||
if (lockTaken)
|
||||
{
|
||||
_participantsSpinLock.Exit(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void Lock()
|
||||
{
|
||||
_indexOfSpinLock.Enter(ref _indexOfLockTaken);
|
||||
}
|
||||
|
||||
public void RemoveParticipants(int participantsToRemove)
|
||||
@@ -25,7 +46,13 @@ namespace Recyclable.Collections.Parallel
|
||||
ThrowNotEnoughParticipants();
|
||||
}
|
||||
|
||||
_ = Interlocked.Add(ref _participants, -participantsToRemove);
|
||||
bool lockTaken = false;
|
||||
_participantsSpinLock.Enter(ref lockTaken);
|
||||
_participants -= participantsToRemove;
|
||||
if (lockTaken)
|
||||
{
|
||||
_participantsSpinLock.Exit(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveParticipant()
|
||||
@@ -35,7 +62,13 @@ namespace Recyclable.Collections.Parallel
|
||||
ThrowNoMoreParticipants();
|
||||
}
|
||||
|
||||
_ = Interlocked.Decrement(ref _participants);
|
||||
bool lockTaken = false;
|
||||
_participantsSpinLock.Enter(ref lockTaken);
|
||||
_participants--;
|
||||
if (lockTaken)
|
||||
{
|
||||
_participantsSpinLock.Exit(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void SignalAndWait()
|
||||
@@ -45,13 +78,28 @@ namespace Recyclable.Collections.Parallel
|
||||
ThrowNoMoreParticipants();
|
||||
}
|
||||
|
||||
_ = Interlocked.Decrement(ref _participants);
|
||||
bool lockTaken = false;
|
||||
_participantsSpinLock.Enter(ref lockTaken);
|
||||
_participants--;
|
||||
if (lockTaken)
|
||||
{
|
||||
_participantsSpinLock.Exit(false);
|
||||
}
|
||||
|
||||
while (_participants > 0)
|
||||
{
|
||||
_participantsSpinWait.SpinOnce();
|
||||
}
|
||||
}
|
||||
|
||||
public void Unlock()
|
||||
{
|
||||
if (_indexOfLockTaken)
|
||||
{
|
||||
_indexOfSpinLock.Exit(false);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ThrowNotEnoughParticipants() => throw new InvalidOperationException("Participant cannot be removed, because there are not enough participants.");
|
||||
private static void ThrowNoMoreParticipants() => throw new InvalidOperationException("Participant cannot be removed, because there are no more participants.");
|
||||
|
||||
|
||||
Reference in new issue
Block a user