--
-----------------------------------------------------------------------------
-#include "config.h"
+#include "ghcconfig.h"
module GHC.Conc
( ThreadId(..)
, pseq -- :: a -> b -> b
, yield -- :: IO ()
, labelThread -- :: ThreadId -> String -> IO ()
- , forkProcessPrim -- :: IO Int
-- Waiting
, threadDelay -- :: Int -> IO ()
#ifdef mingw32_TARGET_OS
, asyncRead -- :: Int -> Int -> Int -> Ptr a -> IO (Int, Int)
, asyncWrite -- :: Int -> Int -> Int -> Ptr a -> IO (Int, Int)
+ , asyncDoProc -- :: FunPtr (Ptr a -> IO Int) -> Ptr a -> IO Int
, asyncReadBA -- :: Int -> Int -> Int -> Int -> MutableByteArray# RealWorld -> IO (Int, Int)
, asyncWriteBA -- :: Int -> Int -> Int -> Int -> MutableByteArray# RealWorld -> IO (Int, Int)
import GHC.Base ( Int(..) )
import GHC.Exception ( Exception(..), AsyncException(..) )
import GHC.Pack ( packCString# )
-import GHC.Ptr ( Ptr(..), plusPtr )
+import GHC.Ptr ( Ptr(..), plusPtr, FunPtr(..) )
infixr 0 `par`, `pseq`
\end{code}
adr = byteArrayContents# ps in
case (labelThread# t adr s) of s1 -> (# s1, () #)
-{- | This function is a replacement for 'System.Posix.Process.forkProcessAll':
-This implementation /will stop all other Concurrent Haskell threads/ in the
-(heavyweight) forked copy.
-'forkProcessPrim' returns the pid of the child process to the parent, 0 to the
-child, and a value less than 0 in case of errors. See also:
-'System.Posix.Process.forkProcess' in package @unix@.
-
-Without this function, you need excessive and often impractical
-explicit synchronization using the regular Concurrent Haskell constructs to assure
-that only the desired thread is running after the fork().
-
-The stopped threads are /not/ garbage collected! This behaviour may change in
-future releases.
-
-NOTE: currently, main threads are not stopped in the child process.
-To work around this problem, call 'forkProcessPrim' from the main thread.
--}
-
--- XXX RTS should know about 'pid_t'.
-
-forkProcessPrim :: IO Int
-forkProcessPrim = IO $ \s -> case (forkProcess# s) of (# s1, id #) -> (# s1, (I# id) #)
-
-- Nota Bene: 'pseq' used to be 'seq'
-- but 'seq' is now defined in PrelGHC
--
-- 'putMVar' will wait until it becomes empty.
--
-- If several threads are competing to fill the same 'MVar', one is
--- chosen to continue at random with the 'MVar' becomes empty.
+-- chosen to continue at random when the 'MVar' becomes empty.
putMVar :: MVar a -> a -> IO ()
putMVar (MVar mvar#) x = IO $ \ s# ->
case putMVar# mvar# x s# of
@threadWaitWrite@ is similar, but for writing on a file descriptor.
\begin{code}
--- |The 'threadDelay' operation will cause the current thread to
--- suspend for a given number of microseconds (GHC only).
+-- | Suspends the current thread for a given number of microseconds
+-- (GHC only).
+--
+-- Note that the resolution used by the Haskell runtime system's
+-- internal timer is 1\/50 second, and 'threadDelay' will round its
+-- argument up to the nearest multiple of this resolution.
+--
+-- There is no guarantee that the thread will be rescheduled promptly
+-- when the delay has expired, but the thread will never continue to
+-- run /earlier/ than specified.
--
--- Note that the resolution
--- used by the Haskell runtime system\'s internal timer together with the
--- fact that the thread may take some time to be rescheduled after the
--- time has expired, means that the accuracy is more like 1\/50 second.
threadDelay :: Int -> IO ()
-- | Block the current thread until data is available to read on the
IO $ \s -> case asyncWrite# fd isSock len buf s of
(# s, len#, err# #) -> (# s, (I# len#, I# err#) #)
+asyncDoProc :: FunPtr (Ptr a -> IO Int) -> Ptr a -> IO Int
+asyncDoProc (FunPtr proc) (Ptr param) =
+ -- the 'length' value is ignored; simplifies implementation of
+ -- the async*# primops to have them all return the same result.
+ IO $ \s -> case asyncDoProc# proc param s of
+ (# s, len#, err# #) -> (# s, I# err# #)
+
-- to aid the use of these primops by the IO Handle implementation,
-- provide the following convenience funs: