Skip to content

Commit 65aa602

Browse files
authored
[Profiler][Docs] Cleanup Profiler Pinning documentation (#110375)
* [Profiler][Docs] Update remaining instances of BEGIN/END_PIN_PROFILER * [Profiler][Docs] Update profiler pinning comments
1 parent e165eb4 commit 65aa602

File tree

4 files changed

+30
-27
lines changed

4 files changed

+30
-27
lines changed

docs/design/coreclr/botr/profilability.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,22 +31,23 @@ ICorProfilerCallback
3131

3232
This interface comprises the callbacks made by the CLR into the profiler to notify the profiler of interesting events. Each callback is wrapped in a thin method in the EE that handles locating the profiler's implementation of ICorProfilerCallback(2), and calling its corresponding method.
3333

34-
Profilers subscribe to events by specifying the corresponding flag in a call to ICorProfilerInfo::SetEventMask(). The profiling API stores these choices and exposes them to the CLR through specialized inline functions (CORProfiler\*) that mask against the bit corresponding to the flag. Then, sprinkled throughout the CLR, you'll see code that calls the ICorProfilerCallback wrapper to notify the profiler of events as they happen, but this call is conditional on the flag being set (determined by calling the specialized inline function):
34+
Profilers subscribe to events by specifying the corresponding flag in a call to ICorProfilerInfo::SetEventMask()/ICorProfilerInfo::SetEventMask2(). The profiling API stores these choices and exposes them to the CLR through specialized inline functions (CORProfiler\*) that mask against the bit corresponding to the flag. Then, sprinkled throughout the CLR, you'll see code that calls the ICorProfilerCallback wrapper to notify the profiler of events as they happen, but this call is conditional on the flag being set (determined by calling the specialized inline function):
3535

3636
{
37-
//check if profiler set flag, pin profiler
38-
BEGIN_PIN_PROFILER(CORProfilerTrackModuleLoads());
37+
// check if profiler set flag
38+
BEGIN_PROFILER_CALLBACK(CORProfilerTrackModuleLoads());
3939

40-
//call the wrapper around the profiler's callback implementation
41-
g_profControlBlock.pProfInterface->ModuleLoadStarted((ModuleID) this);
40+
// call the ProfControlBlock wrapper around the profiler's callback implementation
41+
// which pins the profiler in DoOneProfilerIteration via EvacuationCounterHolder
42+
(&g_profControlBlock)->ModuleLoadStarted((ModuleID) this);
43+
// unpins the profiler after completing the callback
4244

43-
//unpin profiler
44-
END_PIN_PROFILER();
45+
END_PROFILER_CALLBACK();
4546
}
4647

4748
To be clear, the code above is what you'll see sprinkled throughout the code base. The function it calls (in this case ModuleLoadStarted()) is our wrapper around the profiler's callback implementation (in this case ICorProfilerCallback::ModuleLoadStarted()). All of our wrappers appear in a single file (vm\EEToProfInterfaceImpl.cpp), and the guidance provided in the sections below relate to those wrappers; not to the above sample code that calls the wrappers.
4849

49-
The macro BEGIN\_PIN\_PROFILER evaluates the expression passed as its argument. If the expression is TRUE, then the profiler is pinned into memory (meaning the profiler will not be able to detach from the process) and the code between the BEGIN\_PIN\_PROFILER and END\_PIN\_PROFILER macros is executed. If the expression is FALSE, all code between the BEGIN\_PIN\_PROFILER and END\_PIN\_PROFILER macros is skipped. For more information about the BEGIN\_PIN\_PROFILER and END\_PIN\_PROFILER macros, find their definition in the code base and read the comments there.
50+
The macro BEGIN_PROFILER_CALLBACK evaluates the expression passed as its argument. If the expression is TRUE, the code between the BEGIN_PROFILER_CALLBACK and END_PROFILER_CALLBACK macros is executed, and the profiler is pinned into memory (meaning the profiler will not be able to detach from the process) through the ProfControlBlock wrapper. If the expression is FALSE, all code between the BEGIN_PROFILER_CALLBACK and END_PROFILER_CALLBACK macros is skipped. For more information about the BEGIN_PROFILER_CALLBACK and END_PROFILER_CALLBACK macros, find their definition in the code base and read the comments there.
5051

5152
Contracts
5253
---------

src/coreclr/inc/profilepriv.inl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2114,7 +2114,7 @@ FORCEINLINE BOOL CORProfilerTrackEventPipe()
21142114
// These macros must be placed around any callbacks to g_profControlBlock by
21152115
// the EE. Example:
21162116
// {
2117-
// BEGIN_PROFILER_CALLBACK(CORProfilerTrackAppDomainLoads;
2117+
// BEGIN_PROFILER_CALLBACK(CORProfilerTrackAppDomainLoads());
21182118
// g_profControlBlock.AppDomainCreationStarted(MyAppDomainID);
21192119
// END_PROFILER_CALLBACK();
21202120
// }
@@ -2129,7 +2129,7 @@ FORCEINLINE BOOL CORProfilerTrackEventPipe()
21292129
// block. Example:
21302130
//
21312131
// {
2132-
// BEGIN_PROFILER_CALLBACK(CorProfilerTrackTransitions);
2132+
// BEGIN_PROFILER_CALLBACK(CorProfilerTrackTransitions());
21332133
// if (!pNSL->pMD->IsQCall())
21342134
// {
21352135
// g_profControlBlock.

src/coreclr/nativeaot/Runtime/eventtrace_gcheap.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -232,13 +232,13 @@ void ETW::GCLog::MovedReference(
232232
#ifdef PROFILING_SUPPORTED
233233
// ProfAPI
234234
{
235-
BEGIN_PIN_PROFILER(CORProfilerTrackGC());
235+
BEGIN_PROFILER_CALLBACK(CORProfilerTrackGC());
236236
g_profControlBlock.pProfInterface->MovedReference(pbMemBlockStart,
237237
pbMemBlockEnd,
238238
cbRelocDistance,
239239
&(pCtxForEtwAndProfapi->pctxProfAPI),
240240
fCompacting);
241-
END_PIN_PROFILER();
241+
END_PROFILER_CALLBACK();
242242
}
243243
#endif // PROFILING_SUPPORTED
244244

@@ -358,9 +358,9 @@ void ETW::GCLog::EndMovedReferences(size_t profilingContext,
358358
#ifdef PROFILING_SUPPORTED
359359
// ProfAPI
360360
{
361-
BEGIN_PIN_PROFILER(CORProfilerTrackGC());
361+
BEGIN_PROFILER_CALLBACK(CORProfilerTrackGC());
362362
g_profControlBlock.pProfInterface->EndMovedReferences(&(pCtxForEtwAndProfapi->pctxProfAPI));
363-
END_PIN_PROFILER();
363+
END_PROFILER_CALLBACK();
364364
}
365365
#endif //PROFILING_SUPPORTED
366366

src/coreclr/vm/profilinghelper.cpp

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -53,26 +53,28 @@
5353
// following format:
5454
// {
5555
// BEGIN_PROFILER_CALLBACK(CORProfilerTrackAppDomainLoads());
56-
// g_profControlBlock.pProfInterface->AppDomainCreationStarted(MyAppDomainID);
56+
// // call the ProfControlBlock callback wrapper
57+
// (&g_profControlBlock)->AppDomainCreationStarted(MyAppDomainID);
5758
// END_PROFILER_CALLBACK();
5859
// }
59-
// The BEGIN / END macros do the following:
60-
// * Evaluate the expression argument (e.g., CORProfilerTrackAppDomainLoads()). This is a
60+
// The BEGIN / END macros evaluates the expression argument (CORProfiler*). This is a
6161
// "dirty read" as the profiler could be detached at any moment during or after that
6262
// evaluation.
63-
// * If true, push a code:EvacuationCounterHolder on the stack, which increments the
64-
// per-thread evacuation counter (not interlocked).
65-
// * Re-evaluate the expression argument. This time, it's a "clean read" (see below for
66-
// why).
67-
// * If still true, execute the statements inside the BEGIN/END block. Inside that block,
68-
// the profiler is guaranteed to remain loaded, because the evacuation counter
69-
// remains nonzero (again, see below).
70-
// * Once the BEGIN/END block is exited, the evacuation counter is decremented, and the
71-
// profiler is unpinned and allowed to detach.
63+
//
64+
// The ProfControlBlock callback wrappers call DoOneProfilerIteration, doing the following:
65+
// * Pushes a code:EvacuationCounterHolder on the stack for the ProfilerInfo, which
66+
// increments the per-thread evacuation counter (not interlocked).
67+
// * Checks the profiler status (code:ProfilerStatus) to see if the profiler is active.
68+
// * Evaluates the ProfControlBlock condition func (e.g. IsProfilerTrackingAppDomainLoads).
69+
// * If true, invokes the callback func (e.g. AppDomainCreationStartedHelper) which in turn
70+
// calls the EEToProfInterfaceImpl implementation where the profiler is guaranteed to
71+
// remain loaded, because the evacuation counter remains nonzero (again, see below).
72+
// * Once the DoOneProfilerIteration block is exited, the evacuation counter is decremented
73+
// and the profiler is unpinned and allowed to detach.
7274
//
7375
// READER / WRITER COORDINATION
7476
//
75-
// The above ensures that a reader never touches g_profControlBlock.pProfInterface and
77+
// The above ensures that a reader never touches EEToProfInterfaceImpl and
7678
// all it embodies (including the profiler DLL code and callback implementations) unless
7779
// the reader was able to increment its thread's evacuation counter AND re-verify that
7880
// the profiler's status is still active (the status check is included in the macro's

0 commit comments

Comments
 (0)