[Haskell-cafe] forkProcess, forkIO, and multithreaded runtime

Alexander Kjeldaas alexander.kjeldaas at gmail.com
Mon Jan 21 14:57:31 CET 2013


While trying to dig around this morning I started adding clang-style thread
locking annotations to the source code.  These can be very handy and I
found at least one place where the documented locking policy doesn't seem
to match what is happening.

Here is an example with annotations, and what might or might not be a bug.
 With these annotations, clang will be able to prove whether the program
obeys the locking regime or not.

But this is of course only one part of the RTS, but the locking can be
pretty "interesting" in itself.

Does anyone else feel that this sort of annotations would help?

Alexander

diff --git a/rts/Task.c b/rts/Task.c
index e6781a1..1e499dc 100644
--- a/rts/Task.c
+++ b/rts/Task.c
@@ -25,12 +25,12 @@

 // Task lists and global counters.
 // Locks required: all_tasks_mutex.
-Task *all_tasks = NULL;
+Task *all_tasks GUARDED_BY(all_tasks_mutex) = NULL;

-nat taskCount;
-nat workerCount;
-nat currentWorkerCount;
-nat peakWorkerCount;
+nat taskCount GUARDED_BY(all_tasks_mutex);
+nat workerCount GUARDED_BY(all_tasks_mutex);
+nat currentWorkerCount GUARDED_BY(all_tasks_mutex);
+nat peakWorkerCount GUARDED_BY(all_tasks_mutex);

 static int tasksInitialized = 0;

@@ -339,9 +339,11 @@ void updateCapabilityRefs (void)
     ACQUIRE_LOCK(&all_tasks_mutex);

     for (task = all_tasks; task != NULL; task=task->all_next) {
+        ACQUIRE_LOCK(task->lock);
         if (task->cap != NULL) {
             task->cap = &capabilities[task->cap->no];
         }
+        RELEASE_LOCK(task->lock);

         for (incall = task->incall; incall != NULL; incall =
incall->prev_stack) {
             if (incall->suspended_cap != NULL) {



On Mon, Jan 21, 2013 at 2:14 PM, Chris Dornan <chris at chrisdornan.com> wrote:

> I am also sorry to be late on this but I have run into the same problem
> trying to demonise a programme on 7.4.2. My solution was to get a shell
> wrapper to run the daemon in debug mode (I.e., sans fork) and get the shell
> script to do the demonising.
>
> Other than this I have found the threaded RTS to be sound and I am quite
> reliant on it. So, where things that run —threaded are concerned, no
> forkProcess calls for me until I can better understand this better.
>
> If anybody does think they understand what is going on here it would be
> great if they could write it up. IMHO, either the current notes on
> forkProcess don't go far enough, or there is a bug needing a workaround
> until the platform gets fixed.
>
> Chris
>
> From: Mark Lentczner <mark.lentczner at gmail.com>
> Date: Sunday, 20 January 2013 23:15
> To: haskell <haskell-cafe at haskell.org>
> Cc: Mike Meyer <mwm at mired.org>
> Subject: Re: [Haskell-cafe] forkProcess, forkIO, and multithreaded runtime
>
> Sorry to be reviving this thread so long after.... but I seem to be
> running into similar issues as Michael S. did at the start.
>
> In short, I'm using forkProcess with the threaded RTS, and see occasional
> hangs:
>
>    - I see these only on Linux. On Mac OS X, I never do.
>    - I'm using GHC 7.4.2
>    - I noticed the warning in the doc for forkProcess, but assumed I was
>    safe, as I wasn't holding any shared resources at the time of the fork, and
>    no shared resources in the program are used in the child.
>    - WIth gdb, I've traced the hang to here in the run-time: forkProcess
>    > discardTasksExcept > freeTask > closeMutex(&task->lock)
>    > pthread_mutex_destroy
>
> The discussion in this thread leaves me with these questions:
>
>    - Is there reason to think the situation has gotten better in 7.6 and
>    later?
>    - Isn't the only reason *System.Process* is safer because it does an
>    immediate exec in the child? Alas, I really want to just fork()sometimes.
>    - Is it really true that even if my program has no shared resources
>    with the child, that the IO subsystem and FFI system do anyway? Surely the
>    RTS would take care of doing the right thing with those, no?
>    - There should be no concern with exec w.r.t. library invariants since
>    exec is wholesale replacement - all the libraries will reinitialize.
>    Is there a problem here I'm missing?
>
> Alas, I've stopped using the threaded RTS until I understand this better.
>
> - Mark
> _______________________________________________ Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20130121/f84f91fa/attachment.htm>


More information about the Haskell-Cafe mailing list