From 9f2ceb4da7dfbc1cfd09ce54610ebe64288b9007 Mon Sep 17 00:00:00 2001 From: Simon Marlow Date: Tue, 8 Aug 2006 10:31:10 +0000 Subject: [PATCH] Remember to free() memory on exit Patch mostly from Lennart Augustsson in #803, with additions to Task.c by me. --- includes/Stable.h | 3 +++ rts/Hash.c | 22 ++++++++++++++++++++++ rts/RtsStartup.c | 6 ++++++ rts/Stable.c | 12 ++++++++++++ rts/Stats.c | 3 +++ rts/Storage.c | 5 +++++ rts/Task.c | 10 ++++++++++ 7 files changed, 61 insertions(+) diff --git a/includes/Stable.h b/includes/Stable.h index ca2e721..3eabb30 100644 --- a/includes/Stable.h +++ b/includes/Stable.h @@ -55,6 +55,7 @@ extern StgPtr deRefStablePtr(StgStablePtr sp); #endif extern void initStablePtrTable ( void ); +extern void exitStablePtrTable ( void ); extern void enlargeStablePtrTable ( void ); extern StgWord lookupStableName ( StgPtr p ); @@ -63,4 +64,6 @@ extern void threadStablePtrTable ( evac_fn evac ); extern void gcStablePtrTable ( void ); extern void updateStablePtrTable ( rtsBool full ); +extern void exitHashTable ( void ); + #endif diff --git a/rts/Hash.c b/rts/Hash.c index ada11a6..1d80640 100644 --- a/rts/Hash.c +++ b/rts/Hash.c @@ -212,15 +212,25 @@ lookupHashTable(HashTable *table, StgWord key) static HashList *freeList = NULL; +static struct chunkList { + void *chunk; + struct chunkList *next; +} *chunks; + static HashList * allocHashList(void) { HashList *hl, *p; + struct chunkList *cl; if ((hl = freeList) != NULL) { freeList = hl->next; } else { hl = stgMallocBytes(HCHUNK * sizeof(HashList), "allocHashList"); + cl = stgMallocBytes(sizeof (*cl), "allocHashList: chunkList"); + cl->chunk = hl; + cl->next = chunks; + chunks = cl; freeList = hl + 1; for (p = freeList; p < hl + HCHUNK - 1; p++) @@ -374,3 +384,15 @@ allocStrHashTable(void) return allocHashTable_((HashFunction *)hashStr, (CompareFunction *)compareStr); } + +void +exitHashTable(void) +{ + struct chunkList *cl; + + while ((cl = chunks) != NULL) { + chunks = cl->next; + stgFree(cl->chunk); + stgFree(cl); + } +} diff --git a/rts/RtsStartup.c b/rts/RtsStartup.c index 0406ae6..33c742b 100644 --- a/rts/RtsStartup.c +++ b/rts/RtsStartup.c @@ -390,6 +390,12 @@ hs_exit(void) // also outputs the stats (+RTS -s) info. exitStorage(); + /* initialise the stable pointer table */ + exitStablePtrTable(); + + /* free hash table storage */ + exitHashTable(); + #ifdef RTS_GTK_FRONTPANEL if (RtsFlags.GcFlags.frontpanel) { stopFrontPanel(); diff --git a/rts/Stable.c b/rts/Stable.c index 2391cb1..5a1b92b 100644 --- a/rts/Stable.c +++ b/rts/Stable.c @@ -159,6 +159,18 @@ initStablePtrTable(void) #endif } +void +exitStablePtrTable(void) +{ + if (addrToStableHash) + freeHashTable(addrToStableHash, NULL); + addrToStableHash = NULL; + if (stable_ptr_table) + stgFree(stable_ptr_table); + stable_ptr_table = NULL; + SPT_size = 0; +} + /* * get at the real stuff...remove indirections. * diff --git a/rts/Stats.c b/rts/Stats.c index ec8d583..248b0af 100644 --- a/rts/Stats.c +++ b/rts/Stats.c @@ -537,6 +537,9 @@ stat_exit(int alloc) statsFlush(); statsClose(); } + if (GC_coll_times) + stgFree(GC_coll_times); + GC_coll_times = NULL; } /* ----------------------------------------------------------------------------- diff --git a/rts/Storage.c b/rts/Storage.c index 46db1ee..d3b0597 100644 --- a/rts/Storage.c +++ b/rts/Storage.c @@ -273,6 +273,11 @@ exitStorage (void) void freeStorage (void) { + nat g; + + for(g = 0; g < RtsFlags.GcFlags.generations; g++) + stgFree(generations[g].steps); + stgFree(generations); freeAllMBlocks(); } diff --git a/rts/Task.c b/rts/Task.c index c8cd9c4..ef20c09 100644 --- a/rts/Task.c +++ b/rts/Task.c @@ -74,9 +74,19 @@ initTaskManager (void) void stopTaskManager (void) { + Task *task, *next; + debugTrace(DEBUG_sched, "stopping task manager, %d tasks still running", tasksRunning); + + ACQUIRE_LOCK(&sched_mutex); + for (task = task_free_list; task != NULL; next) { + next = task->next; + stgFree(task); + } + task_free_list = NULL; + RELEASE_LOCK(&sched_mutex); } -- 1.7.10.4