[project @ 2003-08-31 18:41:28 by ross]
[ghc-base.git] / Control / Concurrent.hs
index d41b462..451e4f9 100644 (file)
@@ -21,11 +21,15 @@ module Control.Concurrent (
        -- * Basic concurrency operations
 
         ThreadId,
+#ifdef __GLASGOW_HASKELL__
        myThreadId,
+#endif
 
        forkIO,
+#ifdef __GLASGOW_HASKELL__
        killThread,
        throwTo,
+#endif
 
        -- * Scheduling
 
@@ -52,8 +56,10 @@ module Control.Concurrent (
        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
@@ -84,8 +90,7 @@ import GHC.Base
 #endif
 
 #ifdef __HUGS__
-import IOExts ( unsafeInterleaveIO )
-import ConcBase
+import Hugs.ConcBase
 #endif
 
 import Control.Concurrent.MVar
@@ -94,6 +99,10 @@ import Control.Concurrent.QSem
 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
@@ -108,8 +117,8 @@ 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
@@ -147,12 +156,15 @@ functions blocks only the thread making the call.
 -- 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
@@ -166,12 +178,12 @@ instance Eq ThreadId where
 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
@@ -201,7 +213,7 @@ real_handler ex =
 
 #endif /* __GLASGOW_HASKELL__ */
 
-
+#ifndef __HUGS__
 max_buff_size :: Int
 max_buff_size = 1
 
@@ -273,6 +285,7 @@ nmergeIO lss
     return val
   where
     mapIO f xs = sequence (map f xs)
+#endif /* __HUGS__ */
 
 -- ---------------------------------------------------------------------------
 -- More docs
@@ -299,7 +312,7 @@ nmergeIO lss
 >     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.
 
@@ -348,15 +361,15 @@ nmergeIO lss
 
       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
       the switch from @aaaa@ to