Skip to content

Comments

!threadpool -stat#5737

Open
leculver wants to merge 4 commits intodotnet:mainfrom
leculver:issue_531
Open

!threadpool -stat#5737
leculver wants to merge 4 commits intodotnet:mainfrom
leculver:issue_531

Conversation

@leculver
Copy link
Contributor

Quick fix to add David's requested -stat to threadpool. The formatting code already exists in DumpHeapService, we just turn the print into an enumeration and either dump the stats or the raw work items.

Fixes #531

@leculver leculver requested a review from a team as a code owner February 22, 2026 03:41
Copilot AI review requested due to automatic review settings February 22, 2026 03:41
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a -stat option to the !threadpool command to display a DumpHeap-style summary of queued work items grouped by type. The implementation refactors the existing DumpWorkItems() method to extract an EnumerateAllWorkItems() method that yields work items, which can then be consumed either by the original display logic or by the new stats display via DumpHeapService.PrintHeap().

Changes:

  • Added -stat option to display statistical summary of thread pool work items
  • Refactored work item enumeration into a reusable EnumerateAllWorkItems() method
  • Added test coverage for the new -stat option

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/Microsoft.Diagnostics.ExtensionCommands/ThreadPoolCommand.cs Adds -stat option, DumpHeapService import, refactors work item enumeration, and updates help text
src/tests/SOS.UnitTests/Scripts/OtherCommands.script Adds test coverage for !threadpool -stat command

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Adds a -stat flag to the threadpool command that produces a DumpHeap-style
summary of queued work items grouped by type (MT, Count, TotalSize, Class Name).
Delegates to DumpHeapService.PrintHeap with statsOnly: true.

Refactors work item enumeration into EnumerateAllWorkItemsWithPriority() that
returns (ClrObject, bool IsHighPri) tuples, preserving the high-priority
distinction for -wi output. EnumerateAllWorkItems() wraps it for -stat.

Adds mutual exclusivity check: -wi and -stat cannot be specified together.
Prints 'No queued work items.' when -stat finds nothing.

Fixes dotnet#531

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@leculver
Copy link
Contributor Author

Manually tested with:

using System.Diagnostics;

// Saturate the thread pool so subsequent items stay queued.
ManualResetEventSlim blocker = new(false);
int satCount = Environment.ProcessorCount * 2;
for (int i = 0; i < satCount; i++)
    ThreadPool.QueueUserWorkItem(_ => blocker.Wait());

// Let saturation threads start.
Thread.Sleep(1000);

// Queue diverse work items that will remain in the queue.
for (int i = 0; i < 20; i++)
    ThreadPool.QueueUserWorkItem(_ => blocker.Wait());
for (int i = 0; i < 10; i++)
    Task.Run(() => blocker.Wait());

Thread.Sleep(500);

Console.WriteLine("Work items queued. Break here.");
Debugger.Break();

// Clean up.
blocker.Set();
Thread.Sleep(200);

Result:

0:000> !ThreadPool -stat
Using the Portable thread pool.

CPU utilization:  2%
Workers Total:    22
Workers Running:  22
Workers Idle:     0
Worker Min Limit: 20
Worker Max Limit: 32767

Statistics:
          MT Count TotalSize Class Name
7ff9b12e2b80    10       640 System.Threading.Tasks.Task
7ff9b12e4a20    38     1,216 System.Threading.QueueUserWorkItemCallbackDefaultContext
Total 48 objects, 1,856 bytes

0:000> !ThreadPool -wi
Using the Portable thread pool.

CPU utilization:  1%
Workers Total:    22
Workers Running:  22
Workers Idle:     0
Worker Min Limit: 20
Worker Max Limit: 32767

Queue             Object           Type
[Global]          021c06c9e7a0     System.Threading.QueueUserWorkItemCallbackDefaultContext
[Global]          021c06c9e7c0     System.Threading.QueueUserWorkItemCallbackDefaultContext
...  (38 QueueUserWorkItemCallbackDefaultContext rows)
[Global]          021c06cff9d0     System.Threading.Tasks.Task
[Global]          021c06cffa68     System.Threading.Tasks.Task
...  (10 Task rows)

0:000> !ThreadPool -wi -stat
Using the Portable thread pool.

CPU utilization:  10%
Workers Total:    21
Workers Running:  21
Workers Idle:     0
Worker Min Limit: 20
Worker Max Limit: 32767

Queue             Object           Type
[Global]          025aa0c9e7a0     System.Threading.QueueUserWorkItemCallbackDefaultContext
...  (39 QueueUserWorkItemCallbackDefaultContext rows)
[Global]          025aa0cff9d0     System.Threading.Tasks.Task
...  (10 Task rows)

Statistics:
          MT Count TotalSize Class Name
7ff9b12e2b80    10       640 System.Threading.Tasks.Task
7ff9b12e4a20    39     1,248 System.Threading.QueueUserWorkItemCallbackDefaultContext
Total 49 objects, 1,888 bytes

0:000> !ThreadPool
Using the Portable thread pool.

CPU utilization:  2%
Workers Total:    22
Workers Running:  22
Workers Idle:     0
Worker Min Limit: 20
Worker Max Limit: 32767

I can add this test to SOS's test matrix if requested, but these kind of threadpool tests are sometimes flakey and hard to maintain due to changes in how async/threadpool changes over time. Happy to do so if requested though.

We already have good coverage of the -stat code in !dumpheap and friends, and this mostly just shuffles some data with yield return instead of printing directly.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add threadpool -stat

1 participant