Terminate unused worker threads

Simon Marlow marlowsd at gmail.com
Wed Nov 17 06:15:46 EST 2010


Hi Edward,

Sorry for taking so long to get around to reviewing this one.

On 07/11/2010 14:29, Edward Z. Yang wrote:
> I finally got some spare time to do some GHC hacking, and after feeling my
> way around http://hackage.haskell.org/trac/ghc/ticket/4262 I came up with the
> following patch, which appears to work (that is, bound the number of worker
> threads hanging around after FFI calls):
>
> diff -rN -u old-ghc-clean/rts/Capability.c new-ghc-clean/rts/Capability.c
> --- old-ghc-clean/rts/Capability.c      2010-11-07 14:21:53.000000000 +0000
> +++ new-ghc-clean/rts/Capability.c      2010-11-07 14:21:54.000000000 +0000
> @@ -461,6 +461,16 @@
>       // This happens when the system is shutting down (see
>       // Schedule.c:workerStart()).
>       if (!isBoundTask(task)&&  !task->stopped) {
> +       int i;
> +       Task *t = cap->spare_workers;
> +       // arbitrarily picked six spare workers as a good number
> +       for (i = 1; t != NULL&&  i<  6; t = t->next, i++) {}
> +       if (i>= 6) {
> +               debugTrace(DEBUG_sched, "Lots of spare workers hanging around, terminating this thread");
> +               releaseCapability_(cap,rtsFalse);
> +               RELEASE_LOCK(&cap->lock);
> +               pthread_exit(NULL);
> +       }
>      task->next = cap->spare_workers;
>      cap->spare_workers = task;
>       }
>
> There are a few obvious questions with this patch:
>
>      - We're doing a walk (albeit constant bounded) of the spare workers list;
>        if we're actually not going to ever exceed X number maybe we should use
>        a circular buffer or store the number of items in the queue.

I suggest keeping track of the number of items in the queue.

>      - It's not 100% clear to me if I've done enough cleanup (i.e. maybe other locks
>        to release, items to free, etc?)

>      - Of course, POSIX only, for now.  Fortunately Windows is nice enough to give us
>        ExitThread() so porting should be not a problem.

So a worker thread is normally expected to exit by

  - returning from schedule() (Schedule.c line 291)
  - back to scheduleWorker(), which calls releaseCapability_() and
    workerTaskStop()

So I think the main thing missing is a call to workerTaskStop().

It would be really nice if we could arrange that in the case where we 
have too many spare workers, the extra workers exit via the same route, 
but I suspect that might not be easy.

Cheers,
	Simon


More information about the Glasgow-haskell-users mailing list