summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Marlow <simonmar@microsoft.com>2006-08-08 10:31:10 +0000
committerSimon Marlow <simonmar@microsoft.com>2006-08-08 10:31:10 +0000
commit9f2ceb4da7dfbc1cfd09ce54610ebe64288b9007 (patch)
treec8a72bc8d7e4663c9b5f789d54a6a69bfbba4340
parent3098d2143a5865f8f1fba1d7d72132b140f2de94 (diff)
downloadhaskell-9f2ceb4da7dfbc1cfd09ce54610ebe64288b9007.tar.gz
Remember to free() memory on exit
Patch mostly from Lennart Augustsson in #803, with additions to Task.c by me.
-rw-r--r--includes/Stable.h3
-rw-r--r--rts/Hash.c22
-rw-r--r--rts/RtsStartup.c6
-rw-r--r--rts/Stable.c12
-rw-r--r--rts/Stats.c3
-rw-r--r--rts/Storage.c5
-rw-r--r--rts/Task.c10
7 files changed, 61 insertions, 0 deletions
diff --git a/includes/Stable.h b/includes/Stable.h
index ca2e72118a..3eabb30ffe 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 ada11a6a85..1d80640c4a 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 0406ae6f09..33c742b25a 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 2391cb127f..5a1b92b321 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 ec8d5838fb..248b0af58a 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 46db1eefc9..d3b059768b 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 c8cd9c4a2c..ef20c09a6e 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);
}