2 % (c) The AQUA Project, Glasgow University, 1994-1996
5 \section[PrelConc]{Module @PrelConc@}
7 Basic concurrency stuff
10 {-# OPTIONS -fno-implicit-prelude #-}
12 -- Forking and suchlike
16 threadDelay, threadWaitRead, threadWaitWrite,
19 MVar, newMVar, newEmptyMVar, takeMVar, putMVar, readMVar, swapMVar
23 import PrelST ( ST(..), STret(..), StateAndPtr#(..) )
24 import PrelIOBase ( IO(..), IOResult(..), MVar(..) )
25 import PrelErr ( parError )
26 import PrelBase ( Int(..) )
27 import PrelGHC ( fork#, delay#, waitRead#, waitWrite#,
28 SynchVar#, newSynchVar#, takeMVar#, putMVar#,
29 State#, RealWorld, par#
32 infixr 0 `par`, `fork`
37 %************************************************************************
39 \subsection{@par@, and @fork@}
41 %************************************************************************
44 forkST :: ST s a -> ST s a
46 forkST (ST action) = ST $ \ s ->
47 let d@(STret _ r) = action s in
50 forkIO :: IO () -> IO ()
51 forkIO (IO action) = IO $ \ s -> (action s) `fork` IOok s ()
53 par, fork :: Eval a => a -> b -> b
58 #if defined(__PARALLEL_HASKELL__) || defined (__GRANSIM__)
59 par x y = case (par# x) of { 0# -> parError; _ -> y }
64 #if defined(__CONCURRENT_HASKELL__) || defined (__GRANSIM__)
65 fork x y = case (fork# x) of { 0# -> parError; _ -> y }
70 runOrBlockIO m = m -- ?????
74 %************************************************************************
76 \subsection[mvars]{M-Structures}
78 %************************************************************************
80 M-Vars are rendezvous points for concurrent threads. They begin
81 empty, and any attempt to read an empty M-Var blocks. When an M-Var
82 is written, a single blocked thread may be freed. Reading an M-Var
83 toggles its state from full back to empty. Therefore, any value
84 written to an M-Var may only be read once. Multiple reads and writes
85 are allowed, but there must be at least one read between any two
89 --Defined in IOBase to avoid cycle: data MVar a = MVar (SynchVar# RealWorld a)
91 instance Eq (MVar a) where
92 (MVar mvar1#) == (MVar mvar2#) = sameMVar# mvar1# mvar2#
94 newEmptyMVar :: IO (MVar a)
96 newEmptyMVar = IO $ \ s# ->
97 case newSynchVar# s# of
98 StateAndSynchVar# s2# svar# -> IOok s2# (MVar svar#)
100 takeMVar :: MVar a -> IO a
102 takeMVar (MVar mvar#) = IO $ \ s# ->
103 case takeMVar# mvar# s# of
104 StateAndPtr# s2# r -> IOok s2# r
106 putMVar :: MVar a -> a -> IO ()
108 putMVar (MVar mvar#) x = IO $ \ s# ->
109 case putMVar# mvar# x s# of
112 newMVar :: a -> IO (MVar a)
115 newEmptyMVar >>= \ mvar ->
116 putMVar mvar value >>
119 readMVar :: MVar a -> IO a
122 takeMVar mvar >>= \ value ->
123 putMVar mvar value >>
126 swapMVar :: MVar a -> a -> IO a
129 takeMVar mvar >>= \ old ->
135 %************************************************************************
137 \subsection{Thread waiting}
139 %************************************************************************
141 @threadDelay@ delays rescheduling of a thread until the indicated
142 number of microseconds have elapsed. Generally, the microseconds are
143 counted by the context switch timer, which ticks in virtual time;
144 however, when there are no runnable threads, we don't accumulate any
145 virtual time, so we start ticking in real time. (The granularity is
146 the effective resolution of the context switch timer, so it is
147 affected by the RTS -C option.)
149 @threadWaitRead@ delays rescheduling of a thread until input on the
150 specified file descriptor is available for reading (just like select).
151 @threadWaitWrite@ is similar, but for writing on a file descriptor.
154 threadDelay, threadWaitRead, threadWaitWrite :: Int -> IO ()
156 threadDelay (I# x#) = IO $ \ s# ->
160 threadWaitRead (I# x#) = IO $ \ s# ->
161 case waitRead# x# s# of
164 threadWaitWrite (I# x#) = IO $ \ s# ->
165 case waitWrite# x# s# of
169 %*********************************************************
171 \subsection{Ghastly return types}
173 %*********************************************************
176 data StateAndSynchVar# s elt = StateAndSynchVar# (State# s) (SynchVar# s elt)