views:

764

answers:

3

From C#, is it possible to detect the number of context switches that occurred while executing a block of code on a particular thread? Ideally, I'd like to know how many times and what CPU my thread code was scheduled on.

I know I can use tools like Event Tracing for Windows and the associated viewers, but this seemed a bit complicated to get the data I wanted.

Also, tools like Process Explorer make it too hard to tell how many switches occurred as a result of a specific block of code.

Background: I'm trying to test the actual performance of a low level lock primitive in .NET (as a result of some comments on a recent blog post I made.

+3  A: 

It sounds like you may be looking for a programmatic solution, but if not, Microsoft's Process Explorer tool will tell you very easily the number of context switches for a particular thread.

Once in the tool, double-click your process, select the Threads tab, and select your thread.

The .NET tab has more specific .NET-related perf data.

Michael Petrotta
Right, I'm looking for more of a programmatic solution since procexp won't tell me the number of switches that occurred in a specific block. It'd be too hard to factor that out from the procexp numbers.
Jeff Moser
+1  A: 

I've never done this, but here are a few leads that might help:

  1. The .NET profiler APIs might allow you to hook in? The ICorProfilerCallback interface has RuntimeThreadSuspended and RuntimeThreadResumed callbacks. But a comment on this blog post seems to indicate that they won't get you what you are looking for: "RuntimeThreadSuspended is issued when a thread is being suspended by the runtime, typically in preparation for doing a GC."

  2. There is a "Context Switches/sec" perfmon counter that might help. I haven't looked at this counter specifically, but I'm guessing it operates on Win32 threads and not managed threads. You can use the profiling APIs to get the Win32 thread ID for any given managed thread ID.

Good luck! ;)

Aaron Lerch
Thanks for the information!I think the suspension is as you say (e.g. the GC freezing a thread so that it can rearrange memory) rather than a normal context switch.I looked into Context switches/sec, but couldn't get it for a single block. Perhaps there is a way to get the val before and after.
Jeff Moser
A: 

It looks like procexp might be using the kernel thread (KTHREAD) or executive thread (ETHREAD) data structures that have a ContextSwitches field on them. It might be possible to get this from managed code.

Jeff Moser