2 % (c) The AQUA Project, Glasgow University, 1994-1996
5 \section[ConcBase]{Module @ConcBase@}
7 Basic concurrency stuff
10 {-# OPTIONS -fno-implicit-prelude #-}
12 -- Forking and suchlike
17 threadDelay, threadWaitRead, threadWaitWrite,
20 MVar, newMVar, newEmptyMVar, takeMVar, putMVar, readMVar, swapMVar
24 import STBase ( PrimIO(..), ST(..), State(..), StateAndPtr#(..) )
25 import IOBase ( IO(..), MVar(..) )
26 import GHCerr ( parError )
27 import PrelBase ( Int(..) )
28 import GHC ( fork#, delay#, waitRead#, waitWrite#,
29 SynchVar#, newSynchVar#, takeMVar#, putMVar#,
30 State#, RealWorld, par#
33 infixr 0 `par`, `fork`
38 %************************************************************************
40 \subsection{@par@, and @fork@}
42 %************************************************************************
45 forkST :: ST s a -> ST s a
47 forkST (ST action) = ST $ \ s ->
53 forkPrimIO :: PrimIO a -> PrimIO a
56 forkIO :: IO () -> IO ()
57 forkIO (IO (ST action)) = IO $ ST $ \ s ->
61 new_s `fork` (Right (), s)
63 par, fork :: Eval a => a -> b -> b
68 #if defined(__PARALLEL_HASKELL__) || defined (__GRANSIM__)
69 par x y = case (par# x) of { 0# -> parError; _ -> y }
74 #if defined(__CONCURRENT_HASKELL__) || defined (__GRANSIM__)
75 fork x y = case (fork# x) of { 0# -> parError; _ -> y }
82 %************************************************************************
84 \subsection[PreludeGlaST-mvars]{M-Structures}
86 %************************************************************************
88 M-Vars are rendezvous points for concurrent threads. They begin
89 empty, and any attempt to read an empty M-Var blocks. When an M-Var
90 is written, a single blocked thread may be freed. Reading an M-Var
91 toggles its state from full back to empty. Therefore, any value
92 written to an M-Var may only be read once. Multiple reads and writes
93 are allowed, but there must be at least one read between any two
97 --Defined in IOBase to avoid cycle: data MVar a = MVar (SynchVar# RealWorld a)
99 newEmptyMVar :: IO (MVar a)
101 newEmptyMVar = IO $ ST $ \ (S# s#) ->
102 case newSynchVar# s# of
103 StateAndSynchVar# s2# svar# -> (Right (MVar svar#), S# s2#)
105 takeMVar :: MVar a -> IO a
107 takeMVar (MVar mvar#) = IO $ ST $ \ (S# s#) ->
108 case takeMVar# mvar# s# of
109 StateAndPtr# s2# r -> (Right r, S# s2#)
111 putMVar :: MVar a -> a -> IO ()
113 putMVar (MVar mvar#) x = IO $ ST $ \ (S# s#) ->
114 case putMVar# mvar# x s# of
115 s2# -> (Right (), S# s2#)
117 newMVar :: a -> IO (MVar a)
120 newEmptyMVar >>= \ mvar ->
121 putMVar mvar value >>
124 readMVar :: MVar a -> IO a
127 takeMVar mvar >>= \ value ->
128 putMVar mvar value >>
131 swapMVar :: MVar a -> a -> IO a
134 takeMVar mvar >>= \ old ->
140 %************************************************************************
142 \subsection{Thread waiting}
144 %************************************************************************
146 @threadDelay@ delays rescheduling of a thread until the indicated
147 number of microseconds have elapsed. Generally, the microseconds are
148 counted by the context switch timer, which ticks in virtual time;
149 however, when there are no runnable threads, we don't accumulate any
150 virtual time, so we start ticking in real time. (The granularity is
151 the effective resolution of the context switch timer, so it is
152 affected by the RTS -C option.)
154 @threadWaitRead@ delays rescheduling of a thread until input on the
155 specified file descriptor is available for reading (just like select).
156 @threadWaitWrite@ is similar, but for writing on a file descriptor.
159 threadDelay, threadWaitRead, threadWaitWrite :: Int -> IO ()
161 threadDelay (I# x#) = IO $ ST $ \ (S# s#) ->
163 s2# -> (Right (), S# s2#)
165 threadWaitRead (I# x#) = IO $ ST $ \ (S# s#) ->
166 case waitRead# x# s# of
167 s2# -> (Right (), S# s2#)
169 threadWaitWrite (I# x#) = IO $ ST $ \ (S# s#) ->
170 case waitWrite# x# s# of
171 s2# -> (Right (), S# s2#)
174 %*********************************************************
176 \subsection{Ghastly return types}
178 %*********************************************************
181 data StateAndSynchVar# s elt = StateAndSynchVar# (State# s) (SynchVar# s elt)