Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate coreclr's worker thread pool to be able to use the portable thread pool in opt-in fashion #38225

Merged
merged 48 commits into from
Oct 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
da29c61
Add dependencies
kouvel Mar 4, 2020
423d830
Add config var
kouvel Mar 4, 2020
ad228ef
Move portable RegisteredWaitHandle implementation to shared ThreadPoo…
kouvel Mar 9, 2020
1155fb0
Merge RegisteredWaitHandle implementations
kouvel Mar 4, 2020
6f9b3dc
Separate portable-only portion of RegisteredWaitHandle
kouvel May 24, 2020
d792cd7
Fix timers, tiered compilation, introduced time-sensitive work item q…
kouvel Mar 15, 2020
a911883
Implement ResetThreadPoolThread, set thread names for diagnostics
kouvel Mar 15, 2020
40ce9d0
Cache-line-separate PortableThreadPool._numRequestedWorkers similarly…
kouvel Mar 16, 2020
a5d3c2b
Post wait completions to the IO completion port on Windows for corecl…
kouvel Mar 17, 2020
ad632be
Reroute managed gate thread into unmanaged side to perform gate activ…
kouvel Mar 18, 2020
f942773
Flow config values from CoreCLR to the portable thread pool for compat
kouvel Mar 22, 2020
0ef2079
Port - 44970522045f0c323f5735c4fe4b54bd8f71e800 - Fix hill climbing f…
kouvel Mar 23, 2020
3151057
Port - aa5ce2b1bc9ac553ddd493e269a53c999d61e965 - Limit min threads i…
kouvel Mar 23, 2020
5d8d4ae
Port - 8cc2aa35933677339b9e9ec5485754aa750907df - Optimize AdjustMaxW…
kouvel Mar 24, 2020
3916619
Fix ETW events
kouvel Mar 25, 2020
88ea9c4
Fix perf of counts structs
kouvel Mar 27, 2020
8ef63f9
Fix perf of dispatch loop
kouvel Mar 28, 2020
e01df4f
Fix perf of ThreadInt64PersistentCounter
kouvel Mar 29, 2020
7c89f81
Miscellaneous perf fixes
kouvel Apr 1, 2020
13c2d62
Fix starvation heuristic
kouvel Jun 1, 2020
dd23472
Implement worker tracking
kouvel May 23, 2020
6cd2b2d
Use smaller stack size for threads that don't run user code
kouvel May 27, 2020
c8bdfad
Note some SOS dependencies, small fixes in hill climbing to make equi…
kouvel Jun 1, 2020
38c00d5
Port some tests from CoreRT
kouvel Jun 7, 2020
0ff3b03
Fail-fast in thread pool native entry points specific to thread pool …
kouvel Jun 7, 2020
cc35f92
Fix SetMinThreads() and SetMaxThreads() to return true only when both…
kouvel Jun 8, 2020
79eb3b9
Fix registered wait removals for fairness since there can be duplicat…
kouvel Jun 9, 2020
8b309cc
Allow multiple DotNETRuntime event providers/sources in EventPipe
kouvel Jun 12, 2020
ac1917d
Fix registered wait handle timeout logic in the wait thread
kouvel Jun 16, 2020
73f911c
Fix Browser build
kouvel Jun 22, 2020
1b99da7
Remove unnecessary methods from Browser thread pool, address some fee…
kouvel Jun 24, 2020
17b3d2d
Fix build warning after merge
kouvel Jun 30, 2020
e8043ff
Address feedback for events, undo EventPipe change in mono, change ev…
kouvel Jun 30, 2020
8d9cc2d
Disable new timer test for browser
kouvel Jul 1, 2020
f03709b
Fix EventSource tests to expect the new provider name used in mono
kouvel Jul 1, 2020
ff48985
Revert event source name in mono to match coreclr
kouvel Jul 3, 2020
93563e6
Add issue link for prerequisites of enabling the portable thread pool…
kouvel Jul 3, 2020
100dad7
Address feedback
kouvel Jul 6, 2020
4c7f778
Fix race condition in registered wait unregister
kouvel Jul 11, 2020
d55c5fc
Fix a new issue in WaitThread after shifting items in arrays
kouvel Jul 12, 2020
996597f
Fix usage of LowLevelMonitor after rebase
kouvel Sep 10, 2020
82f7cda
Fix tests that use RemoteExecutor to include a test for whether it is…
kouvel Sep 11, 2020
b53a5b9
Fix build
kouvel Sep 11, 2020
7dcb267
Slight fix to starvation heuristic to be closer to what it was before
kouvel Sep 25, 2020
65840d8
Fix license headers in new files
kouvel Oct 9, 2020
fb28ad2
Address feedback
kouvel Oct 9, 2020
04326b6
Change pattern for accessing the event source for better ILLinker com…
kouvel Oct 16, 2020
ec038cf
Move hill climbing config reads into constructor instead of passing t…
kouvel Oct 16, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
<ILLinkTrimAssembly>true</ILLinkTrimAssembly>
<ILLinkTrimXml>$(IntermediateOutputPath)System.Private.CoreLib.xml</ILLinkTrimXml>
<ILLinkDirectory>$(MSBuildThisFileDirectory)src\ILLink\</ILLinkDirectory>

<FeaturePortableThreadPool>true</FeaturePortableThreadPool>
<FeatureSharedLowLevelLock>true</FeatureSharedLowLevelLock>
</PropertyGroup>

<!-- Note that various places in SPCL depend on this resource name i.e. TplEventSource -->
Expand Down Expand Up @@ -289,6 +292,7 @@
<Compile Include="$(BclSourcesRoot)\Interop\Unix\Interop.Libraries.cs" />
<Compile Include="$(BclSourcesRoot)\System\DateTime.Unix.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\Threading\ClrThreadPoolBoundHandle.Unix.cs" />
<Compile Include="$(BclSourcesRoot)\System\Threading\LowLevelLifoSemaphore.Unix.cs" />
</ItemGroup>
<ItemGroup Condition="'$(TargetsWindows)' == 'true'">
<Compile Include="$(BclSourcesRoot)\System\DateTime.Windows.CoreCLR.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;

namespace System.Threading
{
/// <summary>
/// A LIFO semaphore implemented using the PAL's semaphore with uninterruptible waits.
/// </summary>
internal sealed partial class LowLevelLifoSemaphore : IDisposable
{
private Semaphore? _semaphore;

private void Create(int maximumSignalCount)
{
Debug.Assert(maximumSignalCount > 0);
_semaphore = new Semaphore(0, maximumSignalCount);
}

public bool WaitCore(int timeoutMs)
{
Debug.Assert(_semaphore != null);
Debug.Assert(timeoutMs >= -1);

int waitResult = WaitNative(_semaphore!.SafeWaitHandle, timeoutMs);
Debug.Assert(waitResult == WaitHandle.WaitSuccess || waitResult == WaitHandle.WaitTimeout);
return waitResult == WaitHandle.WaitSuccess;
}

[DllImport(RuntimeHelpers.QCall, CharSet = CharSet.Unicode)]
private static extern int WaitNative(SafeWaitHandle handle, int timeoutMs);

public void ReleaseCore(int count)
{
Debug.Assert(_semaphore != null);
Debug.Assert(count > 0);

_semaphore!.Release(count);
}

public void Dispose()
{
Debug.Assert(_semaphore != null);
_semaphore!.Dispose();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,11 @@ public sealed partial class Thread
private int _managedThreadId; // INT32
#pragma warning restore CA1823, 169

// This is used for a quick check on thread pool threads after running a work item to determine if the name, background
// state, or priority were changed by the work item, and if so to reset it. Other threads may also change some of those,
// but those types of changes may race with the reset anyway, so this field doesn't need to be synchronized.
private bool _mayNeedResetForThreadPool;

private Thread() { }

private void Create(ThreadStart start) =>
Expand Down Expand Up @@ -259,6 +264,9 @@ private void SetCultureOnUnstartedThreadNoCheck(CultureInfo value, bool uiCultur

public static void Sleep(int millisecondsTimeout) => SleepInternal(millisecondsTimeout);

[DllImport(RuntimeHelpers.QCall)]
internal static extern void UninterruptibleSleep0();

/// <summary>
/// Wait for a length of time proportional to 'iterations'. Each iteration is should
/// only take a few machine instructions. Calling this API is preferable to coding
Expand Down Expand Up @@ -337,7 +345,14 @@ public extern bool IsAlive
public bool IsBackground
{
get => IsBackgroundNative();
set => SetBackgroundNative(value);
set
{
SetBackgroundNative(value);
if (!value)
{
_mayNeedResetForThreadPool = true;
}
}
}

[MethodImpl(MethodImplOptions.InternalCall)]
Expand All @@ -351,13 +366,22 @@ public extern bool IsThreadPoolThread
{
[MethodImpl(MethodImplOptions.InternalCall)]
get;
[MethodImpl(MethodImplOptions.InternalCall)]
internal set;
}

/// <summary>Returns the priority of the thread.</summary>
public ThreadPriority Priority
{
get => (ThreadPriority)GetPriorityNative();
set => SetPriorityNative((int)value);
set
{
SetPriorityNative((int)value);
if (value != ThreadPriority.Normal)
{
_mayNeedResetForThreadPool = true;
}
}
}

[MethodImpl(MethodImplOptions.InternalCall)]
Expand Down Expand Up @@ -503,12 +527,23 @@ public static int GetCurrentProcessorId()
// we will record that in a readonly static so that it could become a JIT constant and bypass caching entirely.
private static readonly bool s_isProcessorNumberReallyFast = ProcessorIdCache.ProcessorNumberSpeedCheck();

#pragma warning disable CA1822 // Mark members as static
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void ResetThreadPoolThread()
{
// Currently implemented in unmanaged method Thread::InternalReset and
// called internally from the ThreadPool in NotifyWorkItemComplete.
Debug.Assert(this == CurrentThread);
Debug.Assert(IsThreadPoolThread);

if (!ThreadPool.UsePortableThreadPool)
{
// Currently implemented in unmanaged method Thread::InternalReset and
// called internally from the ThreadPool in NotifyWorkItemComplete.
return;
}

if (_mayNeedResetForThreadPool)
{
ResetThreadPoolThreadSlow();
}
}
#pragma warning restore CA1822
} // End of class Thread
}
Loading