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-08-04 03:14:30 +0300
committerAnton Lapounov <antonl@microsoft.com>2017-08-04 03:14:30 +0300
commitd1c4689abe76bda148cda44973d7178123265184 (patch)
treef02a194f31624156ee576d4866879eb1fe618c9a /src/System.Private.Interop
parent64fb7118f6ef5399ed5969719bf94b829e9041e4 (diff)
Fix async call performance regression
Bugs: • https://devdiv.visualstudio.com/DevDiv/_workitems/edit/470211 • https://devdiv.visualstudio.com/DevDiv/_workitems/edit/205405 CR: AdityaM To schedule an asynchronous call, we perform several WinRT calls to check whether the current thread has either a CoreDispatcher or a DispatcherQueue associated with it. These calls, especially the recently added ones related to DispatcherQueue support, are expensive and make async calls around 3 times slower than on desktop CLR on a microbenchmark. This change implements a number of optimizations based on a discussion with Windows developers: • Skip checking for CoreDispatcher/DispatcherQueue on non-[A]STA threads. • Skip checking for CoreDispatcher for desktop apps. (CoreDispatcher is not supported for desktop apps.) • Cache the IDispatcherQueueStatics interface pointer instead of calling RoGetActivationFactory on each async call. • Avoid an unnecessary closure object allocation in FactoryCache.GetActivationFactory. I had to change WinRTCallbacks.s_resourceContextQualifierMap initialization, because it would crash for desktop apps. (The class constructor would never be called for desktop apps before I added extra static fields.) I also deleted the orphaned Interop.WinRT.cs file. [tfs-changeset: 1669116]
Diffstat (limited to 'src/System.Private.Interop')
-rw-r--r--src/System.Private.Interop/src/Shared/__ComObject.cs18
-rw-r--r--src/System.Private.Interop/src/WinRT/Interop.WinRT.cs95
2 files changed, 4 insertions, 109 deletions
diff --git a/src/System.Private.Interop/src/Shared/__ComObject.cs b/src/System.Private.Interop/src/Shared/__ComObject.cs
index ea151f4d6..e0856f8bb 100644
--- a/src/System.Private.Interop/src/Shared/__ComObject.cs
+++ b/src/System.Private.Interop/src/Shared/__ComObject.cs
@@ -3311,8 +3311,6 @@ namespace System.Runtime.InteropServices
/// <returns>Return true if winning race. False otherwise</returns>
internal bool Assign(IntPtr pComPtr, RuntimeTypeHandle handle)
{
- // disable warning for ref volatile
-#pragma warning disable 0420
if (Interlocked.CompareExchange(ref ptr, pComPtr, default(IntPtr)) == default(IntPtr))
{
Debug.Assert(!HasValue, "Entry should be empty");
@@ -3330,7 +3328,6 @@ namespace System.Runtime.InteropServices
{
return false;
}
-#pragma warning restore 0420
}
/// <summary>
@@ -3909,19 +3906,16 @@ namespace System.Runtime.InteropServices
/// </summary>
internal class FactoryCache
{
- private Lock m_factoryLock = new Lock();
private System.Collections.Concurrent.ConcurrentDictionary<string, FactoryCacheItem> m_cachedFactories = new System.Collections.Concurrent.ConcurrentDictionary<string, FactoryCacheItem>();
private static volatile FactoryCache s_factoryCache;
internal static FactoryCache Get()
{
-#pragma warning disable 0420
if (s_factoryCache == null)
{
Interlocked.CompareExchange(ref s_factoryCache, new FactoryCache(), null);
}
-#pragma warning restore 0420
return s_factoryCache;
}
@@ -3965,12 +3959,10 @@ namespace System.Runtime.InteropServices
FactoryCacheItem cacheItem;
-
if (!skipCache)
{
-
- if (m_cachedFactories.TryGetValue(className, out cacheItem))
- {
+ if (m_cachedFactories.TryGetValue(className, out cacheItem))
+ {
if (cacheItem.contextEntry == currentContext)
{
//
@@ -3978,8 +3970,7 @@ namespace System.Runtime.InteropServices
//
return cacheItem.factoryObject;
}
- }
-
+ }
}
//
@@ -3996,12 +3987,11 @@ namespace System.Runtime.InteropServices
//
// Insert into or update cache
//
- m_cachedFactories.AddOrUpdate(className, cacheItem, (key, oldValue) => cacheItem);
+ m_cachedFactories[className] = cacheItem;
}
return cacheItem.factoryObject;
}
-
}
#endif
}
diff --git a/src/System.Private.Interop/src/WinRT/Interop.WinRT.cs b/src/System.Private.Interop/src/WinRT/Interop.WinRT.cs
deleted file mode 100644
index 31a7f252b..000000000
--- a/src/System.Private.Interop/src/WinRT/Interop.WinRT.cs
+++ /dev/null
@@ -1,95 +0,0 @@
-// 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;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Text;
-
-partial class Interop
-{
-
- internal unsafe partial class WinRT
- {
- // Converts a ASCII (code<0x7f) string to byte array
- internal static byte[] AsciiStringToByteArray(string ascii)
- {
- byte[] ret = new byte[ascii.Length + 1];
- int index;
-
- for (index = 0; index < ascii.Length; index++)
- {
- ret[index] = (byte)ascii[index];
- }
-
- ret[index] = 0;
-
- return ret;
- }
-
- internal static unsafe void RoGetActivationFactory(string className, ref Guid iid, out IntPtr ppv)
- {
- fixed (char* unsafe_className = className)
- {
- void* hstring_typeName = null;
-
- HSTRING_HEADER hstringHeader;
- int hr =
- WindowsCreateStringReference(
- unsafe_className, (uint)className.Length, &hstringHeader, &hstring_typeName);
-
- if (hr < 0)
- throw Marshal.GetExceptionForHR(hr);
-
- fixed (Guid* unsafe_iid = &iid)
- {
- fixed (void* unsafe_ppv = &ppv)
- {
- hr = ExternalInterop.RoGetActivationFactory(
- hstring_typeName,
- unsafe_iid,
- unsafe_ppv);
-
- if (hr < 0)
- throw Marshal.GetExceptionForHR(hr);
- }
- }
- }
- }
-
- [DllImport(Interop.CORE_WINRT_STRING)]
- [McgGeneratedNativeCallCodeAttribute]
- [MethodImplAttribute(MethodImplOptions.NoInlining)]
- internal static extern unsafe int WindowsCreateString(char* sourceString, uint length, void* hstring);
-
- [DllImport(Interop.CORE_WINRT_STRING)]
- [McgGeneratedNativeCallCodeAttribute]
- [MethodImplAttribute(MethodImplOptions.NoInlining)]
- internal static extern unsafe int WindowsCreateStringReference(
- char* sourceString, uint length, HSTRING_HEADER* phstringHeader, void* hstring);
-
- [DllImport(Interop.CORE_WINRT_ERROR, PreserveSig = true)]
- [McgGeneratedNativeCallCodeAttribute]
- public static extern int GetRestrictedErrorInfo(out System.IntPtr pRestrictedErrorInfo);
-
- [DllImport(Interop.CORE_WINRT_ERROR, PreserveSig = true)]
- [McgGeneratedNativeCallCodeAttribute]
- [MethodImplAttribute(MethodImplOptions.NoInlining)]
- public static extern int RoOriginateError(int hr, HSTRING hstring);
-
- [DllImport(Interop.CORE_WINRT_ERROR, PreserveSig = true)]
- [McgGeneratedNativeCallCodeAttribute]
- [MethodImplAttribute(MethodImplOptions.NoInlining)]
- public static extern int SetRestrictedErrorInfo(System.IntPtr pRestrictedErrorInfo);
-
- [DllImport(Interop.CORE_WINRT_ERROR1, PreserveSig = true)]
- [McgGeneratedNativeCallCodeAttribute]
- internal static extern int RoOriginateLanguageException(int hr, HSTRING message, IntPtr pLanguageException);
-
- [DllImport(Interop.CORE_WINRT_ERROR1, PreserveSig = true)]
- [McgGeneratedNativeCallCodeAttribute]
- internal static extern int RoReportUnhandledError(IntPtr pRestrictedErrorInfo);
- }
-
-}