-- GENERATED by C->Haskell Compiler, version 0.17.2 Crystal Seed, 24 Jan 2009 (Haskell)
-- Edit the ORIGNAL .chs file instead!


{-# LINE 1 "./Foreign/CUDA/Driver/Stream.chs" #-}
{-# LANGUAGE BangPatterns             #-}
{-# LANGUAGE EmptyDataDecls           #-}
{-# LANGUAGE ForeignFunctionInterface #-}
--------------------------------------------------------------------------------
-- |
-- Module    : Foreign.CUDA.Driver.Stream
-- Copyright : (c) [2009..2012] Trevor L. McDonell
-- License   : BSD
--
-- Stream management for low-level driver interface
--
--------------------------------------------------------------------------------

module Foreign.CUDA.Driver.Stream (

  -- * Stream Management
  Stream(..), StreamFlag,
  create, destroy, finished, block

) where



{-# LINE 23 "./Foreign/CUDA/Driver/Stream.chs" #-}


-- Friends
import Foreign.CUDA.Driver.Error
import Foreign.CUDA.Internal.C2HS

-- System
import Foreign
import Foreign.C
import Control.Monad                            (liftM)


--------------------------------------------------------------------------------
-- Data Types
--------------------------------------------------------------------------------

-- |
-- A processing stream
--
newtype Stream = Stream { useStream :: ((Ptr ()))}
  deriving (Eq, Show)


-- |
-- Possible option flags for stream initialisation. Dummy instance until the API
-- exports actual option values.
--
data StreamFlag
instance Enum StreamFlag where

--------------------------------------------------------------------------------
-- Stream management
--------------------------------------------------------------------------------

-- |
-- Create a new stream
--
{-# INLINEABLE create #-}
create :: [StreamFlag] -> IO Stream
create !flags = resultIfOk =<< cuStreamCreate flags

{-# INLINE cuStreamCreate #-}
cuStreamCreate :: ([StreamFlag]) -> IO ((Status), (Stream))
cuStreamCreate a2 =
  alloca $ \a1' -> 
  let {a2' = combineBitMasks a2} in 
  cuStreamCreate'_ a1' a2' >>= \res ->
  let {res' = cToEnum res} in
  peekStream  a1'>>= \a1'' -> 
  return (res', a1'')

{-# LINE 67 "./Foreign/CUDA/Driver/Stream.chs" #-}

  where peekStream = liftM Stream . peek

-- |
-- Destroy a stream
--
{-# INLINEABLE destroy #-}
destroy :: Stream -> IO ()
destroy !st = nothingIfOk =<< cuStreamDestroy st

{-# INLINE cuStreamDestroy #-}
cuStreamDestroy :: (Stream) -> IO ((Status))
cuStreamDestroy a1 =
  let {a1' = useStream a1} in 
  cuStreamDestroy'_ a1' >>= \res ->
  let {res' = cToEnum res} in
  return (res')

{-# LINE 79 "./Foreign/CUDA/Driver/Stream.chs" #-}



-- |
-- Check if all operations in the stream have completed
--
{-# INLINEABLE finished #-}
finished :: Stream -> IO Bool
finished !st =
  cuStreamQuery st >>= \rv ->
  case rv of
    Success  -> return True
    NotReady -> return False
    _        -> resultIfOk (rv,undefined)

{-# INLINE cuStreamQuery #-}
cuStreamQuery :: (Stream) -> IO ((Status))
cuStreamQuery a1 =
  let {a1' = useStream a1} in 
  cuStreamQuery'_ a1' >>= \res ->
  let {res' = cToEnum res} in
  return (res')

{-# LINE 96 "./Foreign/CUDA/Driver/Stream.chs" #-}



-- |
-- Wait until the device has completed all operations in the Stream
--
{-# INLINEABLE block #-}
block :: Stream -> IO ()
block !st = nothingIfOk =<< cuStreamSynchronize st

{-# INLINE cuStreamSynchronize #-}
cuStreamSynchronize :: (Stream) -> IO ((Status))
cuStreamSynchronize a1 =
  let {a1' = useStream a1} in 
  cuStreamSynchronize'_ a1' >>= \res ->
  let {res' = cToEnum res} in
  return (res')

{-# LINE 108 "./Foreign/CUDA/Driver/Stream.chs" #-}



foreign import ccall unsafe "Foreign/CUDA/Driver/Stream.chs.h cuStreamCreate"
  cuStreamCreate'_ :: ((Ptr (Ptr ())) -> (CUInt -> (IO CInt)))

foreign import ccall unsafe "Foreign/CUDA/Driver/Stream.chs.h cuStreamDestroy"
  cuStreamDestroy'_ :: ((Ptr ()) -> (IO CInt))

foreign import ccall unsafe "Foreign/CUDA/Driver/Stream.chs.h cuStreamQuery"
  cuStreamQuery'_ :: ((Ptr ()) -> (IO CInt))

foreign import ccall unsafe "Foreign/CUDA/Driver/Stream.chs.h cuStreamSynchronize"
  cuStreamSynchronize'_ :: ((Ptr ()) -> (IO CInt))