-- * Basic concurrency operations
ThreadId,
+#ifdef __GLASGOW_HASKELL__
myThreadId,
+#endif
forkIO,
+#ifdef __GLASGOW_HASKELL__
killThread,
throwTo,
+#endif
-- * Scheduling
module Control.Concurrent.SampleVar,
-- * Merging of streams
+#ifndef __HUGS__
mergeIO, -- :: [a] -> [a] -> IO [a]
nmergeIO, -- :: [[a]] -> IO [a]
+#endif
-- $merge
- -- * GHC\'s implementation of concurrency
+ -- * GHC's implementation of concurrency
- -- |This section describes features specific to GHC\'s
+ -- |This section describes features specific to GHC's
-- implementation of Concurrent Haskell.
-- ** Terminating the program
#endif
#ifdef __HUGS__
-import IOExts ( unsafeInterleaveIO )
-import ConcBase
+import Hugs.ConcBase
#endif
import Control.Concurrent.MVar
import Control.Concurrent.QSemN
import Control.Concurrent.SampleVar
+#ifdef __HUGS__
+type ThreadId = ()
+#endif
+
{- $conc_intro
The concurrency extension for Haskell is described in the paper
Concurrency is \"lightweight\", which means that both thread creation
and context switching overheads are extremely low. Scheduling of
Haskell threads is done internally in the Haskell runtime system, and
-doesn\'t make use of any operating system-supplied thread packages.
+doesn't make use of any operating system-supplied thread packages.
Haskell threads can communicate via 'MVar's, a kind of synchronised
mutable variable (see "Control.Concurrent.MVar"). Several common
concurrency abstractions can be built from 'MVar's, and these are
-provided by the "Concurrent" library. Threads may also communicate
-via exceptions.
+provided by the "Control.Concurrent" library.
+In GHC, threads may also communicate via exceptions.
-}
{- $conc_scheduling
as:
-> main = forkIO (write \'a\') >> write \'b\'
+> main = forkIO (write 'a') >> write 'b'
> where write c = putChar c >> write c
will print either @aaaaaaaaaaaaaa...@ or @bbbbbbbbbbbb...@,
Calling a foreign C procedure (such as @getchar@) that blocks waiting
for input will block /all/ threads, unless the @threadsafe@ attribute
is used on the foreign call (and your compiler \/ operating system
-supports it). GHC\'s I\/O system uses non-blocking I\/O internally to
+supports it). GHC's I\/O system uses non-blocking I\/O internally to
implement thread-friendly I\/O, so calling standard Haskell I\/O
-functions blocks only the thead making the call.
+functions blocks only the thread making the call.
-}
-- Thread Ids, specifically the instances of Eq and Ord for these things.
-- cmp_thread in the RTS.
#ifdef __GLASGOW_HASKELL__
-foreign import ccall unsafe "cmp_thread" cmp_thread :: Addr# -> Addr# -> Int
+id2TSO :: ThreadId -> ThreadId#
+id2TSO (ThreadId t) = t
+
+foreign import ccall unsafe "cmp_thread" cmp_thread :: ThreadId# -> ThreadId# -> Int
-- Returns -1, 0, 1
cmpThread :: ThreadId -> ThreadId -> Ordering
-cmpThread (ThreadId t1) (ThreadId t2) =
- case cmp_thread (unsafeCoerce# t1) (unsafeCoerce# t2) of
+cmpThread t1 t2 =
+ case cmp_thread (id2TSO t1) (id2TSO t2) of
-1 -> LT
0 -> EQ
_ -> GT -- must be 1
instance Ord ThreadId where
compare = cmpThread
-foreign import ccall unsafe "rts_getThreadId" getThreadId :: Addr# -> Int
+foreign import ccall unsafe "rts_getThreadId" getThreadId :: ThreadId# -> Int
instance Show ThreadId where
- showsPrec d (ThreadId t) =
+ showsPrec d t =
showString "ThreadId " .
- showsPrec d (getThreadId (unsafeCoerce# t))
+ showsPrec d (getThreadId (id2TSO t))
{- |
This sparks off a new thread to run the 'IO' computation passed as the
#endif /* __GLASGOW_HASKELL__ */
-
+#ifndef __HUGS__
max_buff_size :: Int
max_buff_size = 1
return val
where
mapIO f xs = sequence (map f xs)
+#endif /* __HUGS__ */
-- ---------------------------------------------------------------------------
-- More docs
> return mvar
Note that we use 'finally' from the
- "Exception" module to make sure that the
+ "Control.Exception" module to make sure that the
'MVar' is written to even if the thread dies or
is killed for some reason.
The rescheduling timer runs on a 20ms granularity by
default, but this may be altered using the
- @-i<n>@ RTS option. After a rescheduling
+ @-i\<n\>@ RTS option. After a rescheduling
\"tick\" the running thread is pre-empted as soon as
possible.
One final note: the
@aaaa@ @bbbb@ example may not
work too well on GHC (see Scheduling, above), due
- to the locking on a 'Handle'. Only one thread
- may hold the lock on a 'Handle' at any one
+ to the locking on a 'System.IO.Handle'. Only one thread
+ may hold the lock on a 'System.IO.Handle' at any one
time, so if a reschedule happens while a thread is holding the
- lock, the other thread won\'t be able to run. The upshot is that
+ lock, the other thread won't be able to run. The upshot is that
the switch from @aaaa@ to
@bbbbb@ happens infrequently. It can be
improved by lowering the reschedule tick period. We also have a
patch that causes a reschedule whenever a thread waiting on a
- lock is woken up, but haven\'t found it to be useful for anything
+ lock is woken up, but haven't found it to be useful for anything
other than this example :-)
-}