From 5d0199356f724d06eeb077e580387691127e8178 Mon Sep 17 00:00:00 2001 From: Maciej Paszta Date: Tue, 21 Jun 2011 11:47:05 +0200 Subject: [PATCH 1/8] add readme (cherry picked from commit 0d0b555e2a8e5f5d03794ab938b12632a3356190) --- README | 1 + 1 file changed, 1 insertion(+) create mode 100644 README diff --git a/README b/README new file mode 100644 index 0000000..ceb5fa6 --- /dev/null +++ b/README @@ -0,0 +1 @@ +Fork of SmartThreadPool (http://http://smartthreadpool.codeplex.com). \ No newline at end of file From 17f4f597068acf0559870a47e5af4413a4aa61f9 Mon Sep 17 00:00:00 2001 From: Michal Staszewski Date: Tue, 21 Jun 2011 14:15:17 +0200 Subject: [PATCH 2/8] CHG: STP threads can now be foreground (cherry picked from commit b29bd9578aa4b9ec6b84137ae5ab00d0a410c8e0) --- SmartThreadPool/STPStartInfo.cs | 15 +++++++++++++++ SmartThreadPool/SmartThreadPool.cs | 7 ++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/SmartThreadPool/STPStartInfo.cs b/SmartThreadPool/STPStartInfo.cs index c4a8e07..fdab702 100644 --- a/SmartThreadPool/STPStartInfo.cs +++ b/SmartThreadPool/STPStartInfo.cs @@ -13,6 +13,7 @@ namespace Amib.Threading private int _maxWorkerThreads = SmartThreadPool.DefaultMaxWorkerThreads; private ThreadPriority _threadPriority = SmartThreadPool.DefaultThreadPriority; private string _performanceCounterInstanceName = SmartThreadPool.DefaultPerformanceCounterInstanceName; + private bool _areThreadsBackground = SmartThreadPool.DefaultAreThreadsBackground; private bool _enableLocalPerformanceCounters; public STPStartInfo() @@ -33,6 +34,7 @@ namespace Amib.Threading _threadPriority = stpStartInfo.ThreadPriority; _performanceCounterInstanceName = stpStartInfo.PerformanceCounterInstanceName; _enableLocalPerformanceCounters = stpStartInfo._enableLocalPerformanceCounters; + _areThreadsBackground = stpStartInfo.AreThreadsBackground; } @@ -123,6 +125,19 @@ namespace Amib.Threading } } + /// + /// Get/Set backgroundness of thread in thread pool. + /// + public virtual bool AreThreadsBackground + { + get { return _areThreadsBackground; } + set + { + ThrowIfReadOnly (); + _areThreadsBackground = value; + } + } + /// /// Get a readonly version of this STPStartInfo. /// diff --git a/SmartThreadPool/SmartThreadPool.cs b/SmartThreadPool/SmartThreadPool.cs index 2b0202f..9853d72 100644 --- a/SmartThreadPool/SmartThreadPool.cs +++ b/SmartThreadPool/SmartThreadPool.cs @@ -164,6 +164,11 @@ namespace Amib.Threading /// It is relevant only to QueueWorkItem of Action<...>/Func<...> /// public const bool DefaultFillStateWithArgs = false; + + /// + /// The default thread backgroundness. (true) + /// + public const bool DefaultAreThreadsBackground = true; #endregion @@ -608,7 +613,7 @@ namespace Amib.Threading // Configure the new thread and start it workerThread.Name = "STP " + Name + " Thread #" + _threadCounter; - workerThread.IsBackground = true; + workerThread.IsBackground = _stpStartInfo.AreThreadsBackground; #if !(_SILVERLIGHT) workerThread.Priority = _stpStartInfo.ThreadPriority; #endif From c71422756d8781eea3232e05b09b0a07b5cc3d04 Mon Sep 17 00:00:00 2001 From: Michal Staszewski Date: Tue, 21 Jun 2011 14:16:16 +0200 Subject: [PATCH 3/8] CHG: tasks can have priority (cherry picked from commit 3ec0a40dc9b43b4b11082a3e0d618c266a809522) --- SmartThreadPool/Interfaces.cs | 32 ++++++++- SmartThreadPool/WorkItemsGroupBase.cs | 94 +++++++++++++++++---------- 2 files changed, 92 insertions(+), 34 deletions(-) diff --git a/SmartThreadPool/Interfaces.cs b/SmartThreadPool/Interfaces.cs index ad8c63f..5b17f2b 100644 --- a/SmartThreadPool/Interfaces.cs +++ b/SmartThreadPool/Interfaces.cs @@ -271,7 +271,19 @@ namespace Amib.Threading /// Queue a work item. /// /// Returns a IWorkItemResult object, but its GetResult() will always return null - IWorkItemResult QueueWorkItem(Action action, T arg); + IWorkItemResult QueueWorkItem (Action action, WorkItemPriority priority); + + /// + /// Queue a work item. + /// + /// Returns a IWorkItemResult object, but its GetResult() will always return null + IWorkItemResult QueueWorkItem (Action action, T arg, WorkItemPriority priority); + + /// + /// Queue a work item. + /// + /// Returns a IWorkItemResult object, but its GetResult() will always return null + IWorkItemResult QueueWorkItem (Action action, T arg); /// /// Queue a work item. @@ -279,18 +291,36 @@ namespace Amib.Threading /// Returns a IWorkItemResult object, but its GetResult() will always return null IWorkItemResult QueueWorkItem(Action action, T1 arg1, T2 arg2); + /// + /// Queue a work item. + /// + /// Returns a IWorkItemResult object, but its GetResult() will always return null + IWorkItemResult QueueWorkItem (Action action, T1 arg1, T2 arg2, WorkItemPriority priority); + /// /// Queue a work item. /// /// Returns a IWorkItemResult object, but its GetResult() will always return null IWorkItemResult QueueWorkItem(Action action, T1 arg1, T2 arg2, T3 arg3); + /// + /// Queue a work item. + /// + /// Returns a IWorkItemResult object, but its GetResult() will always return null + IWorkItemResult QueueWorkItem (Action action, T1 arg1, T2 arg2, T3 arg3, WorkItemPriority priority); + /// /// Queue a work item. /// /// Returns a IWorkItemResult object, but its GetResult() will always return null IWorkItemResult QueueWorkItem(Action action, T1 arg1, T2 arg2, T3 arg3, T4 arg4); + /// + /// Queue a work item. + /// + /// Returns a IWorkItemResult object, but its GetResult() will always return null + IWorkItemResult QueueWorkItem (Action action, T1 arg1, T2 arg2, T3 arg3, T4 arg4, WorkItemPriority priority); + #endregion #region QueueWorkItem(Func<...>) diff --git a/SmartThreadPool/WorkItemsGroupBase.cs b/SmartThreadPool/WorkItemsGroupBase.cs index 106a1df..27fae5e 100644 --- a/SmartThreadPool/WorkItemsGroupBase.cs +++ b/SmartThreadPool/WorkItemsGroupBase.cs @@ -278,82 +278,110 @@ namespace Amib.Threading.Internal public IWorkItemResult QueueWorkItem(Action action) { - PreQueueWorkItem(); - WorkItem workItem = WorkItemFactory.CreateWorkItem( + return QueueWorkItem (action, SmartThreadPool.DefaultWorkItemPriority); + } + + public IWorkItemResult QueueWorkItem (Action action, WorkItemPriority priority) + { + PreQueueWorkItem (); + WorkItem workItem = WorkItemFactory.CreateWorkItem ( this, WIGStartInfo, delegate { - action.Invoke(); + action.Invoke (); return null; - }); - Enqueue(workItem); - return workItem.GetWorkItemResult(); + }, priority); + Enqueue (workItem); + return workItem.GetWorkItemResult (); } public IWorkItemResult QueueWorkItem(Action action, T arg) { - PreQueueWorkItem(); - WorkItem workItem = WorkItemFactory.CreateWorkItem( + return QueueWorkItem (action, arg, SmartThreadPool.DefaultWorkItemPriority); + } + + public IWorkItemResult QueueWorkItem (Action action, T arg, WorkItemPriority priority) + { + PreQueueWorkItem (); + WorkItem workItem = WorkItemFactory.CreateWorkItem ( this, WIGStartInfo, state => - { - action.Invoke(arg); - return null; - }, - WIGStartInfo.FillStateWithArgs ? new object[] { arg } : null); - Enqueue(workItem); - return workItem.GetWorkItemResult(); + { + action.Invoke (arg); + return null; + }, + WIGStartInfo.FillStateWithArgs ? new object[] { arg } : null, priority); + Enqueue (workItem); + return workItem.GetWorkItemResult (); } public IWorkItemResult QueueWorkItem(Action action, T1 arg1, T2 arg2) { - PreQueueWorkItem(); - WorkItem workItem = WorkItemFactory.CreateWorkItem( + return QueueWorkItem (action, arg1, arg2, SmartThreadPool.DefaultWorkItemPriority); + } + + public IWorkItemResult QueueWorkItem (Action action, T1 arg1, T2 arg2, WorkItemPriority priority) + { + PreQueueWorkItem (); + WorkItem workItem = WorkItemFactory.CreateWorkItem ( this, WIGStartInfo, state => { - action.Invoke(arg1, arg2); + action.Invoke (arg1, arg2); return null; }, - WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2 } : null); - Enqueue(workItem); - return workItem.GetWorkItemResult(); + WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2 } : null, priority); + Enqueue (workItem); + return workItem.GetWorkItemResult (); } public IWorkItemResult QueueWorkItem(Action action, T1 arg1, T2 arg2, T3 arg3) { - PreQueueWorkItem(); - WorkItem workItem = WorkItemFactory.CreateWorkItem( + return QueueWorkItem (action, arg1, arg2, arg3, SmartThreadPool.DefaultWorkItemPriority); + ; + } + + public IWorkItemResult QueueWorkItem (Action action, T1 arg1, T2 arg2, T3 arg3, WorkItemPriority priority) + { + PreQueueWorkItem (); + WorkItem workItem = WorkItemFactory.CreateWorkItem ( this, WIGStartInfo, state => { - action.Invoke(arg1, arg2, arg3); + action.Invoke (arg1, arg2, arg3); return null; }, - WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3 } : null); - Enqueue(workItem); - return workItem.GetWorkItemResult(); + WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3 } : null, priority); + Enqueue (workItem); + return workItem.GetWorkItemResult (); } public IWorkItemResult QueueWorkItem( Action action, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { - PreQueueWorkItem(); - WorkItem workItem = WorkItemFactory.CreateWorkItem( + return QueueWorkItem (action, arg1, arg2, arg3, arg4, + SmartThreadPool.DefaultWorkItemPriority); + } + + public IWorkItemResult QueueWorkItem ( + Action action, T1 arg1, T2 arg2, T3 arg3, T4 arg4, WorkItemPriority priority) + { + PreQueueWorkItem (); + WorkItem workItem = WorkItemFactory.CreateWorkItem ( this, WIGStartInfo, state => { - action.Invoke(arg1, arg2, arg3, arg4); + action.Invoke (arg1, arg2, arg3, arg4); return null; }, - WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3, arg4 } : null); - Enqueue(workItem); - return workItem.GetWorkItemResult(); + WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3, arg4 } : null, priority); + Enqueue (workItem); + return workItem.GetWorkItemResult (); } #endregion From cbb3211c12752f695f0f1240b6b60ca6ee46642b Mon Sep 17 00:00:00 2001 From: Michal Staszewski Date: Tue, 21 Jun 2011 14:16:50 +0200 Subject: [PATCH 4/8] CHG: threads can be named (cherry picked from commit fbbbc451c9372af2862bc39cdf7698653c611dcf) --- SmartThreadPool/STPStartInfo.cs | 14 ++++++++++++++ SmartThreadPool/SmartThreadPool.cs | 7 ++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/SmartThreadPool/STPStartInfo.cs b/SmartThreadPool/STPStartInfo.cs index fdab702..d19a1d9 100644 --- a/SmartThreadPool/STPStartInfo.cs +++ b/SmartThreadPool/STPStartInfo.cs @@ -15,6 +15,7 @@ namespace Amib.Threading private string _performanceCounterInstanceName = SmartThreadPool.DefaultPerformanceCounterInstanceName; private bool _areThreadsBackground = SmartThreadPool.DefaultAreThreadsBackground; private bool _enableLocalPerformanceCounters; + private string _threadPoolName = SmartThreadPool.DefaultThreadPoolName; public STPStartInfo() { @@ -34,6 +35,7 @@ namespace Amib.Threading _threadPriority = stpStartInfo.ThreadPriority; _performanceCounterInstanceName = stpStartInfo.PerformanceCounterInstanceName; _enableLocalPerformanceCounters = stpStartInfo._enableLocalPerformanceCounters; + _threadPoolName = stpStartInfo._threadPoolName; _areThreadsBackground = stpStartInfo.AreThreadsBackground; } @@ -95,6 +97,18 @@ namespace Amib.Threading } } + /// + /// Get/Set the thread pool name. Threads will get names depending on this. + /// + public virtual string ThreadPoolName { + get { return _threadPoolName; } + set + { + ThrowIfReadOnly (); + _threadPoolName = value; + } + } + /// /// Get/Set the performance counter instance name of this SmartThreadPool /// The default is null which indicate not to use performance counters at all. diff --git a/SmartThreadPool/SmartThreadPool.cs b/SmartThreadPool/SmartThreadPool.cs index 9853d72..0801254 100644 --- a/SmartThreadPool/SmartThreadPool.cs +++ b/SmartThreadPool/SmartThreadPool.cs @@ -161,6 +161,11 @@ namespace Amib.Threading /// /// The default fill state with params. (false) + + /// + /// The default thread pool name. (SmartThreadPool) + /// + public const string DefaultThreadPoolName = "SmartThreadPool"; /// It is relevant only to QueueWorkItem of Action<...>/Func<...> /// public const bool DefaultFillStateWithArgs = false; @@ -395,7 +400,7 @@ namespace Amib.Threading private void Initialize() { - Name = "SmartThreadPool"; + Name = _stpStartInfo.ThreadPoolName; ValidateSTPStartInfo(); // _stpStartInfoRW stores a read/write copy of the STPStartInfo. From 6ba0034f496f3c9d7ff03d3645003c784656bd28 Mon Sep 17 00:00:00 2001 From: Michal Staszewski Date: Tue, 21 Jun 2011 14:34:04 +0200 Subject: [PATCH 5/8] CHG: build fixes (cherry picked from commit 2cd2bcec402a467c974a3106c3b1001dd4ed4ea4) --- STPTests/QueueWorkItemHelper.cs | 2 +- STPTests/STPTests.csproj | 5 ++++- WorkItemsGroupDemo/Form1.cs | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/STPTests/QueueWorkItemHelper.cs b/STPTests/QueueWorkItemHelper.cs index eb72d14..8a8e3d3 100644 --- a/STPTests/QueueWorkItemHelper.cs +++ b/STPTests/QueueWorkItemHelper.cs @@ -61,7 +61,7 @@ namespace SmartThreadPoolTests wii.WorkItemPriority = WorkItemPriority.AboveNormal; WorkItemInfoComparer wiic = new WorkItemInfoComparer(wii, state); - IWorkItemResult wir = wig.QueueWorkItem(wiic.CompareWorkItemInfo, state, WorkItemPriority.AboveNormal); + IWorkItemResult wir = wig.QueueWorkItem((WorkItemCallback) wiic.CompareWorkItemInfo, state, WorkItemPriority.AboveNormal); bool success = (bool)wir.Result; diff --git a/STPTests/STPTests.csproj b/STPTests/STPTests.csproj index 47334c5..1ffdffc 100644 --- a/STPTests/STPTests.csproj +++ b/STPTests/STPTests.csproj @@ -91,7 +91,10 @@ prompt - + + False + ..\lib\nunit.framework.dll + System diff --git a/WorkItemsGroupDemo/Form1.cs b/WorkItemsGroupDemo/Form1.cs index f298d49..3dce606 100644 --- a/WorkItemsGroupDemo/Form1.cs +++ b/WorkItemsGroupDemo/Form1.cs @@ -294,7 +294,7 @@ namespace WorkItemsGroupDemo spinIdleTimeout.Enabled = !start; } - private object DoNothing(object state) + private void DoNothing(WorkItemState state) { WorkItemState workItemState = (WorkItemState)state; _workingStates.Add(workItemState.QueueUsageEntry, workItemState.QueueUsageEntry); @@ -310,7 +310,7 @@ namespace WorkItemsGroupDemo } while (_paused); _workingStates.Remove(workItemState.QueueUsageEntry); - return null; + //return null; } From ea804bada014fa1f2023676b0ffa58cc1d8a4aa9 Mon Sep 17 00:00:00 2001 From: Michal Staszewski Date: Tue, 21 Jun 2011 14:41:32 +0200 Subject: [PATCH 6/8] CHG: fix Pipe test (cherry picked from commit b66d3e93949f2c152e6d8f3d3526cf9bb05a05bb) --- STPTests/TestParallelMethods.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/STPTests/TestParallelMethods.cs b/STPTests/TestParallelMethods.cs index 7787b24..921b6c5 100644 --- a/STPTests/TestParallelMethods.cs +++ b/STPTests/TestParallelMethods.cs @@ -101,6 +101,7 @@ namespace SmartThreadPoolTests sc1 => { if (sc.Counter == 2) { sc1.Increment(); }} ); + stp.WaitForIdle (); Assert.AreEqual(3, sc.Counter); stp.Shutdown(); From 4b16bf08cebf5acb44de78737de3b4ce3eedd777 Mon Sep 17 00:00:00 2001 From: Michal Staszewski Date: Tue, 21 Jun 2011 14:44:04 +0200 Subject: [PATCH 7/8] CHG: passive wait on DequeueWorkItem (cherry picked from commit ac49cc8dce0519e29f26cacc5e785134300c6639) --- SmartThreadPool/WorkItemsQueue.cs | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/SmartThreadPool/WorkItemsQueue.cs b/SmartThreadPool/WorkItemsQueue.cs index e7e265a..689044a 100644 --- a/SmartThreadPool/WorkItemsQueue.cs +++ b/SmartThreadPool/WorkItemsQueue.cs @@ -177,14 +177,8 @@ namespace Amib.Threading.Internal WaiterEntry waiterEntry; WorkItem workItem = null; - - try - { - while (!Monitor.TryEnter(this)) { } - //Stopwatch stopwatch = Stopwatch.StartNew(); - //Monitor.Enter(this); - //stopwatch.Stop(); - + lock (this) + { ValidateNotDisposed(); // If there are waiting work items then take one and return. @@ -201,11 +195,7 @@ namespace Amib.Threading.Internal // Put the waiter with the other waiters PushWaiter(waiterEntry); - } - finally - { - Monitor.Exit(this); - } + } // Prepare array of wait handle for the WaitHandle.WaitAny() WaitHandle [] waitHandles = new WaitHandle[] { From 24d52fea3879cd26ca8a170724e5e59a1006a196 Mon Sep 17 00:00:00 2001 From: Michal Staszewski Date: Tue, 21 Jun 2011 14:51:15 +0200 Subject: [PATCH 8/8] CHG: build adjusted (cherry picked from commit 7459063627ea9225c406ea18cc13207e7e59c4e6) --- SmartThreadPool/Properties/AssemblyInfo.cs | 2 +- SmartThreadPool/SmartThreadPoolMono.csproj | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/SmartThreadPool/Properties/AssemblyInfo.cs b/SmartThreadPool/Properties/AssemblyInfo.cs index 6f0590b..92b94a1 100644 --- a/SmartThreadPool/Properties/AssemblyInfo.cs +++ b/SmartThreadPool/Properties/AssemblyInfo.cs @@ -12,7 +12,7 @@ using System.Runtime.InteropServices; [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] [assembly: Guid("c764a3de-c4f8-434d-85b5-a09830d1e44f")] -[assembly: AssemblyVersion("2.2.1.0")] +[assembly: AssemblyVersion("2.2.2.0")] [assembly: InternalsVisibleTo("STPTests")] diff --git a/SmartThreadPool/SmartThreadPoolMono.csproj b/SmartThreadPool/SmartThreadPoolMono.csproj index ce4c31f..da81348 100644 --- a/SmartThreadPool/SmartThreadPoolMono.csproj +++ b/SmartThreadPool/SmartThreadPoolMono.csproj @@ -5,7 +5,7 @@ {3462F30B-0156-409C-B256-6046D6F1764B} Library false - SmartThreadPoolMono + SmartThreadPool Amib.Threading @@ -17,16 +17,18 @@ true full false - .\bin\Debug\ + .\bin\Debug\Mono TRACE;DEBUG;_MONO - pdbonly + full true - .\bin\Release\ + bin\Release\Mono\ TRACE;_MONO + bin\Release\Mono\SmartThreadPool.XML + true