1 // Licensed to the .NET Foundation under one or more agreements. 2 // The .NET Foundation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 /*============================================================ 6 ** 7 ** 8 ** 9 ** Purpose: Provides some basic access to some environment 10 ** functionality. 11 ** 12 ** 13 ============================================================*/ 14 15 using System.Diagnostics; 16 using System.Runtime.CompilerServices; 17 using System.Threading; 18 19 using Internal.Runtime.Augments; 20 21 namespace System 22 { 23 public enum EnvironmentVariableTarget 24 { 25 Process = 0, 26 User = 1, 27 Machine = 2, 28 } 29 30 internal static partial class Environment 31 { 32 /*==================================TickCount=================================== 33 **Action: Gets the number of ticks since the system was started. 34 **Returns: The number of ticks since the system was started. 35 **Arguments: None 36 **Exceptions: None 37 ==============================================================================*/ 38 public static int TickCount 39 { 40 get 41 { 42 return (int)TickCount64; 43 } 44 } 45 46 //// Note: The CLR's Watson bucketization code looks at the caller of the FCALL method 47 //// to assign blame for crashes. Don't mess with this, such as by making it call 48 //// another managed helper method, unless you consult with some CLR Watson experts. 49 50 FailFast(String message)51 public static void FailFast(String message) 52 { 53 RuntimeExceptionHelpers.FailFast(message); 54 } 55 FailFast(String message, Exception exception)56 public static void FailFast(String message, Exception exception) 57 { 58 RuntimeExceptionHelpers.FailFast(message, exception); 59 } 60 61 // Still needed by shared\System\Diagnostics\Debug.Unix.cs GetEnvironmentVariable(string variable)62 public static string GetEnvironmentVariable(string variable) => EnvironmentAugments.GetEnvironmentVariable(variable); 63 64 public static int CurrentManagedThreadId 65 { 66 get 67 { 68 return ManagedThreadId.Current; 69 } 70 } 71 72 // The upper bits of t_executionIdCache are the executionId. The lower bits of 73 // the t_executionIdCache are counting down to get it periodically refreshed. 74 // TODO: Consider flushing the executionIdCache on Wait operations or similar 75 // actions that are likely to result in changing the executing core 76 [ThreadStatic] 77 private static int t_executionIdCache; 78 79 private const int ExecutionIdCacheShift = 16; 80 private const int ExecutionIdCacheCountDownMask = (1 << ExecutionIdCacheShift) - 1; 81 private const int ExecutionIdRefreshRate = 5000; 82 RefreshExecutionId()83 private static int RefreshExecutionId() 84 { 85 int executionId = ComputeExecutionId(); 86 87 Debug.Assert(ExecutionIdRefreshRate <= ExecutionIdCacheCountDownMask); 88 89 // Mask with Int32.MaxValue to ensure the execution Id is not negative 90 t_executionIdCache = ((executionId << ExecutionIdCacheShift) & Int32.MaxValue) + ExecutionIdRefreshRate; 91 92 return executionId; 93 } 94 95 // Cached processor number used as a hint for which per-core stack to access. It is periodically 96 // refreshed to trail the actual thread core affinity. 97 internal static int CurrentExecutionId 98 { 99 [MethodImpl(MethodImplOptions.AggressiveInlining)] 100 get 101 { 102 int executionIdCache = t_executionIdCache--; 103 if ((executionIdCache & ExecutionIdCacheCountDownMask) == 0) 104 return RefreshExecutionId(); 105 return (executionIdCache >> ExecutionIdCacheShift); 106 } 107 } 108 109 public static bool HasShutdownStarted 110 { 111 get 112 { 113 // .NET Core does not have shutdown finalization 114 return false; 115 } 116 } 117 118 /*===================================NewLine==================================== 119 **Action: A property which returns the appropriate newline string for the given 120 ** platform. 121 **Returns: \r\n on Win32. 122 **Arguments: None. 123 **Exceptions: None. 124 ==============================================================================*/ 125 public static String NewLine 126 { 127 get 128 { 129 #if !PLATFORM_UNIX 130 return "\r\n"; 131 #else 132 return "\n"; 133 #endif // !PLATFORM_UNIX 134 } 135 } 136 137 public static String StackTrace 138 { 139 // Disable inlining to have predictable stack frame that EnvironmentAugments can skip 140 [MethodImpl(MethodImplOptions.NoInlining)] 141 get 142 { 143 return EnvironmentAugments.StackTrace; 144 } 145 } 146 147 public static int ProcessorCount 148 { 149 get 150 { 151 return Runtime.RuntimeImports.RhGetProcessCpuCount(); 152 } 153 } 154 } 155 } 156