diff options
author | Matthew Pickering <matthewtpickering@gmail.com> | 2020-12-07 13:19:28 +0000 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2021-03-03 08:12:29 -0500 |
commit | d89deeba47ce04a5198a71fa4cbc203fe2c90794 (patch) | |
tree | 8f879bbb0774ce686e1688cc638ef22179babf51 /rts/Proftimer.c | |
parent | d8dc0f96237fe6fe7081c04727c7c2573477e5cb (diff) | |
download | haskell-d89deeba47ce04a5198a71fa4cbc203fe2c90794.tar.gz |
Profiling: Allow heap profiling to be controlled dynamically.
This patch exposes three new functions in `GHC.Profiling` which allow
heap profiling to be enabled and disabled dynamically.
1. startHeapProfTimer - Starts heap profiling with the given RTS options
2. stopHeapProfTimer - Stops heap profiling
3. requestHeapCensus - Perform a heap census on the next context
switch, regardless of whether the timer is enabled or not.
Diffstat (limited to 'rts/Proftimer.c')
-rw-r--r-- | rts/Proftimer.c | 45 |
1 files changed, 40 insertions, 5 deletions
diff --git a/rts/Proftimer.c b/rts/Proftimer.c index 00b92a227d..29abb62a8e 100644 --- a/rts/Proftimer.c +++ b/rts/Proftimer.c @@ -18,7 +18,12 @@ static bool do_prof_ticks = false; // enable profiling ticks #endif -static bool do_heap_prof_ticks = false; // enable heap profiling ticks +static bool do_heap_prof_ticks = false; // Whether the timer is currently ticking down +static bool heap_prof_timer_active = false; // Whether the timer is enabled at all + +/* The heap_prof_timer_active flag controls whether heap profiling is enabled +at all, once it is enabled, the `do_heap_prof_ticks` flag controls whether the +counter is currently counting down. This is paused, for example, in Schedule.c. */ // Sampling of Ticky-Ticky profiler to eventlog #if defined(TICKY_TICKY) && defined(TRACING) @@ -51,26 +56,56 @@ startProfTimer( void ) void stopHeapProfTimer( void ) { - RELAXED_STORE(&do_heap_prof_ticks, false); + if (RtsFlags.ProfFlags.doHeapProfile){ + RELAXED_STORE(&heap_prof_timer_active, false); + pauseHeapProfTimer(); + } } void startHeapProfTimer( void ) { + if (RtsFlags.ProfFlags.doHeapProfile){ + RELAXED_STORE(&heap_prof_timer_active, true); + resumeHeapProfTimer(); + } +} + +void +pauseHeapProfTimer ( void ) { + RELAXED_STORE(&do_heap_prof_ticks, false); +} + + +void +resumeHeapProfTimer ( void ) { if (RtsFlags.ProfFlags.doHeapProfile && RtsFlags.ProfFlags.heapProfileIntervalTicks > 0) { - do_heap_prof_ticks = true; + RELAXED_STORE(&do_heap_prof_ticks, true); } } void +requestHeapCensus( void ){ + // If no profiling mode is passed then just ignore the call. + if (RtsFlags.ProfFlags.doHeapProfile){ + RELAXED_STORE(&performHeapProfile, true); + } +} + +void initProfTimer( void ) { performHeapProfile = false; ticks_to_heap_profile = RtsFlags.ProfFlags.heapProfileIntervalTicks; - startHeapProfTimer(); + /* This might look a bit strange but the heap profile timer can + be toggled on/off from within Haskell by calling the startHeapProf + function from within Haskell */ + if (RtsFlags.ProfFlags.startHeapProfileAtStartup){ + startHeapProfTimer(); + } } uint32_t total_ticks = 0; @@ -99,7 +134,7 @@ handleProfTick(void) } #endif - if (RELAXED_LOAD(&do_heap_prof_ticks)) { + if (RELAXED_LOAD(&do_heap_prof_ticks) && RELAXED_LOAD(&heap_prof_timer_active)) { ticks_to_heap_profile--; if (ticks_to_heap_profile <= 0) { ticks_to_heap_profile = RtsFlags.ProfFlags.heapProfileIntervalTicks; |