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