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 newEmptyMVar :: IO (MVar a)
93 newEmptyMVar = IO $ \ s# ->
94 case newSynchVar# s# of
95 StateAndSynchVar# s2# svar# -> IOok s2# (MVar svar#)
97 takeMVar :: MVar a -> IO a
99 takeMVar (MVar mvar#) = IO $ \ s# ->
100 case takeMVar# mvar# s# of
101 StateAndPtr# s2# r -> IOok s2# r
103 putMVar :: MVar a -> a -> IO ()
105 putMVar (MVar mvar#) x = IO $ \ s# ->
106 case putMVar# mvar# x s# of
109 newMVar :: a -> IO (MVar a)
112 newEmptyMVar >>= \ mvar ->
113 putMVar mvar value >>
116 readMVar :: MVar a -> IO a
119 takeMVar mvar >>= \ value ->
120 putMVar mvar value >>
123 swapMVar :: MVar a -> a -> IO a
126 takeMVar mvar >>= \ old ->
132 %************************************************************************
134 \subsection{Thread waiting}
136 %************************************************************************
138 @threadDelay@ delays rescheduling of a thread until the indicated
139 number of microseconds have elapsed. Generally, the microseconds are
140 counted by the context switch timer, which ticks in virtual time;
141 however, when there are no runnable threads, we don't accumulate any
142 virtual time, so we start ticking in real time. (The granularity is
143 the effective resolution of the context switch timer, so it is
144 affected by the RTS -C option.)
146 @threadWaitRead@ delays rescheduling of a thread until input on the
147 specified file descriptor is available for reading (just like select).
148 @threadWaitWrite@ is similar, but for writing on a file descriptor.
151 threadDelay, threadWaitRead, threadWaitWrite :: Int -> IO ()
153 threadDelay (I# x#) = IO $ \ s# ->
157 threadWaitRead (I# x#) = IO $ \ s# ->
158 case waitRead# x# s# of
161 threadWaitWrite (I# x#) = IO $ \ s# ->
162 case waitWrite# x# s# of
166 %*********************************************************
168 \subsection{Ghastly return types}
170 %*********************************************************
173 data StateAndSynchVar# s elt = StateAndSynchVar# (State# s) (SynchVar# s elt)