Skip to content

Commit

Permalink
Enable test for MemoryBarrierProcessWide on arm64. Update comments. (#…
Browse files Browse the repository at this point in the history
…35817)

Linux kernels that we run in the lab should have reliable implementation of MemoryBarrierProcessWide now
  • Loading branch information
VSadov authored May 5, 2020
1 parent b9467c8 commit b6341c6
Showing 1 changed file with 9 additions and 5 deletions.
14 changes: 9 additions & 5 deletions src/libraries/System.Threading/tests/InterlockedTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ public void InterlockedOr_UInt64()
Assert.Equal(0x17755771u, value);
}

[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotArm64Process))] // [ActiveIssue("https://github.com/dotnet/runtime/issues/11177")]
[Fact]
public void MemoryBarrierProcessWide()
{
// Stress MemoryBarrierProcessWide correctness using a simple AsymmetricLock
Expand Down Expand Up @@ -356,8 +356,6 @@ private static T VolatileReadWithoutBarrier<T>(ref T location)
return location;
}

// Returning LockCookie to call Exit on is the fastest implementation because of it works naturally with the RCU pattern.
// The traditional Enter/Exit lock interface would require thread local storage or some other scheme to reclaim the cookie.
// Returning LockCookie to call Exit on is the fastest implementation because of it works naturally with the RCU pattern.
// The traditional Enter/Exit lock interface would require thread local storage or some other scheme to reclaim the cookie.
public LockCookie Enter()
Expand All @@ -380,6 +378,7 @@ public LockCookie Enter()
//
if (VolatileReadWithoutBarrier(ref _current) == entry)
{
// at this point we know for sure that we own the lock.
return entry;
}

Expand All @@ -398,8 +397,13 @@ private LockCookie EnterSlow()
var oldEntry = _current;
_current = new LockCookie(Environment.CurrentManagedThreadId);

// After MemoryBarrierProcessWide, we can be sure that the Volatile.Read done by the fast thread will see that it is not a fast
// thread anymore, and thus it will not attempt to enter the lock.
// MemoryBarrierProcessWide ensures, process-wide, that our write to _current becomes visible
// to every thread, and all writes by other threads become visible to us before we can continue.
// As a result any other thread that sets Taken to true either:
// a) made it past the read of _current and owns the lock OR
// b) will see that _current has changed and will revert Taken without taking the lock
// Thus we only need to wait for 'Taken' to become false and claim the lock for ourselves.
// 'Taken' may yet switch to true after that, but that cannot result in other thread owning the lock.
Interlocked.MemoryBarrierProcessWide();

// Keep looping as long as the lock is taken by other thread
Expand Down

0 comments on commit b6341c6

Please sign in to comment.