Terminate unused worker threads

Edward Z. Yang ezyang at MIT.EDU
Sun Nov 7 09:29:41 EST 2010

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.

    - 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.


More information about the Glasgow-haskell-users mailing list