summaryrefslogtreecommitdiff
path: root/testsuite/tests/concurrent/should_run/conc032.hs
diff options
context:
space:
mode:
Diffstat (limited to 'testsuite/tests/concurrent/should_run/conc032.hs')
-rw-r--r--testsuite/tests/concurrent/should_run/conc032.hs74
1 files changed, 74 insertions, 0 deletions
diff --git a/testsuite/tests/concurrent/should_run/conc032.hs b/testsuite/tests/concurrent/should_run/conc032.hs
new file mode 100644
index 0000000000..42149ff477
--- /dev/null
+++ b/testsuite/tests/concurrent/should_run/conc032.hs
@@ -0,0 +1,74 @@
+-- !!! this test exposed a bug in the take/putMVar implementation in
+-- !!! GHC 5.00. It involves multiple blocking takes & puts on the
+-- !!! same MVar.
+
+import Control.Concurrent
+import System.IO.Unsafe
+
+awk True True z = 1
+awk False y True = 2
+awk x False False = 3
+
+awk'1 True True z = 1
+awk'2 False y True = 2
+awk'3 x False False = 3
+
+awk' x y z | ppm [a1'1,a1'2,a1'3] (x,y,z) = awk'1 x y z
+ | ppm [a2'1,a2'2,a2'3] (x,y,z) = awk'2 x y z
+ | ppm [a3'1,a3'2,a3'3] (x,y,z) = awk'3 x y z
+ | otherwise = 0
+
+a1'1 (True,y,z) s = s True
+a1'1 (x,y,z) s = s False
+
+a1'2 (x,True,z) s = s True
+a1'2 (x,y,z) s = s False
+
+a1'3 (x,y,z) s = s True
+
+a2'1 (False,y,z) s = s True
+a2'1 (x,y,z) s = s False
+
+a2'2 (x,y,z) s = s True
+
+a2'3 (x,y,True) s = s True
+a2'3 (x,y,z) s = s False
+
+a3'1 (x,y,z) s = s True
+
+a3'2 (x,False,z) s = s True
+a3'2 (x,y,z) s = s False
+
+a3'3 (x,y,False) s = s True
+a3'3 (x,y,z) s = s False
+
+ppm fs as = unsafePerformIO (ppm' fs as)
+
+ppm' fs as = do m <- newEmptyMVar
+ let s = putMVar m
+ hs <- sequence [forkIO (f as s)|f <- fs]
+ result <- assess (length fs) m
+ sequence (map killThread hs)
+ return result
+ where assess 0 m = return True
+ assess n m = do h <- takeMVar m
+ if h then (assess (n-1) m)
+ else return False
+
+main = do sequence [putStrLn (show (awk' x y z))|(x,y,z) <- args]
+ where args = [
+ (t,t,t),
+ (t,t,f),
+ (t,f,t),
+ (t,f,f),
+ (f,t,t),
+ (f,t,f),
+ (f,f,t),
+ (f,f,f),
+ (t,t,n)
+ --(f,n,t),
+ --(n,f,f),
+ ]
+ t = True
+ f = False
+ n = odd (last [1..])