[project @ 2004-10-17 00:09:58 by ross]
[haskell-directory.git] / Control / Concurrent.hs
index c0352df..97be321 100644 (file)
@@ -68,7 +68,8 @@ module Control.Concurrent (
        rtsSupportsBoundThreads,
        forkOS,
        isCurrentThreadBound,
-       runInBoundThread
+       runInBoundThread,
+       runInUnboundThread
 #endif
 
        -- * GHC's implementation of concurrency
@@ -142,7 +143,7 @@ In GHC, threads may also communicate via exceptions.
 
     Scheduling may be either pre-emptive or co-operative,
     depending on the implementation of Concurrent Haskell (see below
-    for imformation related to specific compilers).  In a co-operative
+    for information related to specific compilers).  In a co-operative
     system, context switches only occur when you use one of the
     primitives defined in this module.  This means that programs such
     as:
@@ -228,8 +229,7 @@ real_handler ex =
 
        -- report all others:
        AsyncException StackOverflow -> reportStackOverflow False
-       ErrorCall s -> reportError False s
-       other       -> reportError False (showsPrec 0 other "\n")
+       other       -> reportError False other
 
 #endif /* __GLASGOW_HASKELL__ */
 
@@ -314,12 +314,8 @@ nmergeIO lss
 {- $boundthreads
 
 Support for multiple operating system threads and bound threads as described
-below is currently only available in the GHC runtime system when the runtime system
-has been compiled using a special option.
-
-When recompiling GHC, use ./configure --enable-threaded-rts to enable this.
-To find your GHC has already been compiled that way, use
-'rtsSupportsBoundThreads' from GHCi.
+below is currently only available in the GHC runtime system if you use the
+/-threaded/ option when linking.
 
 Other Haskell systems do not currently support multiple operating system threads.
 
@@ -382,6 +378,9 @@ forkOS_entry stableAction = do
 foreign import ccall forkOS_createThread
     :: StablePtr (IO ()) -> IO CInt
 
+failNonThreaded = fail $ "RTS doesn't support multiple OS threads "
+                       ++"(use ghc -threaded when linking)"
+    
 forkOS action 
     | rtsSupportsBoundThreads = do
        mv <- newEmptyMVar
@@ -392,7 +391,7 @@ forkOS action
        tid <- takeMVar mv
        freeStablePtr entry
        return tid
-    | otherwise = fail "RTS not built to support multiple OS threads."
+    | otherwise = failNonThreaded
 
 -- | Returns 'True' if the calling thread is /bound/, that is, if it is
 -- safe to use foreign libraries that rely on thread-local state from the
@@ -429,7 +428,7 @@ runInBoundThread action
                case resultOrException of
                    Left exception -> Exception.throw exception
                    Right result -> return result
-    | otherwise = fail "RTS not built to support multiple OS threads."
+    | otherwise = failNonThreaded
 
 {- | 
 Run the 'IO' computation passed as the first argument. If the calling thread
@@ -445,15 +444,15 @@ doesn't need it's main thread to be bound and makes /heavy/ use of concurrency
 runInUnboundThread :: IO a -> IO a
 
 runInUnboundThread action = do
-       bound <- isCurrentThreadBound
-       if bound
-               then do
-                       mv <- newEmptyMVar
-                       forkIO (Exception.try action >>= putMVar mv)
-                       takeMVar mv >>= \either -> case either of
-                       Left exception -> Exception.throw exception
-                       Right result -> return result
-               else action
+    bound <- isCurrentThreadBound
+    if bound
+        then do
+            mv <- newEmptyMVar
+            forkIO (Exception.try action >>= putMVar mv)
+            takeMVar mv >>= \either -> case either of
+                Left exception -> Exception.throw exception
+                Right result -> return result
+        else action
        
 #endif /* __GLASGOW_HASKELL__ */
 
@@ -527,7 +526,7 @@ runInUnboundThread action = do
       a thread may be pre-empted whenever it allocates some memory,
       which unfortunately means that tight loops which do no
       allocation tend to lock out other threads (this only seems to
-      happen with pathalogical benchmark-style code, however).
+      happen with pathological benchmark-style code, however).
 
       The rescheduling timer runs on a 20ms granularity by
       default, but this may be altered using the