From cf6b495d8f6d8f08fd6603c5ba2ec7a6acf7ac01 Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Mon, 11 Dec 2006 13:10:04 +0000 Subject: [PATCH] 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. --- rts/RtsStartup.c | 3 +++ rts/Schedule.c | 6 ++++++ rts/Schedule.h | 1 + rts/Task.c | 20 +++++++++++++++++--- rts/Task.h | 1 + 5 files changed, 28 insertions(+), 3 deletions(-) diff --git a/rts/RtsStartup.c b/rts/RtsStartup.c index 5bb9806..937334b 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 cf62c5a..77dcf41 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 2afedee..ba5efc2 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 588d414..0e51dbf 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 cc450a7..3b7a08e 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. -- 1.7.10.4