 -- Create a new CUDA context and associate it with the calling thread
 --
 create :: Device -> [ContextFlag] -> IO (Either String Context)
-create dev flags =
-  newContext              >>= \ctx -> withContext ctx $ \p ->
-  cuCtxCreate p flags dev >>= \rv  ->
-    return $ case nothingIfOk rv of
-      Nothing -> Right ctx
-      Just e  -> Left  e
+create dev flags = resultIfOk `fmap` cuCtxCreate flags dev
 
 {# fun unsafe cuCtxCreate
-  { id              `Ptr Context'
+  { alloca-         `Context'       peekCtx*
   , combineBitMasks `[ContextFlag]'
-  , useDevice       `Device'         } -> `Status' cToEnum #}
+  , useDevice       `Device'                 } -> `Status' cToEnum #}
+  where peekCtx = liftM Context . peek
 
 
 -- |

-- currently supported, so this parameter must be empty.
--
attach :: Context -> [ContextFlag] -> IO (Maybe String)
attach ctx flags = withContext ctx $ \p -> (nothingIfOk `fmap` cuCtxAttach p flags)

{# fun unsafe cuCtxAttach
  { id              `Ptr Context'
  , combineBitMasks `[ContextFlag]' } -> `Status' cToEnum #}


-- |
-- Detach the context, and destroy if no longer used
--
detach :: Context -> IO (Maybe String)
detach ctx = withContext ctx $ \p -> (nothingIfOk `fmap` cuCtxDetach p)

{# fun unsafe cuCtxDetach
  { castPtr `Ptr Context' } -> `Status' cToEnum #}


-- |

-- context must be floating (via `pop'), i.e. not attached to any thread.
--
push :: Context -> IO (Maybe String)
push ctx = nothingIfOk `fmap` cuCtxPushCurrent ctx

{# fun unsafe cuCtxPushCurrent
  { useContext `Context' } -> `Status' cToEnum #}


-- |
