ghc-trace-events-0.1.2.1: src/Debug/Trace/ByteString.hs
{-# LANGUAGE CPP #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedTuples #-}
{-|
'B.ByteString' variant of the tracing functions in "Debug.Trace".
-}
module Debug.Trace.ByteString
( -- * Eventlog tracing
-- $eventlog_tracing
traceEvent
, traceEventIO
, unsafeTraceEvent
, unsafeTraceEventIO
-- * Execution phase markers
-- $markers
, traceMarker
, traceMarkerIO
, unsafeTraceMarker
, unsafeTraceMarkerIO
) where
import Control.Monad (when)
import GHC.Exts (Ptr(..), traceEvent#, traceMarker#)
import GHC.IO (IO(..))
import qualified System.IO.Unsafe as Unsafe
import qualified Data.ByteString as B
import qualified Data.ByteString.Unsafe as BU
import Debug.Trace.Flags (userTracingEnabled)
-- $eventlog_tracing
--
-- Eventlog tracing is a performance profiling system. These functions emit
-- extra events into the eventlog. In combination with eventlog profiling
-- tools these functions can be used for monitoring execution and
-- investigating performance problems.
-- | 'B.ByteString' variant of 'Debug.Trace.traceEvent'.
--
-- \(O(n)\) This function copies the 'B.ByteString' to convert it to a
-- null-terminated 'Foreign.C.Types.CString'.
--
-- Note that this function doesn't evaluate the 'B.ByteString' if user tracing
-- in eventlog is disabled.
--
-- The input should be shorter than \(2^{16}\) bytes. Otherwise the RTS
-- generates a broken eventlog.
traceEvent :: B.ByteString -> a -> a
traceEvent message a
| userTracingEnabled = traceEvent' message a
| otherwise = a
traceEvent' :: B.ByteString -> a -> a
traceEvent' message a = Unsafe.unsafeDupablePerformIO $ do
traceEventIO' message
return a
{-# NOINLINE traceEvent' #-}
-- | 'B.ByteString' variant of 'Debug.Trace.traceEventIO'.
--
-- \(O(n)\) This function copies the 'B.ByteString' to convert it to a
-- null-terminated 'Foreign.C.Types.CString'.
--
-- Note that this function doesn't evaluate the 'B.ByteString' if user tracing
-- in eventlog is disabled.
--
-- The input should be shorter than \(2^{16}\) bytes. Otherwise the RTS
-- generates a broken eventlog.
traceEventIO :: B.ByteString -> IO ()
traceEventIO message = when userTracingEnabled $ traceEventIO' message
traceEventIO' :: B.ByteString -> IO ()
traceEventIO' message = B.useAsCString message $ \(Ptr p) -> IO $ \s ->
case traceEvent# p s of
s' -> (# s', () #)
-- | 'B.ByteString' variant of 'Debug.Trace.traceEvent'.
--
-- \(O(1)\) This function is unsafe in the way that it doesn't ensure the input
-- string to be null-terminated. It is user's responsibility to null-terminate
-- the input.
--
-- Note that this function doesn't evaluate the 'B.ByteString' if user tracing
-- in eventlog is disabled.
--
-- The input should be shorter than \(2^{16}\) bytes. Otherwise the RTS
-- generates a broken eventlog.
unsafeTraceEvent :: B.ByteString -> a -> a
unsafeTraceEvent message a
| userTracingEnabled = unsafeTraceEvent' message a
| otherwise = a
unsafeTraceEvent' :: B.ByteString -> a -> a
unsafeTraceEvent' message a = Unsafe.unsafeDupablePerformIO $ do
unsafeTraceEventIO' message
return a
{-# NOINLINE unsafeTraceEvent' #-}
-- | 'B.ByteString' variant of 'Debug.Trace.traceEventIO'.
--
-- \(O(1)\) This function is unsafe in the way that it doesn't ensure the input
-- string to be null-terminated. It is user's responsibility to null-terminate
-- the input.
--
-- Note that this function doesn't evaluate the 'B.ByteString' if user tracing
-- in eventlog is disabled.
--
-- The input should be shorter than \(2^{16}\) bytes. Otherwise the RTS
-- generates a broken eventlog.
unsafeTraceEventIO :: B.ByteString -> IO ()
unsafeTraceEventIO message =
when userTracingEnabled $ unsafeTraceEventIO' message
unsafeTraceEventIO' :: B.ByteString -> IO ()
unsafeTraceEventIO' message =
BU.unsafeUseAsCString message $ \(Ptr p) -> IO $ \s ->
case traceEvent# p s of
s' -> (# s', () #)
-- $markers
--
-- 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.
--
-- 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.
-- | 'B.ByteString' variant of 'Debug.Trace.traceMarker'.
--
-- \(O(n)\) This function copies the 'B.ByteString' to convert it to a
-- null-terminated 'Foreign.C.Types.CString'.
--
-- Note that this function doesn't evaluate the 'B.ByteString' if user tracing
-- in eventlog is disabled.
--
-- The input should be shorter than \(2^{16}\) bytes. Otherwise the RTS
-- generates a broken eventlog.
traceMarker :: B.ByteString -> a -> a
traceMarker message a
| userTracingEnabled = traceMarker' message a
| otherwise = a
traceMarker' :: B.ByteString -> a -> a
traceMarker' message a = Unsafe.unsafeDupablePerformIO $ do
traceMarkerIO' message
return a
{-# NOINLINE traceMarker' #-}
-- | 'B.ByteString' variant of 'Debug.Trace.traceMarkerIO'.
--
-- \(O(n)\) This function copies the 'B.ByteString' to convert it to a
-- null-terminated 'Foreign.C.Types.CString'.
--
-- Note that this function doesn't evaluate the 'B.ByteString' if user tracing
-- in eventlog is disabled.
--
-- The input should be shorter than \(2^{16}\) bytes. Otherwise the RTS
-- generates a broken eventlog.
traceMarkerIO :: B.ByteString -> IO ()
traceMarkerIO message = when userTracingEnabled $ traceMarkerIO' message
traceMarkerIO' :: B.ByteString -> IO ()
traceMarkerIO' message = B.useAsCString message $ \(Ptr p) -> IO $ \s ->
case traceMarker# p s of
s' -> (# s', () #)
-- | 'B.ByteString' variant of 'Debug.Trace.traceMarker'.
--
-- \(O(1)\) This function is unsafe in the way that it doesn't ensure the input
-- string to be null-terminated. It is user's responsibility to null-terminate
-- the input.
--
-- Note that this function doesn't evaluate the 'B.ByteString' if user tracing
-- in eventlog is disabled.
--
-- The input should be shorter than \(2^{16}\) bytes. Otherwise the RTS
-- generates a broken eventlog.
unsafeTraceMarker :: B.ByteString -> a -> a
unsafeTraceMarker message a
| userTracingEnabled = unsafeTraceMarker' message a
| otherwise = a
unsafeTraceMarker' :: B.ByteString -> a -> a
unsafeTraceMarker' message a = Unsafe.unsafeDupablePerformIO $ do
unsafeTraceMarkerIO' message
return a
{-# NOINLINE unsafeTraceMarker' #-}
-- | 'B.ByteString' variant of 'Debug.Trace.traceMarkerIO'.
--
-- \(O(1)\) This function is unsafe in the way that it doesn't ensure the input
-- string to be null-terminated. It is user's responsibility to null-terminate
-- the input.
--
-- Note that this function doesn't evaluate the 'B.ByteString' if user tracing
-- in eventlog is disabled.
--
-- The input should be shorter than \(2^{16}\) bytes. Otherwise the RTS
-- generates a broken eventlog.
unsafeTraceMarkerIO :: B.ByteString -> IO ()
unsafeTraceMarkerIO message =
when userTracingEnabled $ unsafeTraceMarkerIO' message
unsafeTraceMarkerIO' :: B.ByteString -> IO ()
unsafeTraceMarkerIO' message =
BU.unsafeUseAsCString message $ \(Ptr p) -> IO $ \s ->
case traceMarker# p s of
s' -> (# s', () #)