testSV name newEmpty read write = do
  putStrLn ("\n\nTest "++ name)
  sv <- newEmpty
  putStrLn "0: forkIO read thread 1"
  (t1,m1) <- fork $ do
    read sv `onException` (putStrLn "1: read interrupted")
    putStrLn "1: read done UNEXPECTED"
  putStrLn "0: stop thread 1"
  stop (t1,m1)
  putStrLn "0: write sv #1"
  write sv 1
  putStrLn "0: write sv #2 with timeout"
  m <- timeout (1000*100) (write sv 2)
  case m of
    Nothing -> do
      putStrLn "0: timeout triggered, write sv #2 blocked, FAIL"
      return False
    Just () -> do
      putStrLn "0: write sv #2 returned, PASS"
      return True

-- True if test passed, False if test failed
-- This does not expect FIFO semantics for the waiters, uses getValue instead
testSV name newEmpty read write = do
  putStrLn ("\n\nTest "++ name)
  sv <- newEmpty
  putStrLn "0: forkIO read thread 1"
  (t1,m1) <- fork $ do
    read sv `onException` (putStrLn "1: read interrupted")
    putStrLn "1: read done UNEXPECTED"
  putStrLn "0: stop thread 1"
  stop (t1,m1)
  putStrLn "0: write sv #1"
  write sv 1
  putStrLn "0: write sv #2 with timeout"
  m <- timeout (1000*100) (write sv 2)
  case m of
    Nothing -> do
      putStrLn "0: timeout triggered, write sv #2 blocked, FAIL"
      return False
    Just () -> do
      putStrLn "0: write sv #2 returned, PASS"
      return True

-- True if test passed, False if test failed
-- This does not expect FIFO semantics for the waiters, uses getValue instead
testSV name newEmpty read write = do
  putStrLn ("\n\nTest "++ name)
  sv <- newEmpty
  putStrLn "0: forkIO read thread 1"
  (t1,m1) <- fork $ do
    read sv `onException` (putStrLn "1: read interrupted")
    putStrLn "1: read done UNEXPECTED"
  putStrLn "0: stop thread 1"
  stop (t1,m1)
  putStrLn "0: write sv #1"
  write sv 1
  putStrLn "0: write sv #2 with timeout"
  m <- timeout (1000*100) (write sv 2)
  case m of
    Nothing -> do
      putStrLn "0: timeout triggered, write sv #2 blocked, FAIL"
      return False
    Just () -> do
      putStrLn "0: write sv #2 returned, PASS"
      return True

-- True if test passed, False if test failed
-- This does not expect FIFO semantics for the waiters, uses getValue instead