[project @ 2004-04-20 15:49:58 by simonmar]
authorsimonmar <unknown>
Tue, 20 Apr 2004 15:49:58 +0000 (15:49 +0000)
committersimonmar <unknown>
Tue, 20 Apr 2004 15:49:58 +0000 (15:49 +0000)
- comments on INLINability of unsafePerformIO

- change unsafeInterleaveIO from NOINLINE to INLINE(!)  we believe
  this is safe.  Interestingly, there's now a good reason to use
  unsafeInterleaveIO.

GHC/IOBase.lhs

index 5aec209..6fa596a 100644 (file)
@@ -181,13 +181,19 @@ help of 'unsafePerformIO'.  So be careful!
 unsafePerformIO        :: IO a -> a
 unsafePerformIO (IO m) = case m realWorld# of (# _, r #)   -> r
 
+-- Why do we NOINLINE unsafePerformIO?  See the comment with
+-- GHC.ST.runST.  Essentially the issue is that the IO computation
+-- inside unsafePerformIO must be atomic: it must either all run, or
+-- not at all.  If we let the compiler see the application of the IO
+-- to realWorld#, it might float out part of the IO.
+
 {-|
 'unsafeInterleaveIO' allows 'IO' computation to be deferred lazily.
 When passed a value of type @IO a@, the 'IO' will only be performed
 when the value of the @a@ is demanded.  This is used to implement lazy
 file reading, see 'System.IO.hGetContents'.
 -}
-{-# NOINLINE unsafeInterleaveIO #-}
+{-# INLINE unsafeInterleaveIO #-}
 unsafeInterleaveIO :: IO a -> IO a
 unsafeInterleaveIO (IO m)
   = IO ( \ s -> let
@@ -195,6 +201,10 @@ unsafeInterleaveIO (IO m)
                in
                (# s, r #))
 
+-- We believe that INLINE on unsafeInterleaveIO is safe, because the
+-- state from this IO thread is passed explicitly to the interleaved
+-- IO, so it cannot be floated out and shared.
+
 -- ---------------------------------------------------------------------------
 -- Handle type