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 | |
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')
-rw-r--r-- | rts/RtsStartup.c | 3 | ||||
-rw-r--r-- | rts/Schedule.c | 6 | ||||
-rw-r--r-- | rts/Schedule.h | 1 | ||||
-rw-r--r-- | rts/Task.c | 20 | ||||
-rw-r--r-- | rts/Task.h | 1 |
5 files changed, 28 insertions, 3 deletions
diff --git a/rts/RtsStartup.c b/rts/RtsStartup.c index 5bb980674d..937334bdab 100644 --- a/rts/RtsStartup.c +++ b/rts/RtsStartup.c @@ -438,6 +438,9 @@ hs_exit(void) // also outputs the stats (+RTS -s) info. exitStorage(); + /* free the tasks */ + freeScheduler(); + /* free shared Typeable store */ exitTypeableStore(); diff --git a/rts/Schedule.c b/rts/Schedule.c index cf62c5ae7a..77dcf411c7 100644 --- a/rts/Schedule.c +++ b/rts/Schedule.c @@ -2582,6 +2582,12 @@ exitScheduler( void ) #endif } +void +freeScheduler( void ) +{ + freeTaskManager(); +} + /* --------------------------------------------------------------------------- Where are the roots that we know about? diff --git a/rts/Schedule.h b/rts/Schedule.h index 2afedeec86..ba5efc29ad 100644 --- a/rts/Schedule.h +++ b/rts/Schedule.h @@ -19,6 +19,7 @@ */ void initScheduler (void); void exitScheduler (void); +void freeScheduler (void); // Place a new thread on the run queue of the current Capability void scheduleThread (Capability *cap, StgTSO *tso); 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; diff --git a/rts/Task.h b/rts/Task.h index cc450a74a1..3b7a08ee96 100644 --- a/rts/Task.h +++ b/rts/Task.h @@ -170,6 +170,7 @@ extern Task *all_tasks; // void initTaskManager (void); void stopTaskManager (void); +void freeTaskManager (void); // Create a new Task for a bound thread // Requires: sched_mutex. |