Bas van Dijk | 3 May 17:10 2012
Picon

Weird behavior of the NonTermination exception

Hello,

Before I turn the following into a ticket I want to ask if I miss
something obvious:

When I run the following program:

-------------------------------------------------
import Prelude hiding (catch)
import Control.Exception
import Control.Concurrent

main :: IO ()
main = do
  mv <- newEmptyMVar
  _ <- forkIO $ do
         catch action
               (\e -> putStrLn $ "I solved the Halting Problem: " ++
                                 show (e :: SomeException))
         putStrLn "putting MVar..."
         putMVar mv ()
         putStrLn "putted MVar"
  takeMVar mv

action :: IO ()
action = let x = x in x
-------------------------------------------------

I get the output:

(Continue reading)

Edward Z. Yang | 3 May 17:31 2012
Picon

Re: Weird behavior of the NonTermination exception

Excerpts from Bas van Dijk's message of Thu May 03 11:10:38 -0400 2012:
> As can be seen, the putMVar is executed successfully. So why do I get
> the message: "thread blocked indefinitely in an MVar operation"?

GHC will send BlockedIndefinitelyOnMVar to all threads involved
in the deadlock, so it's not unusual that this can interact with
error handlers to cause the system to become undeadlocked.

    http://blog.ezyang.com/2011/07/blockedindefinitelyonmvar/

However, I must admit I am a bit confused as for the timing of
the thrown exceptions.

Edward
Bas van Dijk | 3 May 18:14 2012
Picon

Re: Weird behavior of the NonTermination exception

On 3 May 2012 17:31, Edward Z. Yang <ezyang <at> mit.edu> wrote:
> Excerpts from Bas van Dijk's message of Thu May 03 11:10:38 -0400 2012:
>> As can be seen, the putMVar is executed successfully. So why do I get
>> the message: "thread blocked indefinitely in an MVar operation"?
>
> GHC will send BlockedIndefinitelyOnMVar to all threads involved
> in the deadlock, so it's not unusual that this can interact with
> error handlers to cause the system to become undeadlocked.

But why is the BlockedIndefinitelyOnMVar thrown in the first place?
According to the its documentation and your very enlightening article
it is thrown when:

"The thread is blocked on an MVar, but there are no other references
to the MVar so it can't ever continue."

The first condition holds for the main thread since it's executing
takeMVar. But the second condition doesn't hold since the forked
thread still has a reference to the MVar.

I just tried delaying the thread before the putMVar:

-------------------------------------------------
main :: IO ()
main = do
  mv <- newEmptyMVar
  _ <- forkIO $ do
         catch action
               (\e -> putStrLn $ "I solved the Halting Problem: " ++
                                 show (e :: SomeException))
(Continue reading)

Bas van Dijk | 3 May 18:28 2012
Picon

Re: Weird behavior of the NonTermination exception

On 3 May 2012 18:14, Bas van Dijk <v.dijk.bas <at> gmail.com> wrote:
> Now it seems the thread is killed while delaying. But why is it
> killed?

Oh I realise the forked thread is killed because the main thread
terminates because it received a BlockedIndefinitelyOnMVar exception
and then all daemonic threads are killed.

Bas
Jens Petersen | 4 May 11:23 2012

Re: trouble building ghc-7.4 on Fedora 18 (devel) ARM

A late followup, just to let you know, everything is good now.

> Not sure if +d16 is actually essential on Fedora though guess it doesn't hurt.

It is... I hope llvm will make it the default for armv7 hardware fp.

So finally ghc-7.4.1 is built for Fedora ARM and working:
I also had to forward-port my pkgconfig libffi workaround for
non-native compiler archs to help the C compiler find libffi.h when
building prof libraries.

http://arm.koji.fedoraproject.org/koji/buildinfo?buildID=66294

Thanks for everyone's help and particular big kudos and karma
to those who did the heavy-lifting on the ARM port for 7.4.
Maybe someone has some proper benchmarks
but roughly going by the ghc-7.4.1 build it seems over
twice as fast as 7.0.4. :-))

Jens
Simon Marlow | 4 May 14:12 2012
Picon

Re: Weird behavior of the NonTermination exception

On 03/05/2012 17:14, Bas van Dijk wrote:
> On 3 May 2012 17:31, Edward Z. Yang<ezyang <at> mit.edu>  wrote:
>> Excerpts from Bas van Dijk's message of Thu May 03 11:10:38 -0400 2012:
>>> As can be seen, the putMVar is executed successfully. So why do I get
>>> the message: "thread blocked indefinitely in an MVar operation"?
>>
>> GHC will send BlockedIndefinitelyOnMVar to all threads involved
>> in the deadlock, so it's not unusual that this can interact with
>> error handlers to cause the system to become undeadlocked.
>
> But why is the BlockedIndefinitelyOnMVar thrown in the first place?
> According to the its documentation and your very enlightening article
> it is thrown when:
>
> "The thread is blocked on an MVar, but there are no other references
> to the MVar so it can't ever continue."
>
> The first condition holds for the main thread since it's executing
> takeMVar. But the second condition doesn't hold since the forked
> thread still has a reference to the MVar.

The forked thread is deadlocked, so the MVar is considered unreachable 
and the main thread is also unreachable.  Hence both threads get sent 
the exception.

The RTS does this analysis using the GC, tracing the reachable objects 
starting from the roots.  It then send an exception to any threads which 
were not reachable, which in this case is both the main thread and the 
child, since neither is reachable.

(Continue reading)

Bas van Dijk | 4 May 16:18 2012
Picon

Re: Weird behavior of the NonTermination exception

On 4 May 2012 14:12, Simon Marlow <marlowsd <at> gmail.com> wrote:
> The forked thread is deadlocked, so the MVar is considered unreachable and
> the main thread is also unreachable.  Hence both threads get sent the
> exception.
>
> The RTS does this analysis using the GC, tracing the reachable objects
> starting from the roots.  It then send an exception to any threads which
> were not reachable, which in this case is both the main thread and the
> child, since neither is reachable.
>
> We (the user) knows that waking up the child thread will unblock the main
> thread, but the RTS doesn't know this, and it's not clear how it could find
> out easily (i.e. without multiple scans of the heap).

Thanks Simon, I learned something new today.

Cheers,

Bas

_______________________________________________
Glasgow-haskell-users mailing list
Glasgow-haskell-users <at> haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Jurriaan Hage | 7 May 15:33 2012
Picon

Explicit calls to the garbage collector.

LS.

I have a very memory intensive application. It seems that the timing of my application 
depend very much on the precise setting of -H...M in the runtime system (-H2000M 
seems to work best, computation time becomes a third of what I get when I pass no
-H option).  I conjecture that this good behaviour is the result of gc happening at the right time.
So I wondered: if I can one when is the right time, is it possible then to trigger
GC explicitly from within the Haskell code? 

best,
Jur
Christopher Done | 7 May 16:00 2012

Re: Explicit calls to the garbage collector.

I would also be interested to know this. A web server is an example of
a Haskell program that could force garbage collection at the end of
every request reply, especially a multi-threaded server where the
memory use is localized to threads. For long-running applications, a
GC at this point would be nice.
Joachim Breitner | 7 May 16:10 2012
Picon

Re: Explicit calls to the garbage collector.

Hi,

Am Montag, den 07.05.2012, 15:33 +0200 schrieb Jurriaan Hage:
> I have a very memory intensive application. It seems that the timing of my application 
> depend very much on the precise setting of -H...M in the runtime system (-H2000M 
> seems to work best, computation time becomes a third of what I get when I pass no
> -H option).  I conjecture that this good behaviour is the result of gc happening at the right time.
> So I wondered: if I can one when is the right time, is it possible then to trigger
> GC explicitly from within the Haskell code? 

there is performGC:
http://hackage.haskell.org/packages/archive/base/latest/doc/html/System-Mem.html#v:performGC

Greetings,
Joachim

--

-- 
Joachim "nomeata" Breitner
  mail <at> joachim-breitner.de  |  nomeata <at> debian.org  |  GPG: 0x4743206C
  xmpp: nomeata <at> joachim-breitner.de | http://www.joachim-breitner.de/

_______________________________________________
Glasgow-haskell-users mailing list
Glasgow-haskell-users <at> haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

Gmane