Typo
[packages/base.git] / Debug / Trace.hs
index 17df6f3..eedacfa 100644 (file)
@@ -1,5 +1,5 @@
 {-# LANGUAGE Unsafe #-}
-{-# LANGUAGE CPP, ForeignFunctionInterface #-}
+{-# LANGUAGE MagicHash, UnboxedTuples #-}
 
 -----------------------------------------------------------------------------
 -- |
 module Debug.Trace (
         -- * Tracing
         -- $tracing
-        trace,            -- :: String -> a -> a
+        trace,
+        traceId,
         traceShow,
+        traceShowId,
         traceStack,
-        traceIO,          -- :: String -> IO ()
+        traceIO,
+        traceM,
+        traceShowM,
         putTraceMsg,
 
         -- * Eventlog tracing
         -- $eventlog_tracing
         traceEvent,
         traceEventIO,
+        
+        -- * Execution phase markers
+        -- $markers
+        traceMarker,
+        traceMarkerIO,
   ) where
 
 import Prelude
 import System.IO.Unsafe
 import Control.Monad
 
-#ifdef __GLASGOW_HASKELL__
 import Foreign.C.String
-import qualified GHC.Exts as GHC
+import GHC.Base
+import qualified GHC.Foreign
+import GHC.IO.Encoding
+import GHC.Ptr
 import GHC.Stack
-#else
-import System.IO (hPutStrLn,stderr)
-#endif
 
 -- $tracing
 --
@@ -59,11 +67,9 @@ import System.IO (hPutStrLn,stderr)
 -- | The 'traceIO' function outputs the trace message from the IO monad.
 -- This sequences the output with respect to other IO actions.
 --
+-- /Since: 4.5.0.0/
 traceIO :: String -> IO ()
 traceIO msg = do
-#ifndef __GLASGOW_HASKELL__
-    hPutStrLn stderr msg
-#else
     withCString "%s\n" $ \cfmt ->
      withCString msg  $ \cmsg ->
       debugBelch cfmt cmsg
@@ -72,13 +78,11 @@ traceIO msg = do
 -- using the FFI.
 foreign import ccall unsafe "HsBase.h debugBelch2"
    debugBelch :: CString -> CString -> IO ()
-#endif
 
-
--- | Deprecated. Use 'traceIO'.
+-- |
 putTraceMsg :: String -> IO ()
 putTraceMsg = traceIO
-{-# DEPRECATED putTraceMsg "Use Debug.Trace.traceIO" #-}
+{-# DEPRECATED putTraceMsg "Use 'Debug.Trace.traceIO'" #-} -- deprecated in 7.4
 
 
 {-# NOINLINE trace #-}
@@ -101,6 +105,14 @@ trace string expr = unsafePerformIO $ do
     return expr
 
 {-|
+Like 'trace' but returns the message instead of a third value.
+
+/Since: 4.7.0.0/
+-}
+traceId :: String -> String
+traceId a = trace a a
+
+{-|
 Like 'trace', but uses 'show' on the argument to convert it to a 'String'.
 
 This makes it convenient for printing the values of interesting variables or
@@ -116,6 +128,61 @@ variables @x@ and @z@:
 traceShow :: (Show a) => a -> b -> b
 traceShow = trace . show
 
+{-|
+Like 'traceShow' but returns the shown value instead of a third value.
+
+/Since: 4.7.0.0/
+-}
+traceShowId :: (Show a) => a -> a
+traceShowId a = trace (show a) a
+
+{-|
+Like 'trace' but returning unit in an arbitrary monad. Allows for convenient
+use in do-notation. Note that the application of 'trace' is not an action in the
+monad, as 'traceIO' is in the 'IO' monad.
+
+> ... = do
+>   x <- ...
+>   traceM $ "x: " ++ show x
+>   y <- ...
+>   traceM $ "y: " ++ show y
+
+/Since: 4.7.0.0/
+-}
+traceM :: (Monad m) => String -> m ()
+traceM string = trace string $ return ()
+
+{-|
+Like 'traceM', but uses 'show' on the argument to convert it to a 'String'.
+
+> ... = do
+>   x <- ...
+>   traceMShow $ x
+>   y <- ...
+>   traceMShow $ x + y
+
+/Since: 4.7.0.0/
+-}
+traceShowM :: (Show a, Monad m) => a -> m ()
+traceShowM = traceM . show
+
+-- | like 'trace', but additionally prints a call stack if one is
+-- available.
+--
+-- In the current GHC implementation, the call stack is only
+-- availble if the program was compiled with @-prof@; otherwise
+-- 'traceStack' behaves exactly like 'trace'.  Entries in the call
+-- stack correspond to @SCC@ annotations, so it is a good idea to use
+-- @-fprof-auto@ or @-fprof-auto-calls@ to add SCC annotations automatically.
+--
+-- /Since: 4.5.0.0/
+traceStack :: String -> a -> a
+traceStack str expr = unsafePerformIO $ do
+   traceIO str
+   stack <- currentCallStack
+   when (not (null stack)) $ traceIO (renderStack stack)
+   return expr
+
 
 -- $eventlog_tracing
 --
@@ -141,6 +208,7 @@ traceShow = trace . show
 -- duplicate events emitted if two CPUs simultaneously evaluate the same thunk
 -- that uses 'traceEvent'.
 --
+-- /Since: 4.5.0.0/
 traceEvent :: String -> a -> a
 traceEvent msg expr = unsafeDupablePerformIO $ do
     traceEventIO msg
@@ -152,25 +220,58 @@ traceEvent msg expr = unsafeDupablePerformIO $ do
 -- Compared to 'traceEvent', 'traceEventIO' sequences the event with respect to
 -- other IO actions.
 --
+-- /Since: 4.5.0.0/
 traceEventIO :: String -> IO ()
-#ifdef __GLASGOW_HASKELL__
-traceEventIO = GHC.traceEventIO
-#else
-traceEventIO msg = (return $! length msg) >> return ()
-#endif
+traceEventIO msg =
+  GHC.Foreign.withCString utf8 msg $ \(Ptr p) -> IO $ \s ->
+    case traceEvent# p s of s' -> (# s', () #)
 
--- | like 'trace', but additionally prints a call stack if one is
--- available.
+-- $markers
 --
--- In the current GHC implementation, the call stack is only
--- availble if the program was compiled with @-prof@; otherwise
--- 'traceStack' behaves exactly like 'trace'.  Entries in the call
--- stack correspond to @SCC@ annotations, so it is a good idea to use
--- @-fprof-auto@ or @-fprof-auto-calls@ to add SCC annotations automatically.
+-- When looking at a profile for the execution of a program we often want to
+-- be able to mark certain points or phases in the execution and see that
+-- visually in the profile.
+
+-- For example, a program might have several distinct phases with different
+-- performance or resource behaviour in each phase. To properly interpret the
+-- profile graph we really want to see when each phase starts and ends.
 --
-traceStack :: String -> a -> a
-traceStack str expr = unsafePerformIO $ do
-   traceIO str
-   stack <- currentCallStack
-   when (not (null stack)) $ traceIO (renderStack stack)
-   return expr
+-- Markers let us do this: we can annotate the program to emit a marker at
+-- an appropriate point during execution and then see that in a profile.
+-- 
+-- Currently this feature is only supported in GHC by the eventlog tracing
+-- system, but in future it may also be supported by the heap profiling or
+-- other profiling tools. These function exists for other Haskell
+-- implementations but they have no effect. Note that the string message is
+-- always evaluated, whether or not profiling is available or enabled.
+
+{-# NOINLINE traceMarker #-}
+-- | The 'traceMarker' function emits a marker to the eventlog, if eventlog
+-- profiling is available and enabled at runtime. The @String@ is the name of
+-- the marker. The name is just used in the profiling tools to help you keep
+-- clear which marker is which.
+--
+-- This function is suitable for use in pure code. In an IO context use
+-- 'traceMarkerIO' instead.
+--
+-- Note that when using GHC's SMP runtime, it is possible (but rare) to get
+-- duplicate events emitted if two CPUs simultaneously evaluate the same thunk
+-- that uses 'traceMarker'.
+--
+-- /Since: 4.7.0.0/
+traceMarker :: String -> a -> a
+traceMarker msg expr = unsafeDupablePerformIO $ do
+    traceMarkerIO msg
+    return expr
+
+-- | The 'traceMarkerIO' function emits a marker to the eventlog, if eventlog
+-- profiling is available and enabled at runtime.
+--
+-- Compared to 'traceMarker', 'traceMarkerIO' sequences the event with respect to
+-- other IO actions.
+--
+-- /Since: 4.7.0.0/
+traceMarkerIO :: String -> IO ()
+traceMarkerIO msg =
+  GHC.Foreign.withCString utf8 msg $ \(Ptr p) -> IO $ \s ->
+    case traceMarker# p s of s' -> (# s', () #)