Exemple #1
0
        private static void OnTpRunning(ClrRuntime runtime, string args)
        {
            // Use ClrMD as normal, but ONLY cache the copy of ClrRuntime (this.Runtime).  All other
            // types you get out of ClrMD (such as ClrHeap, ClrTypes, etc) should be discarded and
            // reobtained every run.
            ClrThreadPool threadPool = runtime.ThreadPool;
            ClrHeap       heap       = runtime.Heap;

            // Console.WriteLine now writes to the debugger.

            ClrMDHelper helper = new ClrMDHelper(runtime);


            try
            {
                Console.WriteLine(string.Format(
                                      "\r\nCPU = {0}%% for {1} threads (#idle = {2} + #running = {3} | #dead = {4} | #max = {5})",
                                      threadPool.CpuUtilization.ToString(),
                                      threadPool.TotalThreads.ToString(),
                                      threadPool.IdleThreads.ToString(),
                                      threadPool.RunningThreads.ToString(),
                                      runtime.Threads.Count(t => t.IsThreadpoolWorker && !t.IsThreadpoolCompletionPort && !t.IsAlive && !t.IsThreadpoolGate && !t.IsThreadpoolTimer && !t.IsThreadpoolWait).ToString(),
                                      threadPool.MaxThreads.ToString()
                                      ));

                // show the running worker threads
                DumpRunningThreadpoolThreads(runtime, helper);
            }
            catch (Exception x)
            {
                Console.WriteLine(x.Message);
            }
        }
Exemple #2
0
        public static string CreateMarkup(this ClrThreadPool threadpool)
        {
            var html = new StringBuilder();

            html.Append($"<div>idle: {threadpool.IdleThreads}</div>");
            html.Append($"<div>running: {threadpool.RunningThreads}</div>");
            html.Append($"<div>total: {threadpool.TotalThreads}</div>");

            return(html.ToString());
        }
 /// <summary>
 ///     Initializes a new instance of the <see cref="ClrThreadPoolAdapter" /> class.
 /// </summary>
 /// <param name="threadPool">The thread pool.</param>
 /// <exception cref="ArgumentNullException">threadPool</exception>
 /// <inheritdoc />
 public ClrThreadPoolAdapter(IConverter converter, ClrThreadPool threadPool) : base(converter)
 {
     ThreadPool              = threadPool ?? throw new ArgumentNullException(nameof(threadPool));
     CpuUtilization          = ThreadPool.CpuUtilization;
     FreeCompletionPortCount = ThreadPool.FreeCompletionPortCount;
     IdleThreads             = ThreadPool.IdleThreads;
     MaxCompletionPorts      = ThreadPool.MaxCompletionPorts;
     MaxFreeCompletionPorts  = ThreadPool.MaxFreeCompletionPorts;
     MaxThreads              = ThreadPool.MaxThreads;
     MinCompletionPorts      = ThreadPool.MinCompletionPorts;
     MinThreads              = ThreadPool.MinThreads;
     RunningThreads          = ThreadPool.RunningThreads;
     TotalThreads            = ThreadPool.TotalThreads;
 }
Exemple #4
0
        private void PrintThreadPoolInfo()
        {
            if (context.Runtime != null)
            {
                ClrThreadPool threadPool = this.context.Runtime.GetThreadPool();

                if (threadPool != null)
                {
                    context.WriteLine("Total threads:     {0}", threadPool.TotalThreads);
                    context.WriteLine("Running threads:   {0}", threadPool.RunningThreads);
                    context.WriteLine("Max threads:       {0}", threadPool.MaxThreads);
                    context.WriteLine("Min threads:       {0}", threadPool.MinThreads);
                    context.WriteLine("Idle threads:      {0}", threadPool.IdleThreads);
                    context.WriteLine("CPU utilization    {0}% (estimated)", threadPool.CpuUtilization);
                }
            }
        }
        private static void OnTpRunning(IntPtr client, [MarshalAs(UnmanagedType.LPStr)] string args)
        {
            // Must be the first thing in our extension.
            if (!InitApi(client))
            {
                return;
            }

            // Use ClrMD as normal, but ONLY cache the copy of ClrRuntime (this.Runtime).  All other
            // types you get out of ClrMD (such as ClrHeap, ClrTypes, etc) should be discarded and
            // reobtained every run.
            ClrThreadPool threadPool = Runtime.GetThreadPool();
            ClrHeap       heap       = Runtime.GetHeap();

            // Console.WriteLine now writes to the debugger.

            ClrMDHelper helper = new ClrMDHelper(Runtime);


            try
            {
                Console.WriteLine(string.Format(
                                      "\r\nCPU = {0}%% for {1} threads (#idle = {2} + #running = {3} | #dead = {4} | #max = {5})",
                                      threadPool.CpuUtilization.ToString(),
                                      threadPool.TotalThreads.ToString(),
                                      threadPool.IdleThreads.ToString(),
                                      threadPool.RunningThreads.ToString(),
                                      Runtime.Threads.Count(t => t.IsThreadpoolWorker && !t.IsThreadpoolCompletionPort && !t.IsAlive && !t.IsThreadpoolGate && !t.IsThreadpoolTimer && !t.IsThreadpoolWait).ToString(),
                                      threadPool.MaxThreads.ToString()
                                      ));

                // show the running worker threads
                DumpRunningThreadpoolThreads(helper);
            }
            catch (Exception x)
            {
                Console.WriteLine(x.Message);
            }
        }
        public static void OnTpQueues(IntPtr client, [MarshalAs(UnmanagedType.LPStr)] string args)
        {
            // Must be the first thing in our extension.
            if (!InitApi(client))
            {
                return;
            }

            Dictionary <string, WorkInfo> _workItems = new Dictionary <string, WorkInfo>();
            int _workItemCount = 0;
            Dictionary <string, WorkInfo> _tasks = new Dictionary <string, WorkInfo>();
            int _taskCount = 0;

            // Use ClrMD as normal, but ONLY cache the copy of ClrRuntime (this.Runtime).  All other
            // types you get out of ClrMD (such as ClrHeap, ClrTypes, etc) should be discarded and
            // reobtained every run.
            ClrThreadPool threadPool = Runtime.GetThreadPool();
            ClrHeap       heap       = Runtime.GetHeap();

            // Console.WriteLine now writes to the debugger.

            ClrMDHelper helper = new ClrMDHelper(Runtime);

            // The ThreadPool is keeping track of the pending work items into two different areas:
            // - a global queue: stored by ThreadPoolWorkQueue instances of the ThreadPoolGlobals.workQueue static field
            // - several per thread (TLS) local queues: stored in SparseArray<ThreadPoolWorkQueue+WorkStealingQueue> linked from ThreadPoolWorkQueue.allThreadQueues static fields
            // both are using arrays of Task or QueueUserWorkItemCallback
            //
            // NOTE: don't show other thread pool related topics such as timer callbacks or wait objects
            //
            try
            {
                Console.WriteLine("global work item queue________________________________");
                foreach (var item in helper.EnumerateGlobalThreadPoolItems())
                {
                    switch (item.Type)
                    {
                    case ThreadRoot.Task:
                        Console.Write(string.Format("<link cmd=\"!do {0:X16}\">0x{0:X16}</link> Task", item.Address));
                        Console.WriteLine(" | " + item.MethodName);
                        UpdateStats(_tasks, item.MethodName, ref _taskCount);
                        break;

                    case ThreadRoot.WorkItem:
                        Console.Write(string.Format("<link cmd=\"!do {0}\">0x{0:X16}</link> Work", item.Address));
                        Console.WriteLine(" | " + item.MethodName);
                        UpdateStats(_workItems, item.MethodName, ref _workItemCount);
                        break;

                    default:
                        Console.WriteLine(string.Format("<link cmd=\"!do {0}\">0x{0:X16}</link> {1}", item.Address, item.MethodName));
                        break;
                    }
                }

                // look into the local stealing queues in each thread TLS
                // hopefully, they are all stored in static (one per app domain) instance
                // of ThreadPoolWorkQueue.SparseArray<ThreadPoolWorkQueue.WorkStealingQueue>
                //
                Console.WriteLine("\r\nlocal per thread work items_____________________________________");
                try
                {
                    foreach (var item in helper.EnumerateLocalThreadPoolItems())
                    {
                        switch (item.Type)
                        {
                        case ThreadRoot.Task:
                            Console.Write(string.Format("<link cmd=\"!do {0:X}\">0x{0:X16}</link> Task", item.Address));
                            Console.WriteLine(" | " + item.MethodName);
                            UpdateStats(_tasks, item.MethodName, ref _taskCount);
                            break;

                        case ThreadRoot.WorkItem:
                            Console.Write(string.Format("<link cmd=\"!do {0}\">0x{0:X16}</link> Work", item.Address));
                            Console.WriteLine(" | " + item.MethodName);
                            UpdateStats(_workItems, item.MethodName, ref _workItemCount);
                            break;

                        default:
                            Console.WriteLine(string.Format("<link cmd=\"!do {0:X}\">0x{0:X16}</link> {1}", item.Address, item.MethodName));
                            break;
                        }
                    }
                }
                finally
                {
                    Console.WriteLine("");

                    // provide a summary sorted by count
                    // tasks first if any
                    if (_tasks.Values.Count > 0)
                    {
                        foreach (var item in _tasks.Values.OrderBy(wi => wi.Count))
                        {
                            Console.WriteLine(string.Format(" {0,4} Task  {1}", item.Count.ToString(), item.Name));
                        }
                        Console.WriteLine(" ----");
                        Console.WriteLine(string.Format(" {0,4}\r\n", _taskCount.ToString()));
                    }

                    // then QueueUserWorkItem next if any
                    if (_workItems.Values.Count > 0)
                    {
                        foreach (var item in _workItems.Values.OrderBy(wi => wi.Count))
                        {
                            Console.WriteLine(string.Format(" {0,4} Work  {1}", item.Count.ToString(), item.Name));
                        }
                        Console.WriteLine(" ----");
                        Console.WriteLine(string.Format(" {0,4}\r\n", _workItemCount.ToString()));
                    }
                }
            }
            catch (Exception x)
            {
                Console.WriteLine(x.Message);
            }
        }
 public ThreadPoolInformation(ClrDump clrDump, ClrThreadPool threadPool)
 {
     ClrDump    = clrDump;
     ThreadPool = threadPool;
 }
Exemple #8
0
        public static void OnTpQueues(ClrRuntime runtime, string args)
        {
            Dictionary <string, WorkInfo> _workItems = new Dictionary <string, WorkInfo>();
            int _workItemCount = 0;
            Dictionary <string, WorkInfo> _tasks = new Dictionary <string, WorkInfo>();
            int _taskCount = 0;

            // Use ClrMD as normal, but ONLY cache the copy of ClrRuntime (this.Runtime).  All other
            // types you get out of ClrMD (such as ClrHeap, ClrTypes, etc) should be discarded and
            // reobtained every run.
            ClrThreadPool threadPool = runtime.ThreadPool;
            ClrHeap       heap       = runtime.Heap;

            // Console.WriteLine now writes to the debugger.

            ClrMDHelper helper = new ClrMDHelper(runtime);

            // The ThreadPool is keeping track of the pending work items into two different areas:
            // - a global queue
            // - several per thread (TLS) local queues
            //
            // NOTE: don't show other thread pool related topics such as timer callbacks or wait objects
            //
            try
            {
                Console.WriteLine("global work item queue________________________________");
                foreach (var item in helper.EnumerateGlobalThreadPoolItems())
                {
                    switch (item.Type)
                    {
                    case ThreadRoot.Task:
                        Console.Write(string.Format("<link cmd=\"!do {0:X}\">0x{0:X16}</link> Task", item.Address));
                        Console.WriteLine(" | " + item.MethodName);
                        UpdateStats(_tasks, item.MethodName, ref _taskCount);
                        break;

                    case ThreadRoot.WorkItem:
                        Console.Write(string.Format("<link cmd=\"!do {0:X}\">0x{0:X16}</link> Work", item.Address));
                        Console.WriteLine(" | " + item.MethodName);
                        UpdateStats(_workItems, item.MethodName, ref _workItemCount);
                        break;

                    default:
                        Console.WriteLine(string.Format("<link cmd=\"!do {0:X}\">0x{0:X16}</link> {1}", item.Address, item.MethodName));
                        break;
                    }
                }

                Console.WriteLine("\r\nlocal per thread work items_____________________________________");
                try
                {
                    foreach (var item in helper.EnumerateLocalThreadPoolItems())
                    {
                        switch (item.Type)
                        {
                        case ThreadRoot.Task:
                            Console.Write(string.Format("<link cmd=\"!do {0:X}\">0x{0:X16}</link> Task", item.Address));
                            Console.WriteLine(" | " + item.MethodName);
                            UpdateStats(_tasks, item.MethodName, ref _taskCount);
                            break;

                        case ThreadRoot.WorkItem:
                            Console.Write(string.Format("<link cmd=\"!do {0:X}\">0x{0:X16}</link> Work", item.Address));
                            Console.WriteLine(" | " + item.MethodName);
                            UpdateStats(_workItems, item.MethodName, ref _workItemCount);
                            break;

                        default:
                            Console.WriteLine(string.Format("<link cmd=\"!do {0:X}\">0x{0:X16}</link> {1}", item.Address, item.MethodName));
                            break;
                        }
                    }
                }
                finally
                {
                    Console.WriteLine("");

                    // provide a summary sorted by count
                    // tasks first if any
                    if (_tasks.Values.Count > 0)
                    {
                        foreach (var item in _tasks.Values.OrderBy(wi => wi.Count))
                        {
                            Console.WriteLine(string.Format(" {0,4} Task  {1}", item.Count.ToString(), item.Name));
                        }
                        Console.WriteLine(" ----");
                        Console.WriteLine(string.Format(" {0,4}\r\n", _taskCount.ToString()));
                    }

                    // then QueueUserWorkItem next if any
                    if (_workItems.Values.Count > 0)
                    {
                        foreach (var item in _workItems.Values.OrderBy(wi => wi.Count))
                        {
                            Console.WriteLine(string.Format(" {0,4} Work  {1}", item.Count.ToString(), item.Name));
                        }
                        Console.WriteLine(" ----");
                        Console.WriteLine(string.Format(" {0,4}\r\n", _workItemCount.ToString()));
                    }
                }
            }
            catch (Exception x)
            {
                Console.WriteLine(x.Message);
            }
        }