From 1f10addb2c2b6a3f9113052746c8bc9adabe42df Mon Sep 17 00:00:00 2001 From: Ilya Date: Fri, 23 Feb 2018 10:54:50 +0500 Subject: [PATCH 1/3] Set pipeline thread stack size --- .../engine/hostifaces/LocalPipeline.cs | 70 ++++--------------- 1 file changed, 15 insertions(+), 55 deletions(-) diff --git a/src/System.Management.Automation/engine/hostifaces/LocalPipeline.cs b/src/System.Management.Automation/engine/hostifaces/LocalPipeline.cs index 5ed6faaff38..034557de7ad 100644 --- a/src/System.Management.Automation/engine/hostifaces/LocalPipeline.cs +++ b/src/System.Management.Automation/engine/hostifaces/LocalPipeline.cs @@ -20,6 +20,15 @@ namespace System.Management.Automation.Runspaces /// internal sealed class LocalPipeline : PipelineBase { + // Default stack size in bytes for local pipeline threads. + // + // Each platform uses different default for the thread stack size: + // - Windows 2 MB + // - Linux 8 Mb + // - MacOs 512 KB + // We should use the same default for all platforms to get predictable behavior. + internal const int DefaultPipelineStackSize = 10_000_000; + #region constructors /// @@ -152,12 +161,12 @@ protected override void StartPipelineExecution() #if CORECLR //Start execution of pipeline in another thread // No ApartmentState/ThreadStackSize In CoreCLR - Thread invokeThread = new Thread(new ThreadStart(this.InvokeThreadProc)); + Thread invokeThread = new Thread(new ThreadStart(this.InvokeThreadProc), DefaultPipelineStackSize); SetupInvokeThread(invokeThread, true); #else //Start execution of pipeline in another thread // 2004/05/02-JonN Specify maxStack parameter - Thread invokeThread = new Thread(new ThreadStart(this.InvokeThreadProc), MaxStack); + Thread invokeThread = new Thread(new ThreadStart(this.InvokeThreadProc), DefaultPipelineStackSize); SetupInvokeThread(invokeThread, true); ApartmentState apartmentState; @@ -245,55 +254,6 @@ private void SetupInvokeThread(Thread invokeThread, bool changeName) } } -#if !CORECLR - /// - /// Stack Reserve setting for pipeline threads - /// - internal static int MaxStack - { - get - { - int i = ReadRegistryInt("PipelineMaxStackSizeMB", 10); - if (i < 10) - i = 10; // minimum 10MB - else if (i > 100) - i = 100; // maximum 100MB - return i * 1000000; - } - } - - internal static int ReadRegistryInt(string policyValueName, int defaultValue) - { - RegistryKey key; - try - { - key = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\PowerShell\\1\\ShellIds"); - } - catch (System.Security.SecurityException) - { - return defaultValue; - } - if (null == key) - return defaultValue; - - object temp; - try - { - temp = key.GetValue(policyValueName); - } - catch (System.Security.SecurityException) - { - return defaultValue; - } - if (!(temp is int)) - { - return defaultValue; - } - int i = (int)temp; - return i; - } -#endif - /// /// Helper method for asynchronous invoke ///Unhandled FlowControl exception if InvocationSettings.ExposeFlowControlExceptions is true. @@ -1219,17 +1179,17 @@ protected override } /// - /// Helper class that holds the thread used to execute pipelines when CreateThreadOptions.ReuseThread is used + /// Helper class that holds the thread used to execute pipelines when CreateThreadOptions.ReuseThread is used. /// internal class PipelineThread : IDisposable { /// - /// Creates the worker thread and waits for it to be ready + /// Creates the worker thread and waits for it to be ready. /// #if CORECLR internal PipelineThread() { - _worker = new Thread(WorkerProc); + _worker = new Thread(WorkerProc, LocalPipeline.DefaultPipelineStackSize); _workItem = null; _workItemReady = new AutoResetEvent(false); _closed = false; @@ -1237,7 +1197,7 @@ internal PipelineThread() #else internal PipelineThread(ApartmentState apartmentState) { - _worker = new Thread(WorkerProc, LocalPipeline.MaxStack); + _worker = new Thread(WorkerProc, DefaultPipelineStackSize); _workItem = null; _workItemReady = new AutoResetEvent(false); _closed = false; From f406f77cb08ad22e9abb5b5e77ec71fa360df561 Mon Sep 17 00:00:00 2001 From: Ilya Date: Fri, 23 Feb 2018 23:26:06 +0500 Subject: [PATCH 2/3] Move common code and fix typo --- .../engine/hostifaces/LocalPipeline.cs | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/System.Management.Automation/engine/hostifaces/LocalPipeline.cs b/src/System.Management.Automation/engine/hostifaces/LocalPipeline.cs index 034557de7ad..ea62c023b4b 100644 --- a/src/System.Management.Automation/engine/hostifaces/LocalPipeline.cs +++ b/src/System.Management.Automation/engine/hostifaces/LocalPipeline.cs @@ -158,17 +158,11 @@ protected override void StartPipelineExecution() case PSThreadOptions.Default: case PSThreadOptions.UseNewThread: { -#if CORECLR - //Start execution of pipeline in another thread - // No ApartmentState/ThreadStackSize In CoreCLR - Thread invokeThread = new Thread(new ThreadStart(this.InvokeThreadProc), DefaultPipelineStackSize); - SetupInvokeThread(invokeThread, true); -#else - //Start execution of pipeline in another thread - // 2004/05/02-JonN Specify maxStack parameter + // Start execution of pipeline in another thread Thread invokeThread = new Thread(new ThreadStart(this.InvokeThreadProc), DefaultPipelineStackSize); SetupInvokeThread(invokeThread, true); - +#if !CORECLR + // No ApartmentState in CoreCLR ApartmentState apartmentState; if (InvocationSettings != null && InvocationSettings.ApartmentState != ApartmentState.Unknown) @@ -1197,7 +1191,7 @@ internal PipelineThread() #else internal PipelineThread(ApartmentState apartmentState) { - _worker = new Thread(WorkerProc, DefaultPipelineStackSize); + _worker = new Thread(WorkerProc, LocalPipeline.DefaultPipelineStackSize); _workItem = null; _workItemReady = new AutoResetEvent(false); _closed = false; From a339fb381f1c807a6513bd334f03c9ce346084c4 Mon Sep 17 00:00:00 2001 From: Dongbo Wang Date: Fri, 23 Feb 2018 15:31:55 -0800 Subject: [PATCH 3/3] Update the comment for 'DefaultPipelineStackSize' --- .../engine/hostifaces/LocalPipeline.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/System.Management.Automation/engine/hostifaces/LocalPipeline.cs b/src/System.Management.Automation/engine/hostifaces/LocalPipeline.cs index ea62c023b4b..472b38a9334 100644 --- a/src/System.Management.Automation/engine/hostifaces/LocalPipeline.cs +++ b/src/System.Management.Automation/engine/hostifaces/LocalPipeline.cs @@ -20,13 +20,12 @@ namespace System.Management.Automation.Runspaces /// internal sealed class LocalPipeline : PipelineBase { - // Default stack size in bytes for local pipeline threads. - // - // Each platform uses different default for the thread stack size: + // Each OS platform uses different default stack size for threads: // - Windows 2 MB // - Linux 8 Mb // - MacOs 512 KB - // We should use the same default for all platforms to get predictable behavior. + // We should use the same stack size for pipeline threads on all platforms to get predictable behavior. + // The stack size we use for pipeline threads is 10MB, which is inherited from Windows PowerShell. internal const int DefaultPipelineStackSize = 10_000_000; #region constructors