-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Semaphoreslim, fail faster for timeout 0 #6898
Conversation
|
|
||
| cancellationToken.ThrowIfCancellationRequested(); | ||
|
|
||
| if (millisecondsTimeout == 0 && m_currentCount == 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a comment about why it's safe to be checking this outside of the lock.
|
Have you run the System.Threading tests from corefx with this? |
|
Just doing it now (within build time definitions of now) |
51501fb to
d8bef37
Compare
|
@stephentoub tested with Failure in Discovering: System.Threading.Tests
Discovered: System.Threading.Tests
Starting: System.Threading.Tests
System.Threading.Tests.AsyncLocalTests.AsyncMethodNotifications [FAIL]
System.TypeLoadException : Could not load type 'YieldAwaiter' from assembly 'System.Threading.Tasks, Version=4.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
Stack Trace:
at System.Threading.Tests.AsyncLocalTests.<>c__DisplayClass7_0.<AsyncMethodNotifications>b__1()
I:\Work\GitHub\corefx\src\System.Threading\tests\AsyncLocalTests.cs(251,0): at System.Threading.Tests.AsyncLocalTests.Run(Func`1 func)
I:\Work\GitHub\corefx\src\System.Threading\tests\AsyncLocalTests.cs(275,0): at System.Threading.Tests.AsyncLocalTests.<AsyncMethodNotifications>d__7.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Finished: System.Threading.Tests
=== TEST EXECUTION SUMMARY ===
I:\Work\GitHub\corefx\Tools\tests.targets(260,5): warning : System.Threading.Tests Total: 167, Errors: 0, Failed: 1, Skipped: 0, Time: 5.414s [I:\Work\GitHub\corefx\src\System.Threading\tests\System.Threading.Tests.csproj]Also assume I have override correct, it doesn't shout that its using the coreclr repo in a way I can identify |
d8bef37 to
b5bb3c3
Compare
|
Fixed spelling of |
|
Thanks, Ben. LGTM. Have you measured to see what the throughput improvement is? (And verified that indeed there aren't any allocations? |
|
As aside, a use case example is choice on whether to go async private bool IsReadyToSend => _outgoingSends.Wait(0);
private Task ReadyToSend => _outgoingSends.WaitAsync();
private bool MaxOutstandingSendsReached => _outgoingSends.CurrentCount == 0;
private Task SendAsync(BufferSpan span, bool endOfMessage)
{
if (!IsReadyToSend)
{
return SendAsyncAwaited(span, endOfMessage);
}
var flushSends = endOfMessage || MaxOutstandingSendsReached;
Send(GetSegmentFromSpan(span), flushSends);
if (flushSends && !endOfMessage)
{
return AwaitReadyToSend();
}
return _completedTask;
}
private async Task AwaitReadyToSend()
{
await ReadyToSend;
}
private async Task SendAsyncAwaited(BufferSpan span, bool endOfMessage)
{
await ReadyToSend;
var flushSends = endOfMessage || MaxOutstandingSendsReached;
Send(GetSegmentFromSpan(span), flushSends);
if (flushSends && !endOfMessage)
{
await ReadyToSend;
}
} |
|
@stephentoub the non-async path fared quite badly before (async blocked: code) 1M iters Server GC
Just testing allocations |
|
|
||
| cancellationToken.ThrowIfCancellationRequested(); | ||
|
|
||
| // Pref: Check the stack timeout parameter before checking the volatile count |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo
b5bb3c3 to
21c89ff
Compare
|
Looks like its working 😄 |
|
@dotnet-bot test Linux ARM Emulator Cross Debug Build |
|
Thanks, @benaadams. LGTM. |
|
👏 |
This brings the patch: dotnet/coreclr#6898 Fail faster for `Wait(0)` when no counts available. Don't allocate in the `Wait(0)` and `WaitAsync(0)` fail paths. 1M iters Server GC method | pre (ms) | post (ms) | improvement -------- |------- |------- |------ | Wait(0) | 33,788.25 | 12.28 | x 2751.5 WaitAsync(0) | 360.79 | 24.38 | x 14.8 Memory allocations, saves 360MB over the 1M ops
This brings the patch: dotnet/coreclr#6898 Fail faster for `Wait(0)` when no counts available. Don't allocate in the `Wait(0)` and `WaitAsync(0)` fail paths. 1M iters Server GC method | pre (ms) | post (ms) | improvement -------- |------- |------- |------ | Wait(0) | 33,788.25 | 12.28 | x 2751.5 WaitAsync(0) | 360.79 | 24.38 | x 14.8 Memory allocations, saves 360MB over the 1M ops
…ut-0 Semaphoreslim, fail faster for timeout 0 Commit migrated from dotnet/coreclr@8e794b5


Fail faster for
Wait(0)when no counts available.Don't allocate in the
Wait(0)andWaitAsync(0)fail paths.1M iters Server GC
Memory allocations, saves 360MB over the 1M ops