refactor: Move existing code to generate report information on the threadpool to the ServerBase rather than being in Util
parent
c0a00cd7fd
commit
b7c9dee033
|
@ -667,7 +667,68 @@ namespace OpenSim.Framework.Servers
|
||||||
sb.AppendFormat("Total threads active: {0}\n\n", totalThreads);
|
sb.AppendFormat("Total threads active: {0}\n\n", totalThreads);
|
||||||
|
|
||||||
sb.Append("Main threadpool (excluding script engine pools)\n");
|
sb.Append("Main threadpool (excluding script engine pools)\n");
|
||||||
sb.Append(Util.GetThreadPoolReport());
|
sb.Append(GetThreadPoolReport());
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get a thread pool report.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string GetThreadPoolReport()
|
||||||
|
{
|
||||||
|
string threadPoolUsed = null;
|
||||||
|
int maxThreads = 0;
|
||||||
|
int minThreads = 0;
|
||||||
|
int allocatedThreads = 0;
|
||||||
|
int inUseThreads = 0;
|
||||||
|
int waitingCallbacks = 0;
|
||||||
|
int completionPortThreads = 0;
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
if (Util.FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool)
|
||||||
|
{
|
||||||
|
STPInfo stpi = Util.GetSmartThreadPoolInfo();
|
||||||
|
|
||||||
|
// ROBUST currently leaves this the FireAndForgetMethod but never actually initializes the threadpool.
|
||||||
|
if (stpi != null)
|
||||||
|
{
|
||||||
|
threadPoolUsed = "SmartThreadPool";
|
||||||
|
maxThreads = stpi.MaxThreads;
|
||||||
|
minThreads = stpi.MinThreads;
|
||||||
|
inUseThreads = stpi.InUseThreads;
|
||||||
|
allocatedThreads = stpi.ActiveThreads;
|
||||||
|
waitingCallbacks = stpi.WaitingCallbacks;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (
|
||||||
|
Util.FireAndForgetMethod == FireAndForgetMethod.QueueUserWorkItem
|
||||||
|
|| Util.FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem)
|
||||||
|
{
|
||||||
|
threadPoolUsed = "BuiltInThreadPool";
|
||||||
|
ThreadPool.GetMaxThreads(out maxThreads, out completionPortThreads);
|
||||||
|
ThreadPool.GetMinThreads(out minThreads, out completionPortThreads);
|
||||||
|
int availableThreads;
|
||||||
|
ThreadPool.GetAvailableThreads(out availableThreads, out completionPortThreads);
|
||||||
|
inUseThreads = maxThreads - availableThreads;
|
||||||
|
allocatedThreads = -1;
|
||||||
|
waitingCallbacks = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (threadPoolUsed != null)
|
||||||
|
{
|
||||||
|
sb.AppendFormat("Thread pool used : {0}\n", threadPoolUsed);
|
||||||
|
sb.AppendFormat("Max threads : {0}\n", maxThreads);
|
||||||
|
sb.AppendFormat("Min threads : {0}\n", minThreads);
|
||||||
|
sb.AppendFormat("Allocated threads : {0}\n", allocatedThreads < 0 ? "not applicable" : allocatedThreads.ToString());
|
||||||
|
sb.AppendFormat("In use threads : {0}\n", inUseThreads);
|
||||||
|
sb.AppendFormat("Work items waiting : {0}\n", waitingCallbacks < 0 ? "not available" : waitingCallbacks.ToString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sb.AppendFormat("Thread pool not used\n");
|
||||||
|
}
|
||||||
|
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,10 +88,31 @@ namespace OpenSim.Framework
|
||||||
Thread,
|
Thread,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Class for delivering SmartThreadPool statistical information
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// We do it this way so that we do not directly expose STP.
|
||||||
|
/// </remarks>
|
||||||
|
public class STPInfo
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public STPStartInfo STPStartInfo { get; set; }
|
||||||
|
public WIGStartInfo WIGStartInfo { get; set; }
|
||||||
|
public bool IsIdle { get; set; }
|
||||||
|
public bool IsShuttingDown { get; set; }
|
||||||
|
public int MaxThreads { get; set; }
|
||||||
|
public int MinThreads { get; set; }
|
||||||
|
public int InUseThreads { get; set; }
|
||||||
|
public int ActiveThreads { get; set; }
|
||||||
|
public int WaitingCallbacks { get; set; }
|
||||||
|
public int MaxConcurrentWorkItems { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Miscellaneous utility functions
|
/// Miscellaneous utility functions
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Util
|
public static class Util
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
@ -1852,74 +1873,31 @@ namespace OpenSim.Framework
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get a thread pool report.
|
/// Get information about the current state of the smart thread pool.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns>
|
||||||
public static string GetThreadPoolReport()
|
/// null if this isn't the pool being used for non-scriptengine threads.
|
||||||
|
/// </returns>
|
||||||
|
public static STPInfo GetSmartThreadPoolInfo()
|
||||||
{
|
{
|
||||||
string threadPoolUsed = null;
|
if (m_ThreadPool == null)
|
||||||
int maxThreads = 0;
|
return null;
|
||||||
int minThreads = 0;
|
|
||||||
int allocatedThreads = 0;
|
|
||||||
int inUseThreads = 0;
|
|
||||||
int waitingCallbacks = 0;
|
|
||||||
int completionPortThreads = 0;
|
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
STPInfo stpi = new STPInfo();
|
||||||
if (FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool)
|
stpi.Name = m_ThreadPool.Name;
|
||||||
{
|
stpi.STPStartInfo = m_ThreadPool.STPStartInfo;
|
||||||
// ROBUST currently leaves this the FireAndForgetMethod but never actually initializes the threadpool.
|
stpi.IsIdle = m_ThreadPool.IsIdle;
|
||||||
if (m_ThreadPool != null)
|
stpi.IsShuttingDown = m_ThreadPool.IsShuttingdown;
|
||||||
{
|
stpi.MaxThreads = m_ThreadPool.MaxThreads;
|
||||||
threadPoolUsed = "SmartThreadPool";
|
stpi.MinThreads = m_ThreadPool.MinThreads;
|
||||||
maxThreads = m_ThreadPool.MaxThreads;
|
stpi.InUseThreads = m_ThreadPool.InUseThreads;
|
||||||
minThreads = m_ThreadPool.MinThreads;
|
stpi.ActiveThreads = m_ThreadPool.ActiveThreads;
|
||||||
inUseThreads = m_ThreadPool.InUseThreads;
|
stpi.WaitingCallbacks = m_ThreadPool.WaitingCallbacks;
|
||||||
allocatedThreads = m_ThreadPool.ActiveThreads;
|
stpi.MaxConcurrentWorkItems = m_ThreadPool.Concurrency;
|
||||||
waitingCallbacks = m_ThreadPool.WaitingCallbacks;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (
|
|
||||||
FireAndForgetMethod == FireAndForgetMethod.QueueUserWorkItem
|
|
||||||
|| FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem)
|
|
||||||
{
|
|
||||||
threadPoolUsed = "BuiltInThreadPool";
|
|
||||||
ThreadPool.GetMaxThreads(out maxThreads, out completionPortThreads);
|
|
||||||
ThreadPool.GetMinThreads(out minThreads, out completionPortThreads);
|
|
||||||
int availableThreads;
|
|
||||||
ThreadPool.GetAvailableThreads(out availableThreads, out completionPortThreads);
|
|
||||||
inUseThreads = maxThreads - availableThreads;
|
|
||||||
allocatedThreads = -1;
|
|
||||||
waitingCallbacks = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (threadPoolUsed != null)
|
return stpi;
|
||||||
{
|
|
||||||
sb.AppendFormat("Thread pool used : {0}\n", threadPoolUsed);
|
|
||||||
sb.AppendFormat("Max threads : {0}\n", maxThreads);
|
|
||||||
sb.AppendFormat("Min threads : {0}\n", minThreads);
|
|
||||||
sb.AppendFormat("Allocated threads : {0}\n", allocatedThreads < 0 ? "not applicable" : allocatedThreads.ToString());
|
|
||||||
sb.AppendFormat("In use threads : {0}\n", inUseThreads);
|
|
||||||
sb.AppendFormat("Work items waiting : {0}\n", waitingCallbacks < 0 ? "not available" : waitingCallbacks.ToString());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sb.AppendFormat("Thread pool not used\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// private static object SmartThreadPoolCallback(object o)
|
|
||||||
// {
|
|
||||||
// object[] array = (object[])o;
|
|
||||||
// WaitCallback callback = (WaitCallback)array[0];
|
|
||||||
// object obj = array[1];
|
|
||||||
//
|
|
||||||
// callback(obj);
|
|
||||||
// return null;
|
|
||||||
// }
|
|
||||||
|
|
||||||
#endregion FireAndForget Threading Pattern
|
#endregion FireAndForget Threading Pattern
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
Loading…
Reference in New Issue