   CLCommandQueue -> CLKernel -> CLuint -> Ptr CSize -> Ptr CSize -> Ptr CSize -> CLuint -> Ptr CLEvent -> Ptr CLEvent -> IO CLint
 foreign import ccall "clEnqueueTask" raw_clEnqueueTask :: 
   CLCommandQueue -> CLKernel -> CLuint -> Ptr CLEvent -> Ptr CLEvent -> IO CLint
+foreign import ccall "clEnqueueMarker" raw_clEnqueueMarker :: 
+  CLCommandQueue -> Ptr CLEvent -> IO CLint 
+foreign import ccall "clEnqueueWaitForEvents" raw_clEnqueueWaitForEvents :: 
+  CLCommandQueue -> CLuint -> Ptr CLEvent -> IO CLint
+foreign import ccall "clEnqueueBarrier" raw_clEnqueueBarrier :: 
+  CLCommandQueue -> IO CLint 
 foreign import ccall "clFlush" raw_clFlush ::
   CLCommandQueue -> IO CLint
 foreign import ccall "clFinish" raw_clFinish ::

  -- * Memory Commands
  clEnqueueReadBuffer, clEnqueueWriteBuffer,
  -- * Executing Kernels
  clEnqueueNDRangeKernel, clEnqueueTask,
  -- * Flush and Finish
  clFlush, clFinish
  ) where

      infoid = getCLValue CL_QUEUE_PROPERTIES
      size = fromIntegral $ sizeOf (0::CLCommandQueueProperty_)

{-| Enable or disable the properties of a command-queue.  Returns the
command-queue properties before they were changed by
'clSetCommandQueueProperty'.  As specified for 'clCreateCommandQueue', the
'CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE' command-queue property determines
whether the commands in a command-queue are executed in-order or
out-of-order. Changing this command-queue property will cause the OpenCL
implementation to block until all previously queued commands in command_queue
have completed. This can be an expensive operation and therefore changes to the
'CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE' property should be only done when
absolutely necessary.

 It is possible that a device(s) becomes unavailable after a context and
command-queues that use this device(s) have been created and commands have been
queued to command-queues. In this case the behavior of OpenCL API calls that use
this context (and command-queues) are considered to be
implementation-defined. The user callback function, if specified when the
context is created, can be used to record appropriate information when the
device becomes unavailable.
-}
clSetCommandQueueProperty :: CLCommandQueue -> [CLCommandQueueProperty] -> Bool 
                          -> IO (Either CLError [CLCommandQueueProperty])
clSetCommandQueueProperty cq xs val = alloca $ \(dat :: Ptr CLCommandQueueProperty_) -> do
  errcode <- raw_clSetCommandQueueProperty cq props (fromBool val) dat
  if errcode == getCLValue CL_SUCCESS
    then fmap (Right . bitmaskToCommandQueueProperties) $ peek dat
    else return . Left . getEnumCL $ errcode
    where
      props = bitmaskFromFlags xs

-- -----------------------------------------------------------------------------
clEnqueue :: (CLuint -> Ptr CLEvent -> Ptr CLEvent -> IO CLint) -> [CLEvent] 
             -> IO (Either CLError CLEvent)
clEnqueue f [] = alloca $ \event -> do
  errcode <- f 0 nullPtr event
  if errcode == getCLValue CL_SUCCESS
    then fmap Right $ peek event
    else return . Left . getEnumCL $ errcode
clEnqueue f events = allocaArray nevents $ \pevents -> do
  pokeArray pevents events
  alloca $ \event -> do
    errcode <- f cnevents pevents event
    if errcode == getCLValue CL_SUCCESS
      then fmap Right $ peek event
      else return . Left . getEnumCL $ errcode
    where
      nevents = length events
      cnevents = fromIntegral nevents
