#4391: forkIO threads do not properly save/restore the floating point
environment
---------------------------------+------------------------------------------
Reporter: draconx | Owner:
Type: bug | Status: merge
Priority: normal | Milestone: 7.2.1
Component: Runtime System | Version: 6.12.3
Keywords: | Testcase:
Blockedby: | Difficulty:
Os: Unknown/Multiple | Blocking:
Architecture: x86_64 (amd64) | Failure: None/Unknown
---------------------------------+------------------------------------------
Comment(by simonmar):
Replying to [comment:13 draconx]:
> The fenv.h functions are standard C, not limited to POSIX systems.
True, I'll fix that.
> Also, this
> IMO needs to be in the Control.Concurrent manual, because this has
everything
> to do with threads and nothing to do with the FFI.
I don't think I agree. You have to use the FFI to access the `fenv.h`
functions, and if you do, you have problems even without threads.
> About purity: the thing is, even if we had the perfect pure API for
floating
> point, you'd _still_ be bitten by this issue! That's because the issue
is not
> about purity at all: it's about the runtime clobbering CPU registers on
context
> switches. Note that integer operations on a certain popular CPU
architecture
> are just as "impure" as floating point: there is a register which stores
flags
> such as overflow state that is modified by operations (this register
performs
> essentially identical function to the floating point control word on
that
> same popular architecture). But nobody would posit that "all bets are
off"
> because a program uses conditional branches! No amount of purity will
save
> you from silent data corruption.
Are you claiming we have a problem with the overflow flag, or other CPU
state?
I get the impression from your comments that you think GHC preempts
threads at arbitrary points, and therefore has to save the entire CPU
state, like OS threads do. We don't do that - threads are preempted at
safe points only, and we know exactly what state needs to be saved and
restored (it doesn't include the overflow flag, for instance, because we
know that a safe point never occurs between an instruction that sets the
overflow flag and one that tests it). Using safe points means that we
have much less state to save than OS threads, which is why Haskell threads
are much cheaper. There are costs of course - for example it's harder to
preempt tight loops without sacrificing performance, and GHC doesn't
currently attempt to do that.
We do handle certain global state specially. A good example is the
`errno` variable: we save the value of `errno` over a context switch. We
could do the same thing with the FPU state, but we've decided not to, for
the reasons already explained. I'm sure this isn't the perfect solution
for everyone, but I think it's the best compromise.
--
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/4391#comment:14>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs