diff --git a/rts/Capability.c b/rts/Capability.c index 3d55b421f8e453e5c5be0e1b55f5dd8f3a930cd5..510656f473b6c4911f54e32b12cc50cca2e87b1f 100644 --- a/rts/Capability.c +++ b/rts/Capability.c @@ -673,8 +673,7 @@ shutdownCapability (Capability *cap, Task *task) continue; } debugTrace(DEBUG_sched, "capability %d is stopped.", cap->no); - stgFree(cap->mut_lists); - freeSparkPool(&cap->r.rSparks); + freeCapability(cap); RELEASE_LOCK(&cap->lock); break; } @@ -712,4 +711,11 @@ tryGrabCapability (Capability *cap, Task *task) #endif /* THREADED_RTS */ +void +freeCapability (Capability *cap) { + stgFree(cap->mut_lists); +#if defined(THREADED_RTS) || defined(PARALLEL_HASKELL) + freeSparkPool(&cap->r.rSparks); +#endif +} diff --git a/rts/Capability.h b/rts/Capability.h index dd17863c604c3b759ef961163dca4a6adf703e66..dedd6351b693bebc23ba0f0bac3584e29f2f17d5 100644 --- a/rts/Capability.h +++ b/rts/Capability.h @@ -232,6 +232,9 @@ extern void grabCapability (Capability **pCap); #endif /* !THREADED_RTS */ +// Free a capability on exit +void freeCapability (Capability *cap); + /* ----------------------------------------------------------------------------- * INLINE functions... private below here * -------------------------------------------------------------------------- */ diff --git a/rts/ProfHeap.c b/rts/ProfHeap.c index 4aecd0b5b3fcc6b9b92db05c4a3f290a686eba33..e93151d4f44dd930b9fd4067c33157268b3535eb 100644 --- a/rts/ProfHeap.c +++ b/rts/ProfHeap.c @@ -316,6 +316,13 @@ initEra(Census *census) census->drag_total = 0; } +STATIC_INLINE void +freeEra(Census *census) +{ + arenaFree(census->arena); + freeHashTable(census->hash, NULL); +} + /* -------------------------------------------------------------------------- * Increases era by 1 and initialize census[era]. * Reallocates gi[] and increases its size if needed. @@ -355,6 +362,10 @@ void initProfiling1( void ) { } +void freeProfiling1( void ) +{ +} + void initProfiling2( void ) { if (RtsFlags.ProfFlags.doHeapProfile) { @@ -493,6 +504,14 @@ endHeapProfiling(void) } #endif + { + nat t; + for (t = 0; t <= era; t++) { + freeEra( &censuses[t] ); + } + } + stgFree(censuses); + seconds = mut_user_time(); printSample(rtsTrue, seconds); printSample(rtsFalse, seconds); diff --git a/rts/Profiling.c b/rts/Profiling.c index a8650788e95df0480f0f89b90fa449f323ae0f8e..4e759b6942a85ba7d618d3ebc01e89e4859a71bb 100644 --- a/rts/Profiling.c +++ b/rts/Profiling.c @@ -185,6 +185,12 @@ initProfiling1 (void) */ } +void +freeProfiling1 (void) +{ + arenaFree(prof_arena); +} + void initProfiling2 (void) { diff --git a/rts/Profiling.h b/rts/Profiling.h index d968349a527cefe6500dd26e3341504f2ff139fb..edfc1b2c5e9851dbdefbf76f59839670affd6798 100644 --- a/rts/Profiling.h +++ b/rts/Profiling.h @@ -13,6 +13,7 @@ #if defined(PROFILING) || defined(DEBUG) void initProfiling1 ( void ); +void freeProfiling1 ( void ); void initProfiling2 ( void ); void endProfiling ( void ); diff --git a/rts/RtsSignals.h b/rts/RtsSignals.h index eafeeaaf5543abecbcf22fc5b2dc44c0b630fec5..6d9374a70c5e6b4db6e304c6c6fe9b5630588c9d 100644 --- a/rts/RtsSignals.h +++ b/rts/RtsSignals.h @@ -41,6 +41,8 @@ extern void initUserSignals(void); */ extern void initDefaultHandlers(void); +extern void freeSignalHandlers(void); + /* * Function: blockUserSignals() * diff --git a/rts/RtsStartup.c b/rts/RtsStartup.c index 87df96a13c91a36d41252e863ab3b7353ed46af1..7193876970c59c87063f1ee84f48fb38236eef46 100644 --- a/rts/RtsStartup.c +++ b/rts/RtsStartup.c @@ -378,6 +378,10 @@ hs_exit(void) /* start timing the shutdown */ stat_startExit(); +#if defined(RTS_USER_SIGNALS) + freeSignalHandlers(); +#endif + #if defined(THREADED_RTS) ioManagerDie(); #endif @@ -447,6 +451,10 @@ hs_exit(void) /* free the stable pointer table */ exitStablePtrTable(); +#if defined(PROFILING) || defined(DEBUG) + freeProfiling1(); +#endif + #if defined(DEBUG) /* free the thread label table */ freeThreadLabelTable(); diff --git a/rts/Schedule.c b/rts/Schedule.c index 8ebedd4279f4d897e286efc7aadeeda9f0e9fd2a..a11a15e94d9733a9a84c79adddaa61e60597dc66 100644 --- a/rts/Schedule.c +++ b/rts/Schedule.c @@ -2581,6 +2581,8 @@ exitScheduler( void ) boundTaskExiting(task); stopTaskManager(); } +#else + freeCapability(&MainCapability); #endif } @@ -2588,6 +2590,9 @@ void freeScheduler( void ) { freeTaskManager(); + if (n_capabilities != 1) { + stgFree(capabilities); + } #if defined(THREADED_RTS) closeMutex(&sched_mutex); #endif diff --git a/rts/posix/Signals.c b/rts/posix/Signals.c index a5044cd6de08c34af2d904128e91b65a5e983d4f..2380eacfbdd3bf29161644792155ffa45a6626ff 100644 --- a/rts/posix/Signals.c +++ b/rts/posix/Signals.c @@ -545,4 +545,11 @@ initDefaultHandlers() #endif } +void +freeSignalHandlers(void) { + if (signal_handlers != NULL) { + stgFree(signal_handlers); + } +} + #endif /* RTS_USER_SIGNALS */ diff --git a/rts/win32/ConsoleHandler.c b/rts/win32/ConsoleHandler.c index 5b5cfc338bcde8f70dc12684a5f3a092ab7178ce..a2de74b54a2f9d606cad7e01de65bf15bb8592e5 100644 --- a/rts/win32/ConsoleHandler.c +++ b/rts/win32/ConsoleHandler.c @@ -52,6 +52,11 @@ initUserSignals(void) return; } +void +freeSignalHandlers(void) { + /* Do nothing */ +} + /* Seems to be a bit of an orphan...where used? */ void finiUserSignals(void)