Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Lapounov <antonl@microsoft.com>2017-01-20 01:11:48 +0300
committerAnton Lapounov <antonl@microsoft.com>2017-01-20 01:11:48 +0300
commit70874488d0b71ae376c302827288f8c4806c9b26 (patch)
treefde28677dcc0459c10ab89efdfbbd1f2ddda4cc4
parent1ac148442ddab83c8023a498e086bae7eeabe1fd (diff)
Use native thread id in the Lock class so it may be implemented as a compiler intrinsic on Windows.
CR: SergeyK, EJan [tfs-changeset: 1645128]
-rw-r--r--src/Common/src/Interop/Windows/Interop.Libraries.cs1
-rw-r--r--src/Common/src/Interop/Windows/mincore/Interop.GetCurrentThreadId.cs14
-rw-r--r--src/System.Private.CoreLib/src/Interop/Interop.manual.cs3
-rw-r--r--src/System.Private.CoreLib/src/System.Private.CoreLib.csproj3
-rw-r--r--src/System.Private.CoreLib/src/System/Environment.Unix.cs2
-rw-r--r--src/System.Private.CoreLib/src/System/Environment.Windows.cs2
-rw-r--r--src/System.Private.CoreLib/src/System/Threading/Lock.cs22
7 files changed, 34 insertions, 13 deletions
diff --git a/src/Common/src/Interop/Windows/Interop.Libraries.cs b/src/Common/src/Interop/Windows/Interop.Libraries.cs
index 6740c2cb2..0c1679ed2 100644
--- a/src/Common/src/Interop/Windows/Interop.Libraries.cs
+++ b/src/Common/src/Interop/Windows/Interop.Libraries.cs
@@ -15,6 +15,7 @@ internal static partial class Interop
internal const string IO = "api-ms-win-core-io-l1-1-0.dll";
internal const string Memory = "api-ms-win-core-memory-l1-1-0.dll";
internal const string ProcessEnvironment = "api-ms-win-core-processenvironment-l1-1-0.dll";
+ internal const string ProcessThreads = "api-ms-win-core-processthreads-l1-1-0.dll";
internal const string RealTime = "api-ms-win-core-realtime-l1-1-0.dll";
internal const string SysInfo = "api-ms-win-core-sysinfo-l1-2-0.dll";
internal const string Kernel32 = "api-ms-win-core-kernel32-legacy-l1-1-0.dll";
diff --git a/src/Common/src/Interop/Windows/mincore/Interop.GetCurrentThreadId.cs b/src/Common/src/Interop/Windows/mincore/Interop.GetCurrentThreadId.cs
new file mode 100644
index 000000000..10e850f03
--- /dev/null
+++ b/src/Common/src/Interop/Windows/mincore/Interop.GetCurrentThreadId.cs
@@ -0,0 +1,14 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class mincore
+ {
+ [DllImport(Libraries.ProcessThreads)]
+ internal extern static uint GetCurrentThreadId();
+ }
+}
diff --git a/src/System.Private.CoreLib/src/Interop/Interop.manual.cs b/src/System.Private.CoreLib/src/Interop/Interop.manual.cs
index 08b9a91e5..ffc17b236 100644
--- a/src/System.Private.CoreLib/src/Interop/Interop.manual.cs
+++ b/src/System.Private.CoreLib/src/Interop/Interop.manual.cs
@@ -86,9 +86,6 @@ internal partial class Interop
[DllImport("api-ms-win-core-synch-l1-1-0.dll", EntryPoint = "CreateSemaphoreExW", CharSet = CharSet.Unicode)]
internal static extern IntPtr CreateSemaphoreEx(IntPtr lpSemaphoreAttributes, int lInitialCount, int lMaximumCount, string lpName, uint dwFlags, uint dwDesiredAccess);
- [DllImport("api-ms-win-core-processthreads-l1-1-0.dll")]
- internal extern static uint GetCurrentThreadId();
-
[DllImport("api-ms-win-core-debug-l1-1-0.dll", EntryPoint = "IsDebuggerPresent", CharSet = CharSet.Unicode)]
internal extern static bool IsDebuggerPresent();
diff --git a/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj b/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj
index 4998a45c6..41cce6086 100644
--- a/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj
+++ b/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj
@@ -752,6 +752,9 @@
<Compile Include="..\..\Common\src\Interop\Windows\Interop.BOOL.cs">
<Link>Interop\Windows\Interop.BOOL.cs</Link>
</Compile>
+ <Compile Include="..\..\Common\src\Interop\Windows\mincore\Interop.GetCurrentThreadId.cs">
+ <Link>Interop\Windows\mincore\Interop.GetCurrentThreadId.cs</Link>
+ </Compile>
<Compile Include="..\..\Common\src\Interop\Windows\mincore\Interop.SetLastError.cs">
<Link>Interop\Windows\mincore\Interop.SetLastError.cs</Link>
</Compile>
diff --git a/src/System.Private.CoreLib/src/System/Environment.Unix.cs b/src/System.Private.CoreLib/src/System/Environment.Unix.cs
index bcfdbe4f6..7cf60c683 100644
--- a/src/System.Private.CoreLib/src/System/Environment.Unix.cs
+++ b/src/System.Private.CoreLib/src/System/Environment.Unix.cs
@@ -9,6 +9,8 @@ namespace System
{
public static partial class Environment
{
+ internal static int CurrentNativeThreadId => ManagedThreadId.Current;
+
internal static long TickCount64
{
get
diff --git a/src/System.Private.CoreLib/src/System/Environment.Windows.cs b/src/System.Private.CoreLib/src/System/Environment.Windows.cs
index 7576857a9..3c35f0f7a 100644
--- a/src/System.Private.CoreLib/src/System/Environment.Windows.cs
+++ b/src/System.Private.CoreLib/src/System/Environment.Windows.cs
@@ -6,6 +6,8 @@ namespace System
{
public static partial class Environment
{
+ internal static int CurrentNativeThreadId => unchecked((int)Interop.mincore.GetCurrentThreadId());
+
internal static long TickCount64 => (long)Interop.mincore.GetTickCount64();
public static int ProcessorCount
diff --git a/src/System.Private.CoreLib/src/System/Threading/Lock.cs b/src/System.Private.CoreLib/src/System/Threading/Lock.cs
index e81d5c3cf..1a122c21b 100644
--- a/src/System.Private.CoreLib/src/System/Threading/Lock.cs
+++ b/src/System.Private.CoreLib/src/System/Threading/Lock.cs
@@ -2,9 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-#pragma warning disable 0420 //passing volatile field by reference
-
-
using System.Diagnostics;
using System.Runtime.CompilerServices;
@@ -57,12 +54,14 @@ namespace System.Threading
}
}
- /// <remarks>Inlined version of Lock.Acquire has CurrentManagedThreadId not inlined, non-inlined version has it inlined.
- /// So it saves code to keep this function non inlining while keep the same runtime cost</remarks>
+ // On platforms where CurrentNativeThreadId redirects to ManagedThreadId.Current the inlined
+ // version of Lock.Acquire has the ManagedThreadId.Current call not inlined, while the non-inlined
+ // version has it inlined. So it saves code to keep this function not inlined while having
+ // the same runtime cost.
[MethodImpl(MethodImplOptions.NoInlining)]
public void Acquire()
{
- int currentThreadId = Environment.CurrentManagedThreadId;
+ int currentThreadId = Environment.CurrentNativeThreadId;
//
// Make one quick attempt to acquire an uncontended lock
@@ -95,7 +94,7 @@ namespace System.Threading
if (millisecondsTimeout < -1)
throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
- int currentThreadId = Environment.CurrentManagedThreadId;
+ int currentThreadId = Environment.CurrentNativeThreadId;
//
// Make one quick attempt to acquire an uncontended lock
@@ -231,13 +230,16 @@ namespace System.Threading
get
{
//
+ // The comment below is for platforms where CurrentNativeThreadId redirects to
+ // ManagedThreadId.Current instead of being a compiler intrinsic.
+ //
// Compare the current owning thread ID with the current thread ID. We need
// to read the current thread's ID before we read m_owningThreadId. Otherwise,
// the following might happen:
//
// 1) We read m_owningThreadId, and get, say 42, which belongs to another thread.
// 2) Thread 42 releases the lock, and exits.
- // 3) We call CurrentManagedThreadId. If this is the first time it's been called
+ // 3) We call ManagedThreadId.Current. If this is the first time it's been called
// on this thread, we'll go get a new ID. We may reuse thread 42's ID, since
// that thread is dead.
// 4) Now we're thread 42, and it looks like we own the lock, even though we don't.
@@ -246,8 +248,8 @@ namespace System.Threading
// because while we're doing this check the current thread is definitely still
// alive.
//
- int currentManagedThreadId = Environment.CurrentManagedThreadId;
- bool acquired = (currentManagedThreadId == _owningThreadId);
+ int currentThreadId = Environment.CurrentNativeThreadId;
+ bool acquired = (currentThreadId == _owningThreadId);
if (acquired)
Debug.Assert((_state & Locked) != 0);
return acquired;