aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Framework/Servers/ServerBase.cs63
-rw-r--r--OpenSim/Framework/Util.cs104
2 files changed, 103 insertions, 64 deletions
diff --git a/OpenSim/Framework/Servers/ServerBase.cs b/OpenSim/Framework/Servers/ServerBase.cs
index 5358444..029b848 100644
--- a/OpenSim/Framework/Servers/ServerBase.cs
+++ b/OpenSim/Framework/Servers/ServerBase.cs
@@ -667,7 +667,68 @@ namespace OpenSim.Framework.Servers
667 sb.AppendFormat("Total threads active: {0}\n\n", totalThreads); 667 sb.AppendFormat("Total threads active: {0}\n\n", totalThreads);
668 668
669 sb.Append("Main threadpool (excluding script engine pools)\n"); 669 sb.Append("Main threadpool (excluding script engine pools)\n");
670 sb.Append(Util.GetThreadPoolReport()); 670 sb.Append(GetThreadPoolReport());
671
672 return sb.ToString();
673 }
674
675 /// <summary>
676 /// Get a thread pool report.
677 /// </summary>
678 /// <returns></returns>
679 public static string GetThreadPoolReport()
680 {
681 string threadPoolUsed = null;
682 int maxThreads = 0;
683 int minThreads = 0;
684 int allocatedThreads = 0;
685 int inUseThreads = 0;
686 int waitingCallbacks = 0;
687 int completionPortThreads = 0;
688
689 StringBuilder sb = new StringBuilder();
690 if (Util.FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool)
691 {
692 STPInfo stpi = Util.GetSmartThreadPoolInfo();
693
694 // ROBUST currently leaves this the FireAndForgetMethod but never actually initializes the threadpool.
695 if (stpi != null)
696 {
697 threadPoolUsed = "SmartThreadPool";
698 maxThreads = stpi.MaxThreads;
699 minThreads = stpi.MinThreads;
700 inUseThreads = stpi.InUseThreads;
701 allocatedThreads = stpi.ActiveThreads;
702 waitingCallbacks = stpi.WaitingCallbacks;
703 }
704 }
705 else if (
706 Util.FireAndForgetMethod == FireAndForgetMethod.QueueUserWorkItem
707 || Util.FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem)
708 {
709 threadPoolUsed = "BuiltInThreadPool";
710 ThreadPool.GetMaxThreads(out maxThreads, out completionPortThreads);
711 ThreadPool.GetMinThreads(out minThreads, out completionPortThreads);
712 int availableThreads;
713 ThreadPool.GetAvailableThreads(out availableThreads, out completionPortThreads);
714 inUseThreads = maxThreads - availableThreads;
715 allocatedThreads = -1;
716 waitingCallbacks = -1;
717 }
718
719 if (threadPoolUsed != null)
720 {
721 sb.AppendFormat("Thread pool used : {0}\n", threadPoolUsed);
722 sb.AppendFormat("Max threads : {0}\n", maxThreads);
723 sb.AppendFormat("Min threads : {0}\n", minThreads);
724 sb.AppendFormat("Allocated threads : {0}\n", allocatedThreads < 0 ? "not applicable" : allocatedThreads.ToString());
725 sb.AppendFormat("In use threads : {0}\n", inUseThreads);
726 sb.AppendFormat("Work items waiting : {0}\n", waitingCallbacks < 0 ? "not available" : waitingCallbacks.ToString());
727 }
728 else
729 {
730 sb.AppendFormat("Thread pool not used\n");
731 }
671 732
672 return sb.ToString(); 733 return sb.ToString();
673 } 734 }
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index 5e5eb7e..ba6cc75 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -89,9 +89,30 @@ namespace OpenSim.Framework
89 } 89 }
90 90
91 /// <summary> 91 /// <summary>
92 /// Class for delivering SmartThreadPool statistical information
93 /// </summary>
94 /// <remarks>
95 /// We do it this way so that we do not directly expose STP.
96 /// </remarks>
97 public class STPInfo
98 {
99 public string Name { get; set; }
100 public STPStartInfo STPStartInfo { get; set; }
101 public WIGStartInfo WIGStartInfo { get; set; }
102 public bool IsIdle { get; set; }
103 public bool IsShuttingDown { get; set; }
104 public int MaxThreads { get; set; }
105 public int MinThreads { get; set; }
106 public int InUseThreads { get; set; }
107 public int ActiveThreads { get; set; }
108 public int WaitingCallbacks { get; set; }
109 public int MaxConcurrentWorkItems { get; set; }
110 }
111
112 /// <summary>
92 /// Miscellaneous utility functions 113 /// Miscellaneous utility functions
93 /// </summary> 114 /// </summary>
94 public class Util 115 public static class Util
95 { 116 {
96 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 117 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
97 118
@@ -1852,74 +1873,31 @@ namespace OpenSim.Framework
1852 } 1873 }
1853 1874
1854 /// <summary> 1875 /// <summary>
1855 /// Get a thread pool report. 1876 /// Get information about the current state of the smart thread pool.
1856 /// </summary> 1877 /// </summary>
1857 /// <returns></returns> 1878 /// <returns>
1858 public static string GetThreadPoolReport() 1879 /// null if this isn't the pool being used for non-scriptengine threads.
1880 /// </returns>
1881 public static STPInfo GetSmartThreadPoolInfo()
1859 { 1882 {
1860 string threadPoolUsed = null; 1883 if (m_ThreadPool == null)
1861 int maxThreads = 0; 1884 return null;
1862 int minThreads = 0;
1863 int allocatedThreads = 0;
1864 int inUseThreads = 0;
1865 int waitingCallbacks = 0;
1866 int completionPortThreads = 0;
1867
1868 StringBuilder sb = new StringBuilder();
1869 if (FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool)
1870 {
1871 // ROBUST currently leaves this the FireAndForgetMethod but never actually initializes the threadpool.
1872 if (m_ThreadPool != null)
1873 {
1874 threadPoolUsed = "SmartThreadPool";
1875 maxThreads = m_ThreadPool.MaxThreads;
1876 minThreads = m_ThreadPool.MinThreads;
1877 inUseThreads = m_ThreadPool.InUseThreads;
1878 allocatedThreads = m_ThreadPool.ActiveThreads;
1879 waitingCallbacks = m_ThreadPool.WaitingCallbacks;
1880 }
1881 }
1882 else if (
1883 FireAndForgetMethod == FireAndForgetMethod.QueueUserWorkItem
1884 || FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem)
1885 {
1886 threadPoolUsed = "BuiltInThreadPool";
1887 ThreadPool.GetMaxThreads(out maxThreads, out completionPortThreads);
1888 ThreadPool.GetMinThreads(out minThreads, out completionPortThreads);
1889 int availableThreads;
1890 ThreadPool.GetAvailableThreads(out availableThreads, out completionPortThreads);
1891 inUseThreads = maxThreads - availableThreads;
1892 allocatedThreads = -1;
1893 waitingCallbacks = -1;
1894 }
1895 1885
1896 if (threadPoolUsed != null) 1886 STPInfo stpi = new STPInfo();
1897 { 1887 stpi.Name = m_ThreadPool.Name;
1898 sb.AppendFormat("Thread pool used : {0}\n", threadPoolUsed); 1888 stpi.STPStartInfo = m_ThreadPool.STPStartInfo;
1899 sb.AppendFormat("Max threads : {0}\n", maxThreads); 1889 stpi.IsIdle = m_ThreadPool.IsIdle;
1900 sb.AppendFormat("Min threads : {0}\n", minThreads); 1890 stpi.IsShuttingDown = m_ThreadPool.IsShuttingdown;
1901 sb.AppendFormat("Allocated threads : {0}\n", allocatedThreads < 0 ? "not applicable" : allocatedThreads.ToString()); 1891 stpi.MaxThreads = m_ThreadPool.MaxThreads;
1902 sb.AppendFormat("In use threads : {0}\n", inUseThreads); 1892 stpi.MinThreads = m_ThreadPool.MinThreads;
1903 sb.AppendFormat("Work items waiting : {0}\n", waitingCallbacks < 0 ? "not available" : waitingCallbacks.ToString()); 1893 stpi.InUseThreads = m_ThreadPool.InUseThreads;
1904 } 1894 stpi.ActiveThreads = m_ThreadPool.ActiveThreads;
1905 else 1895 stpi.WaitingCallbacks = m_ThreadPool.WaitingCallbacks;
1906 { 1896 stpi.MaxConcurrentWorkItems = m_ThreadPool.Concurrency;
1907 sb.AppendFormat("Thread pool not used\n");
1908 }
1909 1897
1910 return sb.ToString(); 1898 return stpi;
1911 } 1899 }
1912 1900
1913// private static object SmartThreadPoolCallback(object o)
1914// {
1915// object[] array = (object[])o;
1916// WaitCallback callback = (WaitCallback)array[0];
1917// object obj = array[1];
1918//
1919// callback(obj);
1920// return null;
1921// }
1922
1923 #endregion FireAndForget Threading Pattern 1901 #endregion FireAndForget Threading Pattern
1924 1902
1925 /// <summary> 1903 /// <summary>