2013-05-01 22:00:46 +00:00
using System ;
using System.Diagnostics ;
using System.Threading ;
namespace Amib.Threading
{
public interface ISTPPerformanceCountersReader
{
long InUseThreads { get ; }
long ActiveThreads { get ; }
long WorkItemsQueued { get ; }
long WorkItemsProcessed { get ; }
}
}
namespace Amib.Threading.Internal
{
internal interface ISTPInstancePerformanceCounters : IDisposable
{
void Close ( ) ;
void SampleThreads ( long activeThreads , long inUseThreads ) ;
void SampleWorkItems ( long workItemsQueued , long workItemsProcessed ) ;
void SampleWorkItemsWaitTime ( TimeSpan workItemWaitTime ) ;
void SampleWorkItemsProcessTime ( TimeSpan workItemProcessTime ) ;
}
#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
internal enum STPPerformanceCounterType
2017-01-05 19:07:37 +00:00
{
// Fields
ActiveThreads = 0 ,
InUseThreads = 1 ,
OverheadThreads = 2 ,
OverheadThreadsPercent = 3 ,
OverheadThreadsPercentBase = 4 ,
WorkItems = 5 ,
WorkItemsInQueue = 6 ,
WorkItemsProcessed = 7 ,
WorkItemsQueuedPerSecond = 8 ,
WorkItemsProcessedPerSecond = 9 ,
AvgWorkItemWaitTime = 10 ,
AvgWorkItemWaitTimeBase = 11 ,
AvgWorkItemProcessTime = 12 ,
AvgWorkItemProcessTimeBase = 13 ,
WorkItemsGroups = 14 ,
LastCounter = 14 ,
}
/// <summary>
/// Summary description for STPPerformanceCounter.
/// </summary>
internal class STPPerformanceCounter
{
// Fields
private readonly PerformanceCounterType _pcType ;
protected string _counterHelp ;
protected string _counterName ;
// Methods
public STPPerformanceCounter (
string counterName ,
string counterHelp ,
PerformanceCounterType pcType )
{
_counterName = counterName ;
_counterHelp = counterHelp ;
_pcType = pcType ;
}
public void AddCounterToCollection ( CounterCreationDataCollection counterData )
{
CounterCreationData counterCreationData = new CounterCreationData (
_counterName ,
_counterHelp ,
_pcType ) ;
counterData . Add ( counterCreationData ) ;
}
// Properties
public string Name
{
get
{
return _counterName ;
}
}
}
internal class STPPerformanceCounters
{
// Fields
internal STPPerformanceCounter [ ] _stpPerformanceCounters ;
private static readonly STPPerformanceCounters _instance ;
internal const string _stpCategoryHelp = "SmartThreadPool performance counters" ;
internal const string _stpCategoryName = "SmartThreadPool" ;
// Methods
static STPPerformanceCounters ( )
{
_instance = new STPPerformanceCounters ( ) ;
}
private STPPerformanceCounters ( )
{
STPPerformanceCounter [ ] stpPerformanceCounters = new STPPerformanceCounter [ ]
{
new STPPerformanceCounter ( "Active threads" , "The current number of available in the thread pool." , PerformanceCounterType . NumberOfItems32 ) ,
new STPPerformanceCounter ( "In use threads" , "The current number of threads that execute a work item." , PerformanceCounterType . NumberOfItems32 ) ,
new STPPerformanceCounter ( "Overhead threads" , "The current number of threads that are active, but are not in use." , PerformanceCounterType . NumberOfItems32 ) ,
new STPPerformanceCounter ( "% overhead threads" , "The current number of threads that are active, but are not in use in percents." , PerformanceCounterType . RawFraction ) ,
new STPPerformanceCounter ( "% overhead threads base" , "The current number of threads that are active, but are not in use in percents." , PerformanceCounterType . RawBase ) ,
new STPPerformanceCounter ( "Work Items" , "The number of work items in the Smart Thread Pool. Both queued and processed." , PerformanceCounterType . NumberOfItems32 ) ,
new STPPerformanceCounter ( "Work Items in queue" , "The current number of work items in the queue" , PerformanceCounterType . NumberOfItems32 ) ,
new STPPerformanceCounter ( "Work Items processed" , "The number of work items already processed" , PerformanceCounterType . NumberOfItems32 ) ,
new STPPerformanceCounter ( "Work Items queued/sec" , "The number of work items queued per second" , PerformanceCounterType . RateOfCountsPerSecond32 ) ,
new STPPerformanceCounter ( "Work Items processed/sec" , "The number of work items processed per second" , PerformanceCounterType . RateOfCountsPerSecond32 ) ,
new STPPerformanceCounter ( "Avg. Work Item wait time/sec" , "The average time a work item supends in the queue waiting for its turn to execute." , PerformanceCounterType . AverageCount64 ) ,
new STPPerformanceCounter ( "Avg. Work Item wait time base" , "The average time a work item supends in the queue waiting for its turn to execute." , PerformanceCounterType . AverageBase ) ,
new STPPerformanceCounter ( "Avg. Work Item process time/sec" , "The average time it takes to process a work item." , PerformanceCounterType . AverageCount64 ) ,
new STPPerformanceCounter ( "Avg. Work Item process time base" , "The average time it takes to process a work item." , PerformanceCounterType . AverageBase ) ,
new STPPerformanceCounter ( "Work Items Groups" , "The current number of work item groups associated with the Smart Thread Pool." , PerformanceCounterType . NumberOfItems32 ) ,
} ;
_stpPerformanceCounters = stpPerformanceCounters ;
SetupCategory ( ) ;
}
private void SetupCategory ( )
{
if ( ! PerformanceCounterCategory . Exists ( _stpCategoryName ) )
{
CounterCreationDataCollection counters = new CounterCreationDataCollection ( ) ;
for ( int i = 0 ; i < _stpPerformanceCounters . Length ; i + + )
{
_stpPerformanceCounters [ i ] . AddCounterToCollection ( counters ) ;
}
PerformanceCounterCategory . Create (
_stpCategoryName ,
_stpCategoryHelp ,
2013-05-01 22:00:46 +00:00
PerformanceCounterCategoryType . MultiInstance ,
2017-01-05 19:07:37 +00:00
counters ) ;
}
}
// Properties
public static STPPerformanceCounters Instance
{
get
{
return _instance ;
}
}
}
internal class STPInstancePerformanceCounter : IDisposable
{
// Fields
2013-05-01 22:00:46 +00:00
private bool _isDisposed ;
2017-01-05 19:07:37 +00:00
private PerformanceCounter _pcs ;
2013-05-01 22:00:46 +00:00
2017-01-05 19:07:37 +00:00
// Methods
protected STPInstancePerformanceCounter ( )
{
2013-05-01 22:00:46 +00:00
_isDisposed = false ;
2017-01-05 19:07:37 +00:00
}
public STPInstancePerformanceCounter (
string instance ,
STPPerformanceCounterType spcType ) : this ( )
{
STPPerformanceCounters counters = STPPerformanceCounters . Instance ;
_pcs = new PerformanceCounter (
STPPerformanceCounters . _stpCategoryName ,
counters . _stpPerformanceCounters [ ( int ) spcType ] . Name ,
instance ,
false ) ;
_pcs . RawValue = _pcs . RawValue ;
}
public void Close ( )
{
if ( _pcs ! = null )
{
_pcs . RemoveInstance ( ) ;
_pcs . Close ( ) ;
_pcs = null ;
}
}
public void Dispose ( )
{
2013-05-01 22:00:46 +00:00
Dispose ( true ) ;
2017-01-05 19:07:37 +00:00
}
2013-05-01 22:00:46 +00:00
public virtual void Dispose ( bool disposing )
{
if ( ! _isDisposed )
{
if ( disposing )
{
Close ( ) ;
}
}
_isDisposed = true ;
}
2017-01-05 19:07:37 +00:00
public virtual void Increment ( )
{
_pcs . Increment ( ) ;
}
public virtual void IncrementBy ( long val )
{
_pcs . IncrementBy ( val ) ;
}
public virtual void Set ( long val )
{
_pcs . RawValue = val ;
}
}
internal class STPInstanceNullPerformanceCounter : STPInstancePerformanceCounter
{
// Methods
public override void Increment ( ) { }
public override void IncrementBy ( long value ) { }
public override void Set ( long val ) { }
}
internal class STPInstancePerformanceCounters : ISTPInstancePerformanceCounters
{
2013-05-01 22:00:46 +00:00
private bool _isDisposed ;
2017-01-05 19:07:37 +00:00
// Fields
private STPInstancePerformanceCounter [ ] _pcs ;
private static readonly STPInstancePerformanceCounter _stpInstanceNullPerformanceCounter ;
// Methods
static STPInstancePerformanceCounters ( )
{
_stpInstanceNullPerformanceCounter = new STPInstanceNullPerformanceCounter ( ) ;
}
public STPInstancePerformanceCounters ( string instance )
{
2013-05-01 22:00:46 +00:00
_isDisposed = false ;
2017-01-05 19:07:37 +00:00
_pcs = new STPInstancePerformanceCounter [ ( int ) STPPerformanceCounterType . LastCounter ] ;
2013-05-01 22:00:46 +00:00
// Call the STPPerformanceCounters.Instance so the static constructor will
// intialize the STPPerformanceCounters singleton.
2017-01-05 19:07:37 +00:00
STPPerformanceCounters . Instance . GetHashCode ( ) ;
for ( int i = 0 ; i < _pcs . Length ; i + + )
{
if ( instance ! = null )
{
_pcs [ i ] = new STPInstancePerformanceCounter (
instance ,
( STPPerformanceCounterType ) i ) ;
}
else
{
_pcs [ i ] = _stpInstanceNullPerformanceCounter ;
}
}
}
public void Close ( )
{
if ( null ! = _pcs )
{
for ( int i = 0 ; i < _pcs . Length ; i + + )
{
2013-05-01 22:00:46 +00:00
if ( null ! = _pcs [ i ] )
{
_pcs [ i ] . Dispose ( ) ;
}
2017-01-05 19:07:37 +00:00
}
_pcs = null ;
}
}
2013-05-01 22:00:46 +00:00
2017-01-05 19:07:37 +00:00
public void Dispose ( )
{
2013-05-01 22:00:46 +00:00
Dispose ( true ) ;
2017-01-05 19:07:37 +00:00
}
2013-05-01 22:00:46 +00:00
public virtual void Dispose ( bool disposing )
{
if ( ! _isDisposed )
{
if ( disposing )
{
Close ( ) ;
}
}
_isDisposed = true ;
}
2017-01-05 19:07:37 +00:00
private STPInstancePerformanceCounter GetCounter ( STPPerformanceCounterType spcType )
{
return _pcs [ ( int ) spcType ] ;
}
public void SampleThreads ( long activeThreads , long inUseThreads )
{
GetCounter ( STPPerformanceCounterType . ActiveThreads ) . Set ( activeThreads ) ;
GetCounter ( STPPerformanceCounterType . InUseThreads ) . Set ( inUseThreads ) ;
GetCounter ( STPPerformanceCounterType . OverheadThreads ) . Set ( activeThreads - inUseThreads ) ;
GetCounter ( STPPerformanceCounterType . OverheadThreadsPercentBase ) . Set ( activeThreads - inUseThreads ) ;
GetCounter ( STPPerformanceCounterType . OverheadThreadsPercent ) . Set ( inUseThreads ) ;
}
public void SampleWorkItems ( long workItemsQueued , long workItemsProcessed )
{
GetCounter ( STPPerformanceCounterType . WorkItems ) . Set ( workItemsQueued + workItemsProcessed ) ;
GetCounter ( STPPerformanceCounterType . WorkItemsInQueue ) . Set ( workItemsQueued ) ;
GetCounter ( STPPerformanceCounterType . WorkItemsProcessed ) . Set ( workItemsProcessed ) ;
GetCounter ( STPPerformanceCounterType . WorkItemsQueuedPerSecond ) . Set ( workItemsQueued ) ;
GetCounter ( STPPerformanceCounterType . WorkItemsProcessedPerSecond ) . Set ( workItemsProcessed ) ;
}
public void SampleWorkItemsWaitTime ( TimeSpan workItemWaitTime )
{
GetCounter ( STPPerformanceCounterType . AvgWorkItemWaitTime ) . IncrementBy ( ( long ) workItemWaitTime . TotalMilliseconds ) ;
GetCounter ( STPPerformanceCounterType . AvgWorkItemWaitTimeBase ) . Increment ( ) ;
}
public void SampleWorkItemsProcessTime ( TimeSpan workItemProcessTime )
{
GetCounter ( STPPerformanceCounterType . AvgWorkItemProcessTime ) . IncrementBy ( ( long ) workItemProcessTime . TotalMilliseconds ) ;
GetCounter ( STPPerformanceCounterType . AvgWorkItemProcessTimeBase ) . Increment ( ) ;
}
2013-05-01 22:00:46 +00:00
}
# endif
internal class NullSTPInstancePerformanceCounters : ISTPInstancePerformanceCounters , ISTPPerformanceCountersReader
2017-01-05 19:07:37 +00:00
{
private static readonly NullSTPInstancePerformanceCounters _instance = new NullSTPInstancePerformanceCounters ( ) ;
public static NullSTPInstancePerformanceCounters Instance
{
get { return _instance ; }
}
public void Close ( ) { }
public void Dispose ( ) { }
public void SampleThreads ( long activeThreads , long inUseThreads ) { }
public void SampleWorkItems ( long workItemsQueued , long workItemsProcessed ) { }
public void SampleWorkItemsWaitTime ( TimeSpan workItemWaitTime ) { }
public void SampleWorkItemsProcessTime ( TimeSpan workItemProcessTime ) { }
2013-05-01 22:00:46 +00:00
public long InUseThreads
{
get { return 0 ; }
}
public long ActiveThreads
{
get { return 0 ; }
}
public long WorkItemsQueued
{
get { return 0 ; }
}
public long WorkItemsProcessed
{
get { return 0 ; }
}
2017-01-05 19:07:37 +00:00
}
2013-05-01 22:00:46 +00:00
internal class LocalSTPInstancePerformanceCounters : ISTPInstancePerformanceCounters , ISTPPerformanceCountersReader
{
public void Close ( ) { }
public void Dispose ( ) { }
private long _activeThreads ;
private long _inUseThreads ;
private long _workItemsQueued ;
private long _workItemsProcessed ;
public long InUseThreads
{
get { return _inUseThreads ; }
}
public long ActiveThreads
{
get { return _activeThreads ; }
}
public long WorkItemsQueued
{
get { return _workItemsQueued ; }
}
public long WorkItemsProcessed
{
get { return _workItemsProcessed ; }
}
public void SampleThreads ( long activeThreads , long inUseThreads )
{
_activeThreads = activeThreads ;
_inUseThreads = inUseThreads ;
}
public void SampleWorkItems ( long workItemsQueued , long workItemsProcessed )
{
_workItemsQueued = workItemsQueued ;
_workItemsProcessed = workItemsProcessed ;
}
public void SampleWorkItemsWaitTime ( TimeSpan workItemWaitTime )
{
// Not supported
}
public void SampleWorkItemsProcessTime ( TimeSpan workItemProcessTime )
{
// Not supported
}
}
}