Skip to content

Commit

Permalink
Remove code dupe
Browse files Browse the repository at this point in the history
  • Loading branch information
john-h-k committed Jul 11, 2019
1 parent aa8273f commit 53de583
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 26 deletions.
22 changes: 11 additions & 11 deletions SpinLockSlim/SpinLockSlim.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public struct SpinLockSlim
public void Enter(ref bool taken)
{
// while acquired == 1, loop, then when it == 0, exit and set it to 1
while (Interlocked.CompareExchange(ref _acquired, True, False) != False)
while (TryAcquire())
{
// NOP
}
Expand All @@ -63,7 +63,7 @@ public void Enter(ref bool taken)
public void TryEnter(ref bool taken)
{
// if it acquired == 0, change it to 1 and return true, else return false
taken = Interlocked.CompareExchange(ref _acquired, True, False) == False;
taken = TryAcquire();
}

/// <summary>
Expand All @@ -80,20 +80,17 @@ public void TryEnter(ref bool taken)
public void TryEnter(ref bool taken, uint iterations)
{
// if it acquired == 0, change it to 1 and return true, else return false
while (Interlocked.CompareExchange(ref _acquired, True, False) != False)
while (TryAcquire())
{
if (iterations-- == 0) // postfix decrement, so no issue if iterations == 0 at first
{
taken = false;
return;
}
}

taken = true;
}

private static readonly Stopwatch Timer = Stopwatch.StartNew();

/// <summary>
/// Try to safely enter the lock for a certain <see cref="TimeSpan"/> (<paramref name="timeout"/>).
/// <paramref name="taken"/> will be <c>true</c> if the lock was taken, else <c>false</c>.
Expand All @@ -109,13 +106,13 @@ public void TryEnter(ref bool taken, TimeSpan timeout)
{
unchecked
{
long start = Timer.ElapsedTicks;
var end = (long)((timeout.TotalMilliseconds * Stopwatch.Frequency) + start);
long start = Stopwatch.GetTimestamp();
long end = (long)timeout.TotalMilliseconds * Stopwatch.Frequency + start;

// if it acquired == 0, change it to 1 and return true, else return false
while (Interlocked.CompareExchange(ref _acquired, True, False) != False)
while (TryAcquire())
{
if (Timer.ElapsedTicks >= end)
if (Stopwatch.GetTimestamp() >= end)
{
return;
}
Expand All @@ -141,7 +138,7 @@ public void Exit()
/// Exit the lock with an optional post-release memory barrier. This method is dangerous and must be called only once the caller is sure they have
/// ownership of the lock. Use <see cref="SpinLockSlimChecked"/> for debugging to ensure your code
/// only calls <see cref="Exit()"/> when it has ownership
/// </summary>[MethodImpl(AggressiveInlining_AggressiveOpts)]
/// </summary>
/// <param name="insertMemBarrier">Whether a memory barrier should be inserted after the release</param>
[MethodImpl(AggressiveInlining_AggressiveOpts)]
public void Exit(bool insertMemBarrier)
Expand All @@ -164,5 +161,8 @@ public void ExitWithBarrier()

Thread.MemoryBarrier();
}

[MethodImpl(AggressiveInlining_AggressiveOpts)]
private bool TryAcquire() => Interlocked.CompareExchange(ref _acquired, True, False) != False;
}
}
33 changes: 18 additions & 15 deletions SpinLockSlim/SpinLockSlimChecked.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public void Enter(ref bool taken)
EnsureFalseAndNotRecursiveEntry(taken);

// while acquired == 1, loop, then when it == 0, exit and set it to 1
while (Interlocked.CompareExchange(ref _acquired, True, False) != False)
while (TryAcquire())
{
// NOP
}
Expand All @@ -78,7 +78,7 @@ public void TryEnter(ref bool taken)

// if acquired == 0 (the lock is not taken), change it to 1 (take the lock)
// and return true, else return false
taken = Interlocked.CompareExchange(ref _acquired, True, False) == False;
taken = TryAcquire();
}

/// <summary>
Expand All @@ -99,20 +99,17 @@ public void TryEnter(ref bool taken, uint iterations)

// if acquired == 0 (the lock is not taken), change it to 1 (take the lock)
// and return true, else retry until it we run out of iterations
while (Interlocked.CompareExchange(ref _acquired, True, False) != False)
while (TryAcquire())
{
if (iterations-- == 0) // postfix decrement, so no issue if iterations == 0 at first
{
taken = false;
return;
}
}

taken = true;
}

private static readonly Stopwatch Timer = Stopwatch.StartNew();

/// <summary>
/// Try to safely enter the lock for a certain <see cref="TimeSpan"/> (<paramref name="timeout"/>).
/// <paramref name="taken"/> will be <c>true</c> if the lock was taken, else <c>false</c>.
Expand All @@ -131,15 +128,18 @@ public void TryEnter(ref bool taken, TimeSpan timeout)
EnsurePositiveTimeSpan(timeout);
EnsureFalseAndNotRecursiveEntry(taken);

long start = Timer.ElapsedTicks;
var end = (long)((timeout.TotalMilliseconds / Stopwatch.Frequency) + start);

// if it acquired == 0, change it to 1 and return true, else return false
while (Interlocked.CompareExchange(ref _acquired, True, False) != False)
unchecked
{
if (Timer.ElapsedTicks >= end)
long start = Stopwatch.GetTimestamp();
var end = (long)((timeout.TotalMilliseconds * Stopwatch.Frequency) + start);

// if it acquired == 0, change it to 1 and return true, else return false
while (TryAcquire())
{
return;
if (Stopwatch.GetTimestamp() >= end)
{
return;
}
}
}

Expand Down Expand Up @@ -186,7 +186,7 @@ public void ExitWithBarrier()

[MethodImpl(AggressiveInlining_AggressiveOpts)]
[DebuggerHidden]
private static void ValidateRefBoolAsFalse(bool value)
private static void ValidateRefBoolAsFalse(in bool value)
{
if (value)
ThrowHelper.ThrowArgumentException("Bool must be false");
Expand All @@ -204,7 +204,7 @@ private void EnsureNotRecursiveEntry()

[MethodImpl(AggressiveInlining_AggressiveOpts)]
[DebuggerHidden]
private void EnsureFalseAndNotRecursiveEntry(bool value)
private void EnsureFalseAndNotRecursiveEntry(in bool value)
{
ValidateRefBoolAsFalse(value);
EnsureNotRecursiveEntry();
Expand All @@ -228,5 +228,8 @@ private void EnsureOwnedAndOwnedByCurrentThread()
ThrowHelper.ThrowSynchronizationLockException(
$"Lock is not owned by current thread - lock is owned by thread with ThreadId {_acquired}, but thread trying to exit has ThreadId {threadId}");
}

[MethodImpl(AggressiveInlining_AggressiveOpts)]
private bool TryAcquire() => Interlocked.CompareExchange(ref _acquired, True, False) != False;
}
}

0 comments on commit 53de583

Please sign in to comment.