#2094: add two new forms of unsafePerformIO and one of unsafeInterleaveIO
-------------------------+--------------------------------------------------
Reporter: duncan | Owner:
Type: proposal | Status: new
Priority: normal | Component: libraries/base
Version: 6.8.2 | Severity: normal
Keywords: | Testcase:
Architecture: Unknown | Os: Unknown
-------------------------+--------------------------------------------------
This proposal is to add two new variations on unsafePerformIO and one new
form of unsafeInterleaveIO to the System.IO.Unsafe module in the base
library (which already exports unsafePerformIO and unsafeInterleaveIO).
The additions are documented and portable to non-ghc.
Summary and documentation below, see attached patch for code details.
Suggested timescale: ~2 weeks, ends Friday 29th February
= Summary =
* `unsafeDupablePerformIO` and `unsafeDupableInterleaveIO`
When GHC added SMP support the previous `unsafePerform/InterleaveIO` got
renamed to these two functions and new `unsafePerform/InterleaveIO`
functions were added that provide protection against duplication in a
multi-threaded context. This protection comes at some cost so there are
cases where it is ok to uses these weaker forms if duplicating the IO
action is safe. These are already defined and documented in `GHC.IOBase`,
this patch just exports them.
* `unsafeInlinePerformIO`
This is an even less safe form of `unsafePerformIO`. It is used in the
`Data.ByteString` implementation and is very occasionally needed in other
projects. If it is needed it is better that it be supplied in a portable
form from a standard module with a sensible name and with full
documentation.
= Haddock Documentation =
This version of 'unsafePerformIO' is slightly more efficient,
because it omits the check that the IO is only being
performed by a single thread. Hence, when you write
'unsafeDupablePerformIO', there is a possibility that the IO
action may be performed multiple times (on a multiprocessor),
and you should therefore ensure that it gives the same results
each time.
{{{unsafeDupablePerformIO :: IO a -> a}}}
TODO: Actually, unsafeDupableInterleaveIO is not yet documented, that
will have to be fixed.
{{{unsafeDupableInterleaveIO :: IO a -> IO a}}}
This variant of 'unsafePerformIO' is quite /mind-bogglingly
unsafe/. It unstitches the dependency chain that holds the IO
monad together and breaks all your ordinary intuitions about
IO, sequencing and side effects. Avoid it unless you really
know what you are doing.
It is only safe for operations which are genuinely pure (not
just externally pure) for example reading from an immutable
foreign data structure. In particular, you should do no memory
allocation inside an 'unsafeInlinePerformIO' block. This is
because an allocation is a constant and is likely to be
floated out and shared. More generally, any part of any
IO action that does not depend on a function argument is
likely to be floated to the top level and have its result
shared.
It is more efficient because in addition to the checks that
'unsafeDupablePerformIO' omits, we also inline. Additionally
we do not pretend that the body is lazy which allows the
strictness analyser to see the strictness in the body. In turn
this allows some re-ordering of operations and any
corresponding side-effects.
With GHC it compiles to essentially no code and it exposes the
body to further inlining.
{{{unsafeInlinePerformIO :: IO a -> a}}}
--
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/2094>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
_______________________________________________
Glasgow-haskell-bugs mailing list
Glasgow-haskell-bugs@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs