summaryrefslogtreecommitdiff
path: root/testsuite/tests
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2010-03-11 12:02:31 +0000
committerSimon Marlow <marlowsd@gmail.com>2010-03-11 12:02:31 +0000
commit501039704b8586a357cf57133dc1f31ce44679d8 (patch)
tree1ff26c5cb158752b0c5affc87a0746f5ede99023 /testsuite/tests
parent286dc0aaea694751b8aac0159a8ddf10dc60243a (diff)
downloadhaskell-501039704b8586a357cf57133dc1f31ce44679d8.tar.gz
Add some tortuous throwTo tests
Diffstat (limited to 'testsuite/tests')
-rw-r--r--testsuite/tests/ghc-regress/concurrent/should_run/all.T5
-rw-r--r--testsuite/tests/ghc-regress/concurrent/should_run/throwto001.hs38
-rw-r--r--testsuite/tests/ghc-regress/concurrent/should_run/throwto002.hs25
-rw-r--r--testsuite/tests/ghc-regress/concurrent/should_run/throwto003.hs17
4 files changed, 85 insertions, 0 deletions
diff --git a/testsuite/tests/ghc-regress/concurrent/should_run/all.T b/testsuite/tests/ghc-regress/concurrent/should_run/all.T
index a90b2260c3..122fb385a4 100644
--- a/testsuite/tests/ghc-regress/concurrent/should_run/all.T
+++ b/testsuite/tests/ghc-regress/concurrent/should_run/all.T
@@ -151,3 +151,8 @@ test('conc065', ignore_output, compile_and_run, [''])
test('conc066', ignore_output, compile_and_run, [''])
test('conc067', ignore_output, compile_and_run, [''])
test('conc068', exit_code(1), compile_and_run, [''])
+
+# each of these runs for about a second
+test('throwto001', extra_run_opts('1000 2000'), compile_and_run, [''])
+test('throwto002', ignore_output, compile_and_run, [''])
+test('throwto003', normal, compile_and_run, [''])
diff --git a/testsuite/tests/ghc-regress/concurrent/should_run/throwto001.hs b/testsuite/tests/ghc-regress/concurrent/should_run/throwto001.hs
new file mode 100644
index 0000000000..999d3335d8
--- /dev/null
+++ b/testsuite/tests/ghc-regress/concurrent/should_run/throwto001.hs
@@ -0,0 +1,38 @@
+import Control.Concurrent
+import Control.Exception
+import Data.Array
+import System.Random
+import System.Environment
+import Control.Monad
+import GHC.Conc
+
+-- A fiendish throwTo test. A bunch of threads take random MVars from
+-- a shared array; if the MVar has Nothing in it, replace it with Just
+-- of the current thread's ThreadId. If the MVar has another ThreadId
+-- in it, then killThread that thread, and replace it with the current
+-- thread's ThreadId. We keep going until only one thread is left
+-- standing.
+--
+-- On multiple CPUs this should give throwTo a good workout.
+--
+main = do
+ [m, t] <- fmap (fmap read) getArgs
+ ms <- replicateM m $ newMVar Nothing
+ let arr = listArray (1,m) ms
+ dead <- newTVarIO 0
+ ts <- replicateM t $ forkIO (thread m arr `onException`
+ (atomically $ do d <- readTVar dead
+ writeTVar dead $! d+1))
+ atomically $ do
+ d <- readTVar dead
+ when (d < t-1) $ retry
+
+thread m arr = do
+ x <- randomIO
+ id <- myThreadId
+ modifyMVar_ (arr ! ((x `mod` m) + 1)) $ \b ->
+ case b of
+ Nothing -> return (Just id)
+ Just other -> do when (other /= id) $ killThread other
+ return (Just id)
+ thread m arr
diff --git a/testsuite/tests/ghc-regress/concurrent/should_run/throwto002.hs b/testsuite/tests/ghc-regress/concurrent/should_run/throwto002.hs
new file mode 100644
index 0000000000..c9857f1f1e
--- /dev/null
+++ b/testsuite/tests/ghc-regress/concurrent/should_run/throwto002.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE DoRec, ScopedTypeVariables #-}
+import Control.Concurrent
+import Control.Exception
+import Data.Array
+import System.Random
+import System.Environment
+import Control.Monad
+import GHC.Conc
+import Data.IORef
+import Prelude hiding (catch)
+
+main = do
+ r <- newIORef 0
+ rec
+ t1 <- block $ forkIO (thread r t2)
+ t2 <- block $ forkIO (thread r t1)
+ threadDelay 1000000
+ readIORef r >>= print
+
+thread r t = run
+ where
+ run = (unblock $ forever $ do killThread t
+ i <- atomicModifyIORef r (\i -> (i + 1, i))
+ evaluate i)
+ `catch` \(e::SomeException) -> run
diff --git a/testsuite/tests/ghc-regress/concurrent/should_run/throwto003.hs b/testsuite/tests/ghc-regress/concurrent/should_run/throwto003.hs
new file mode 100644
index 0000000000..6369c62352
--- /dev/null
+++ b/testsuite/tests/ghc-regress/concurrent/should_run/throwto003.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE DoRec, ScopedTypeVariables #-}
+import Control.Concurrent
+import Control.Exception
+import Control.Monad
+import Prelude hiding (catch)
+
+main = do
+ m <- newMVar 1
+ t1 <- forkIO $ thread m
+ t2 <- forkIO $ forever $ killThread t1
+ threadDelay 1000000
+ takeMVar m
+
+thread m = run
+ where
+ run = (unblock $ forever $ modifyMVar_ m $ \v -> if v `mod` 2 == 1 then return (v*2) else return (v-1))
+ `catch` \(e::SomeException) -> run