Make GetCurrentProcessorNumber an FCall
authorStephen Toub <stoub@microsoft.com>
Fri, 25 Nov 2016 04:39:15 +0000 (23:39 -0500)
committerStephen Toub <stoub@microsoft.com>
Mon, 28 Nov 2016 15:51:45 +0000 (10:51 -0500)
src/classlibnative/bcltype/system.cpp
src/classlibnative/bcltype/system.h
src/mscorlib/corefx/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.Unix.cs
src/mscorlib/corefx/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.Windows.cs
src/mscorlib/corefx/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs
src/mscorlib/src/Microsoft/Win32/Win32Native.cs
src/mscorlib/src/System/Environment.cs
src/vm/ecalllist.h

index bb3e179..8bb3409 100644 (file)
@@ -63,6 +63,16 @@ FCIMPLEND;
 
 
 
+FCIMPL0(UINT32, SystemNative::GetCurrentProcessorNumber)
+{
+    FCALL_CONTRACT;
+
+    return ::GetCurrentProcessorNumber();
+}
+FCIMPLEND;
+
+
+
 FCIMPL0(UINT32, SystemNative::GetTickCount)
 {
     FCALL_CONTRACT;
index 60355b3..9edc595 100644 (file)
@@ -72,6 +72,7 @@ private:
 public:
     // Functions on the System.Environment class
     static FCDECL0(INT64, __GetSystemTimeAsFileTime);
+    static FCDECL0(UINT32, GetCurrentProcessorNumber);
     static FCDECL0(UINT32, GetTickCount);
     static FCDECL1(FC_BOOL_RET, GetOSVersion, OSVERSIONINFOObject *osVer);
     static FCDECL1(FC_BOOL_RET, GetOSVersionEx, OSVERSIONINFOEXObject *osVer);
index 2a0b1f7..8a1d006 100644 (file)
@@ -15,11 +15,11 @@ namespace System.Buffers
             [MethodImpl(MethodImplOptions.AggressiveInlining)]
             get
             {
-                // On Unix, GetCurrentProcessorNumber is implemented in terms of sched_getcpu, which
+                // On Unix, CurrentProcessorNumber is implemented in terms of sched_getcpu, which
                 // doesn't exist on all platforms.  On those it doesn't exist on, GetCurrentProcessorNumber
                 // returns -1.  As a fallback in that case and to spread the threads across the buckets
                 // by default, we use the current managed thread ID as a proxy.
-                int id = GetCurrentProcessorNumber();
+                int id = CurrentProcessorNumber;
                 if (id < 0) id = Environment.CurrentManagedThreadId;
                 return id;
             }
index 4ec158d..d42242c 100644 (file)
@@ -14,7 +14,7 @@ namespace System.Buffers
         private static int ExecutionId
         {
             [MethodImpl(MethodImplOptions.AggressiveInlining)]
-            get { return GetCurrentProcessorNumber(); }
+            get { return CurrentProcessorNumber; }
         }
     }
 }
index 3d2b1e2..debc336 100644 (file)
@@ -25,7 +25,6 @@ namespace System.Buffers
         // - Explore dumping stale buffers from the global queue, similar to PinnableBufferCache (maybe merging them).
         // - Explore changing the size of each per-core bucket, potentially dynamically or based on other factors like array size.
         // - Explore changing number of buckets and what sizes of arrays are cached.
-        // - Measure making GetCurrentProcessorNumber an FCall rather than a P/Invoke.
         // - Investigate whether false sharing is causing any issues, in particular on LockedStack's count and the contents of its array.
         // ...
 
@@ -75,15 +74,18 @@ namespace System.Buffers
 
         /// <summary>Gets the processor number associated with the current thread.</summary>
         /// <remarks>Uses a cached value if one exists on the current thread.</remarks>
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        private static int GetCurrentProcessorNumber()
+        private static int CurrentProcessorNumber
         {
-            int? num = t_cachedProcessorNumber;
-            if (!num.HasValue)
+            [MethodImpl(MethodImplOptions.AggressiveInlining)]
+            get
             {
-                t_cachedProcessorNumber = num = Win32Native.GetCurrentProcessorNumber();
+                int? num = t_cachedProcessorNumber;
+                if (!num.HasValue)
+                {
+                    t_cachedProcessorNumber = num = Environment.CurrentProcessorNumber;
+                }
+                return num.GetValueOrDefault();
             }
-            return num.GetValueOrDefault();
         }
 
         public override T[] Rent(int minimumLength)
index cb15ee8..0931cba 100644 (file)
@@ -725,9 +725,6 @@ namespace Microsoft.Win32 {
         [DllImport(KERNEL32, SetLastError=true)]
         internal static extern void GetSystemInfo(ref SYSTEM_INFO lpSystemInfo);
 
-        [DllImport(KERNEL32)]
-        internal static extern int GetCurrentProcessorNumber();
-
         [DllImport(KERNEL32, CharSet=CharSet.Auto, BestFitMapping=true)]
         internal static extern int FormatMessage(int dwFlags, IntPtr lpSource,
                     int dwMessageId, int dwLanguageId, [Out]StringBuilder lpBuffer,
index aa192b9..f55a80b 100644 (file)
@@ -1815,5 +1815,11 @@ namespace System {
             }
         }
 
+        internal static extern int CurrentProcessorNumber
+        {
+            [System.Security.SecuritySafeCritical]
+            [MethodImplAttribute(MethodImplOptions.InternalCall)]
+            get;
+        }
     }
 }
index d5063c4..f87fafc 100644 (file)
@@ -288,6 +288,7 @@ FCFuncStart(gEnvironmentFuncs)
     FCFuncElement("GetResourceFromDefault", GetResourceFromDefault)
 #endif // !FEATURE_CORECLR
     FCFuncElement("GetCommandLineArgsNative", SystemNative::GetCommandLineArgs)
+    FCFuncElement("get_CurrentProcessorNumber", SystemNative::GetCurrentProcessorNumber)
 
 #if defined(FEATURE_COMINTEROP) && !defined(FEATURE_CORESYSTEM)
     QCFuncElement("WinRTSupported", SystemNative::WinRTSupported)