summaryrefslogtreecommitdiff
path: root/rts/Proftimer.c
diff options
context:
space:
mode:
authorMatthew Pickering <matthewtpickering@gmail.com>2020-12-07 13:19:28 +0000
committerMarge Bot <ben+marge-bot@smart-cactus.org>2021-03-03 08:12:29 -0500
commitd89deeba47ce04a5198a71fa4cbc203fe2c90794 (patch)
tree8f879bbb0774ce686e1688cc638ef22179babf51 /rts/Proftimer.c
parentd8dc0f96237fe6fe7081c04727c7c2573477e5cb (diff)
downloadhaskell-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.c45
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;