diff options
author | Ian Lynagh <igloo@earth.li> | 2006-12-11 13:10:04 +0000 |
---|---|---|
committer | Ian Lynagh <igloo@earth.li> | 2006-12-11 13:10:04 +0000 |
commit | cf6b495d8f6d8f08fd6603c5ba2ec7a6acf7ac01 (patch) | |
tree | c580b3eac83af32a8f807914901181ed4a7dcf19 /rts/Task.c | |
parent | d526504719676871376324858fe2073aa2011424 (diff) | |
download | haskell-cf6b495d8f6d8f08fd6603c5ba2ec7a6acf7ac01.tar.gz |
Add freeScheduler/freeTaskManager and call it later than exitScheduler
We were freeing the tasks in exitScheduler (stopTaskManager) before
exitStorage (stat_exit), but the latter needs to walk down the list
printing stats. Resulted in segfaults with commands like
ghc -v0 -e main q.hs -H32m -H32m +RTS -Sstderr
(where q.hs is trivial), but very sensitive to exact commandline and
libc version or something.
Diffstat (limited to 'rts/Task.c')
-rw-r--r-- | rts/Task.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/rts/Task.c b/rts/Task.c index 588d414d87..0e51dbf124 100644 --- a/rts/Task.c +++ b/rts/Task.c @@ -68,19 +68,33 @@ initTaskManager (void) void stopTaskManager (void) { - Task *task, *next; + Task *task; debugTrace(DEBUG_sched, "stopping task manager, %d tasks still running", tasksRunning); ACQUIRE_LOCK(&sched_mutex); - for (task = task_free_list; task != NULL; task = next) { - next = task->next; + for (task = task_free_list; task != NULL; task = task->next) { #if defined(THREADED_RTS) closeCondition(&task->cond); closeMutex(&task->lock); #endif + } + RELEASE_LOCK(&sched_mutex); +} + + +void +freeTaskManager (void) +{ + Task *task, *next; + + debugTrace(DEBUG_sched, "freeing task manager"); + + ACQUIRE_LOCK(&sched_mutex); + for (task = task_free_list; task != NULL; task = next) { + next = task->next; stgFree(task); } task_free_list = NULL; |