Merged branch 'master' with kesyw (Piotr Wysocki)

This commit is contained in:
Ami Bar
2012-07-03 22:58:36 +03:00
10 changed files with 163 additions and 66 deletions
+1 -1
View File
@@ -61,7 +61,7 @@ namespace SmartThreadPoolTests
wii.WorkItemPriority = WorkItemPriority.AboveNormal; wii.WorkItemPriority = WorkItemPriority.AboveNormal;
WorkItemInfoComparer wiic = new WorkItemInfoComparer(wii, state); 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; bool success = (bool)wir.Result;
+4 -1
View File
@@ -91,7 +91,10 @@
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="nunit.framework, Version=2.5.2.9222, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL" /> <Reference Include="nunit.framework, Version=2.5.1.9189, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\lib\nunit.framework.dll</HintPath>
</Reference>
<Reference Include="System"> <Reference Include="System">
<Name>System</Name> <Name>System</Name>
</Reference> </Reference>
+31 -1
View File
@@ -271,7 +271,19 @@ namespace Amib.Threading
/// Queue a work item. /// Queue a work item.
/// </summary> /// </summary>
/// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns> /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
IWorkItemResult QueueWorkItem<T>(Action<T> action, T arg); IWorkItemResult QueueWorkItem (Action action, WorkItemPriority priority);
/// <summary>
/// Queue a work item.
/// </summary>
/// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
IWorkItemResult QueueWorkItem<T> (Action<T> action, T arg, WorkItemPriority priority);
/// <summary>
/// Queue a work item.
/// </summary>
/// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
IWorkItemResult QueueWorkItem<T> (Action<T> action, T arg);
/// <summary> /// <summary>
/// Queue a work item. /// Queue a work item.
@@ -279,18 +291,36 @@ namespace Amib.Threading
/// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns> /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
IWorkItemResult QueueWorkItem<T1, T2>(Action<T1, T2> action, T1 arg1, T2 arg2); IWorkItemResult QueueWorkItem<T1, T2>(Action<T1, T2> action, T1 arg1, T2 arg2);
/// <summary>
/// Queue a work item.
/// </summary>
/// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
IWorkItemResult QueueWorkItem<T1, T2> (Action<T1, T2> action, T1 arg1, T2 arg2, WorkItemPriority priority);
/// <summary> /// <summary>
/// Queue a work item. /// Queue a work item.
/// </summary> /// </summary>
/// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns> /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
IWorkItemResult QueueWorkItem<T1, T2, T3>(Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3); IWorkItemResult QueueWorkItem<T1, T2, T3>(Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3);
/// <summary>
/// Queue a work item.
/// </summary>
/// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
IWorkItemResult QueueWorkItem<T1, T2, T3> (Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3, WorkItemPriority priority);
/// <summary> /// <summary>
/// Queue a work item. /// Queue a work item.
/// </summary> /// </summary>
/// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns> /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
IWorkItemResult QueueWorkItem<T1, T2, T3, T4>(Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4); IWorkItemResult QueueWorkItem<T1, T2, T3, T4>(Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4);
/// <summary>
/// Queue a work item.
/// </summary>
/// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
IWorkItemResult QueueWorkItem<T1, T2, T3, T4> (Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4, WorkItemPriority priority);
#endregion #endregion
#region QueueWorkItem(Func<...>) #region QueueWorkItem(Func<...>)
+1 -1
View File
@@ -12,7 +12,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]
[assembly: Guid("c764a3de-c4f8-434d-85b5-a09830d1e44f")] [assembly: Guid("c764a3de-c4f8-434d-85b5-a09830d1e44f")]
[assembly: AssemblyVersion("2.2.1.0")] [assembly: AssemblyVersion("2.2.2.0")]
[assembly: InternalsVisibleTo("STPTests")] [assembly: InternalsVisibleTo("STPTests")]
+29
View File
@@ -13,7 +13,9 @@ namespace Amib.Threading
private int _maxWorkerThreads = SmartThreadPool.DefaultMaxWorkerThreads; private int _maxWorkerThreads = SmartThreadPool.DefaultMaxWorkerThreads;
private ThreadPriority _threadPriority = SmartThreadPool.DefaultThreadPriority; private ThreadPriority _threadPriority = SmartThreadPool.DefaultThreadPriority;
private string _performanceCounterInstanceName = SmartThreadPool.DefaultPerformanceCounterInstanceName; private string _performanceCounterInstanceName = SmartThreadPool.DefaultPerformanceCounterInstanceName;
private bool _areThreadsBackground = SmartThreadPool.DefaultAreThreadsBackground;
private bool _enableLocalPerformanceCounters; private bool _enableLocalPerformanceCounters;
private string _threadPoolName = SmartThreadPool.DefaultThreadPoolName;
public STPStartInfo() public STPStartInfo()
{ {
@@ -33,6 +35,8 @@ namespace Amib.Threading
_threadPriority = stpStartInfo.ThreadPriority; _threadPriority = stpStartInfo.ThreadPriority;
_performanceCounterInstanceName = stpStartInfo.PerformanceCounterInstanceName; _performanceCounterInstanceName = stpStartInfo.PerformanceCounterInstanceName;
_enableLocalPerformanceCounters = stpStartInfo._enableLocalPerformanceCounters; _enableLocalPerformanceCounters = stpStartInfo._enableLocalPerformanceCounters;
_threadPoolName = stpStartInfo._threadPoolName;
_areThreadsBackground = stpStartInfo.AreThreadsBackground;
} }
@@ -93,6 +97,18 @@ namespace Amib.Threading
} }
} }
/// <summary>
/// Get/Set the thread pool name. Threads will get names depending on this.
/// </summary>
public virtual string ThreadPoolName {
get { return _threadPoolName; }
set
{
ThrowIfReadOnly ();
_threadPoolName = value;
}
}
/// <summary> /// <summary>
/// Get/Set the performance counter instance name of this SmartThreadPool /// Get/Set the performance counter instance name of this SmartThreadPool
/// The default is null which indicate not to use performance counters at all. /// The default is null which indicate not to use performance counters at all.
@@ -123,6 +139,19 @@ namespace Amib.Threading
} }
} }
/// <summary>
/// Get/Set backgroundness of thread in thread pool.
/// </summary>
public virtual bool AreThreadsBackground
{
get { return _areThreadsBackground; }
set
{
ThrowIfReadOnly ();
_areThreadsBackground = value;
}
}
/// <summary> /// <summary>
/// Get a readonly version of this STPStartInfo. /// Get a readonly version of this STPStartInfo.
/// </summary> /// </summary>
+12 -2
View File
@@ -161,9 +161,19 @@ namespace Amib.Threading
/// <summary> /// <summary>
/// The default fill state with params. (false) /// The default fill state with params. (false)
/// <summary>
/// The default thread pool name. (SmartThreadPool)
/// </summary>
public const string DefaultThreadPoolName = "SmartThreadPool";
/// It is relevant only to QueueWorkItem of Action<...>/Func<...> /// It is relevant only to QueueWorkItem of Action<...>/Func<...>
/// </summary> /// </summary>
public const bool DefaultFillStateWithArgs = false; public const bool DefaultFillStateWithArgs = false;
/// <summary>
/// The default thread backgroundness. (true)
/// </summary>
public const bool DefaultAreThreadsBackground = true;
#endregion #endregion
@@ -390,7 +400,7 @@ namespace Amib.Threading
private void Initialize() private void Initialize()
{ {
Name = "SmartThreadPool"; Name = _stpStartInfo.ThreadPoolName;
ValidateSTPStartInfo(); ValidateSTPStartInfo();
// _stpStartInfoRW stores a read/write copy of the STPStartInfo. // _stpStartInfoRW stores a read/write copy of the STPStartInfo.
@@ -608,7 +618,7 @@ namespace Amib.Threading
// Configure the new thread and start it // Configure the new thread and start it
workerThread.Name = "STP " + Name + " Thread #" + _threadCounter; workerThread.Name = "STP " + Name + " Thread #" + _threadCounter;
workerThread.IsBackground = true; workerThread.IsBackground = _stpStartInfo.AreThreadsBackground;
#if !(_SILVERLIGHT) #if !(_SILVERLIGHT)
workerThread.Priority = _stpStartInfo.ThreadPriority; workerThread.Priority = _stpStartInfo.ThreadPriority;
#endif #endif
+6 -4
View File
@@ -5,7 +5,7 @@
<ProjectGuid>{3462F30B-0156-409C-B256-6046D6F1764B}</ProjectGuid> <ProjectGuid>{3462F30B-0156-409C-B256-6046D6F1764B}</ProjectGuid>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<NoStandardLibraries>false</NoStandardLibraries> <NoStandardLibraries>false</NoStandardLibraries>
<AssemblyName>SmartThreadPoolMono</AssemblyName> <AssemblyName>SmartThreadPool</AssemblyName>
<RootNamespace>Amib.Threading</RootNamespace> <RootNamespace>Amib.Threading</RootNamespace>
<FileUpgradeFlags> <FileUpgradeFlags>
</FileUpgradeFlags> </FileUpgradeFlags>
@@ -17,16 +17,18 @@
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType> <DebugType>full</DebugType>
<Optimize>false</Optimize> <Optimize>false</Optimize>
<OutputPath>.\bin\Debug\</OutputPath> <OutputPath>.\bin\Debug\Mono</OutputPath>
<DefineConstants>TRACE;DEBUG;_MONO</DefineConstants> <DefineConstants>TRACE;DEBUG;_MONO</DefineConstants>
<DocumentationFile> <DocumentationFile>
</DocumentationFile> </DocumentationFile>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType> <DebugType>full</DebugType>
<Optimize>true</Optimize> <Optimize>true</Optimize>
<OutputPath>.\bin\Release\</OutputPath> <OutputPath>bin\Release\Mono\</OutputPath>
<DefineConstants>TRACE;_MONO</DefineConstants> <DefineConstants>TRACE;_MONO</DefineConstants>
<DocumentationFile>bin\Release\Mono\SmartThreadPool.XML</DocumentationFile>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="System" /> <Reference Include="System" />
+61 -33
View File
@@ -278,82 +278,110 @@ namespace Amib.Threading.Internal
public IWorkItemResult QueueWorkItem(Action action) public IWorkItemResult QueueWorkItem(Action action)
{ {
PreQueueWorkItem(); return QueueWorkItem (action, SmartThreadPool.DefaultWorkItemPriority);
WorkItem workItem = WorkItemFactory.CreateWorkItem( }
public IWorkItemResult QueueWorkItem (Action action, WorkItemPriority priority)
{
PreQueueWorkItem ();
WorkItem workItem = WorkItemFactory.CreateWorkItem (
this, this,
WIGStartInfo, WIGStartInfo,
delegate delegate
{ {
action.Invoke(); action.Invoke ();
return null; return null;
}); }, priority);
Enqueue(workItem); Enqueue (workItem);
return workItem.GetWorkItemResult(); return workItem.GetWorkItemResult ();
} }
public IWorkItemResult QueueWorkItem<T>(Action<T> action, T arg) public IWorkItemResult QueueWorkItem<T>(Action<T> action, T arg)
{ {
PreQueueWorkItem(); return QueueWorkItem<T> (action, arg, SmartThreadPool.DefaultWorkItemPriority);
WorkItem workItem = WorkItemFactory.CreateWorkItem( }
public IWorkItemResult QueueWorkItem<T> (Action<T> action, T arg, WorkItemPriority priority)
{
PreQueueWorkItem ();
WorkItem workItem = WorkItemFactory.CreateWorkItem (
this, this,
WIGStartInfo, WIGStartInfo,
state => state =>
{ {
action.Invoke(arg); action.Invoke (arg);
return null; return null;
}, },
WIGStartInfo.FillStateWithArgs ? new object[] { arg } : null); WIGStartInfo.FillStateWithArgs ? new object[] { arg } : null, priority);
Enqueue(workItem); Enqueue (workItem);
return workItem.GetWorkItemResult(); return workItem.GetWorkItemResult ();
} }
public IWorkItemResult QueueWorkItem<T1, T2>(Action<T1, T2> action, T1 arg1, T2 arg2) public IWorkItemResult QueueWorkItem<T1, T2>(Action<T1, T2> action, T1 arg1, T2 arg2)
{ {
PreQueueWorkItem(); return QueueWorkItem<T1, T2> (action, arg1, arg2, SmartThreadPool.DefaultWorkItemPriority);
WorkItem workItem = WorkItemFactory.CreateWorkItem( }
public IWorkItemResult QueueWorkItem<T1, T2> (Action<T1, T2> action, T1 arg1, T2 arg2, WorkItemPriority priority)
{
PreQueueWorkItem ();
WorkItem workItem = WorkItemFactory.CreateWorkItem (
this, this,
WIGStartInfo, WIGStartInfo,
state => state =>
{ {
action.Invoke(arg1, arg2); action.Invoke (arg1, arg2);
return null; return null;
}, },
WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2 } : null); WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2 } : null, priority);
Enqueue(workItem); Enqueue (workItem);
return workItem.GetWorkItemResult(); return workItem.GetWorkItemResult ();
} }
public IWorkItemResult QueueWorkItem<T1, T2, T3>(Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3) public IWorkItemResult QueueWorkItem<T1, T2, T3>(Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3)
{ {
PreQueueWorkItem(); return QueueWorkItem<T1, T2, T3> (action, arg1, arg2, arg3, SmartThreadPool.DefaultWorkItemPriority);
WorkItem workItem = WorkItemFactory.CreateWorkItem( ;
}
public IWorkItemResult QueueWorkItem<T1, T2, T3> (Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3, WorkItemPriority priority)
{
PreQueueWorkItem ();
WorkItem workItem = WorkItemFactory.CreateWorkItem (
this, this,
WIGStartInfo, WIGStartInfo,
state => state =>
{ {
action.Invoke(arg1, arg2, arg3); action.Invoke (arg1, arg2, arg3);
return null; return null;
}, },
WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3 } : null); WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3 } : null, priority);
Enqueue(workItem); Enqueue (workItem);
return workItem.GetWorkItemResult(); return workItem.GetWorkItemResult ();
} }
public IWorkItemResult QueueWorkItem<T1, T2, T3, T4>( public IWorkItemResult QueueWorkItem<T1, T2, T3, T4>(
Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4) Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
{ {
PreQueueWorkItem(); return QueueWorkItem<T1, T2, T3, T4> (action, arg1, arg2, arg3, arg4,
WorkItem workItem = WorkItemFactory.CreateWorkItem( SmartThreadPool.DefaultWorkItemPriority);
}
public IWorkItemResult QueueWorkItem<T1, T2, T3, T4> (
Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4, WorkItemPriority priority)
{
PreQueueWorkItem ();
WorkItem workItem = WorkItemFactory.CreateWorkItem (
this, this,
WIGStartInfo, WIGStartInfo,
state => state =>
{ {
action.Invoke(arg1, arg2, arg3, arg4); action.Invoke (arg1, arg2, arg3, arg4);
return null; return null;
}, },
WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3, arg4 } : null); WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3, arg4 } : null, priority);
Enqueue(workItem); Enqueue (workItem);
return workItem.GetWorkItemResult(); return workItem.GetWorkItemResult ();
} }
#endregion #endregion
+16 -21
View File
@@ -163,27 +163,22 @@ namespace Amib.Threading.Internal
int millisecondsTimeout, int millisecondsTimeout,
WaitHandle cancelEvent) WaitHandle cancelEvent)
{ {
// This method cause the caller to wait for a work item. // This method cause the caller to wait for a work item.
// If there is at least one waiting work item then the // If there is at least one waiting work item then the
// method returns immidiately with it. // method returns immidiately with it.
// //
// If there are no waiting work items then the caller // If there are no waiting work items then the caller
// is queued between other waiters for a work item to arrive. // is queued between other waiters for a work item to arrive.
// //
// If a work item didn't come within millisecondsTimeout or // If a work item didn't come within millisecondsTimeout or
// the user canceled the wait by signaling the cancelEvent // the user canceled the wait by signaling the cancelEvent
// then the method returns null to indicate that the caller // then the method returns null to indicate that the caller
// didn't get a work item. // didn't get a work item.
WaiterEntry waiterEntry;
WorkItem workItem = null;
lock (this)
{
//Stopwatch stopwatch = Stopwatch.StartNew();
//Monitor.Enter(this);
//stopwatch.Stop();
WaiterEntry waiterEntry;
WorkItem workItem = null;
lock (this)
{
ValidateNotDisposed(); ValidateNotDisposed();
// If there are waiting work items then take one and return. // If there are waiting work items then take one and return.
@@ -200,7 +195,7 @@ namespace Amib.Threading.Internal
// Put the waiter with the other waiters // Put the waiter with the other waiters
PushWaiter(waiterEntry); PushWaiter(waiterEntry);
} }
// Prepare array of wait handle for the WaitHandle.WaitAny() // Prepare array of wait handle for the WaitHandle.WaitAny()
WaitHandle [] waitHandles = new WaitHandle[] { WaitHandle [] waitHandles = new WaitHandle[] {
+2 -2
View File
@@ -294,7 +294,7 @@ namespace WorkItemsGroupDemo
spinIdleTimeout.Enabled = !start; spinIdleTimeout.Enabled = !start;
} }
private object DoNothing(object state) private void DoNothing(WorkItemState state)
{ {
WorkItemState workItemState = (WorkItemState)state; WorkItemState workItemState = (WorkItemState)state;
_workingStates.Add(workItemState.QueueUsageEntry, workItemState.QueueUsageEntry); _workingStates.Add(workItemState.QueueUsageEntry, workItemState.QueueUsageEntry);
@@ -310,7 +310,7 @@ namespace WorkItemsGroupDemo
} while (_paused); } while (_paused);
_workingStates.Remove(workItemState.QueueUsageEntry); _workingStates.Remove(workItemState.QueueUsageEntry);
return null; //return null;
} }