Commit 9f2ceb4d authored by Simon Marlow's avatar Simon Marlow

Remember to free() memory on exit

Patch mostly from Lennart Augustsson in #803, with additions to
Task.c by me.
parent 3098d214
...@@ -55,6 +55,7 @@ extern StgPtr deRefStablePtr(StgStablePtr sp); ...@@ -55,6 +55,7 @@ extern StgPtr deRefStablePtr(StgStablePtr sp);
#endif #endif
extern void initStablePtrTable ( void ); extern void initStablePtrTable ( void );
extern void exitStablePtrTable ( void );
extern void enlargeStablePtrTable ( void ); extern void enlargeStablePtrTable ( void );
extern StgWord lookupStableName ( StgPtr p ); extern StgWord lookupStableName ( StgPtr p );
...@@ -63,4 +64,6 @@ extern void threadStablePtrTable ( evac_fn evac ); ...@@ -63,4 +64,6 @@ extern void threadStablePtrTable ( evac_fn evac );
extern void gcStablePtrTable ( void ); extern void gcStablePtrTable ( void );
extern void updateStablePtrTable ( rtsBool full ); extern void updateStablePtrTable ( rtsBool full );
extern void exitHashTable ( void );
#endif #endif
...@@ -212,15 +212,25 @@ lookupHashTable(HashTable *table, StgWord key) ...@@ -212,15 +212,25 @@ lookupHashTable(HashTable *table, StgWord key)
static HashList *freeList = NULL; static HashList *freeList = NULL;
static struct chunkList {
void *chunk;
struct chunkList *next;
} *chunks;
static HashList * static HashList *
allocHashList(void) allocHashList(void)
{ {
HashList *hl, *p; HashList *hl, *p;
struct chunkList *cl;
if ((hl = freeList) != NULL) { if ((hl = freeList) != NULL) {
freeList = hl->next; freeList = hl->next;
} else { } else {
hl = stgMallocBytes(HCHUNK * sizeof(HashList), "allocHashList"); hl = stgMallocBytes(HCHUNK * sizeof(HashList), "allocHashList");
cl = stgMallocBytes(sizeof (*cl), "allocHashList: chunkList");
cl->chunk = hl;
cl->next = chunks;
chunks = cl;
freeList = hl + 1; freeList = hl + 1;
for (p = freeList; p < hl + HCHUNK - 1; p++) for (p = freeList; p < hl + HCHUNK - 1; p++)
...@@ -374,3 +384,15 @@ allocStrHashTable(void) ...@@ -374,3 +384,15 @@ allocStrHashTable(void)
return allocHashTable_((HashFunction *)hashStr, return allocHashTable_((HashFunction *)hashStr,
(CompareFunction *)compareStr); (CompareFunction *)compareStr);
} }
void
exitHashTable(void)
{
struct chunkList *cl;
while ((cl = chunks) != NULL) {
chunks = cl->next;
stgFree(cl->chunk);
stgFree(cl);
}
}
...@@ -390,6 +390,12 @@ hs_exit(void) ...@@ -390,6 +390,12 @@ hs_exit(void)
// also outputs the stats (+RTS -s) info. // also outputs the stats (+RTS -s) info.
exitStorage(); exitStorage();
/* initialise the stable pointer table */
exitStablePtrTable();
/* free hash table storage */
exitHashTable();
#ifdef RTS_GTK_FRONTPANEL #ifdef RTS_GTK_FRONTPANEL
if (RtsFlags.GcFlags.frontpanel) { if (RtsFlags.GcFlags.frontpanel) {
stopFrontPanel(); stopFrontPanel();
......
...@@ -159,6 +159,18 @@ initStablePtrTable(void) ...@@ -159,6 +159,18 @@ initStablePtrTable(void)
#endif #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. * get at the real stuff...remove indirections.
* *
......
...@@ -537,6 +537,9 @@ stat_exit(int alloc) ...@@ -537,6 +537,9 @@ stat_exit(int alloc)
statsFlush(); statsFlush();
statsClose(); statsClose();
} }
if (GC_coll_times)
stgFree(GC_coll_times);
GC_coll_times = NULL;
} }
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
......
...@@ -273,6 +273,11 @@ exitStorage (void) ...@@ -273,6 +273,11 @@ exitStorage (void)
void void
freeStorage (void) freeStorage (void)
{ {
nat g;
for(g = 0; g < RtsFlags.GcFlags.generations; g++)
stgFree(generations[g].steps);
stgFree(generations);
freeAllMBlocks(); freeAllMBlocks();
} }
......
...@@ -74,9 +74,19 @@ initTaskManager (void) ...@@ -74,9 +74,19 @@ initTaskManager (void)
void void
stopTaskManager (void) stopTaskManager (void)
{ {
Task *task, *next;
debugTrace(DEBUG_sched, debugTrace(DEBUG_sched,
"stopping task manager, %d tasks still running", "stopping task manager, %d tasks still running",
tasksRunning); 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);
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment