module Main where
import Control.Concurrent
import Control.Concurrent.Async.Timer
import Control.Exception
import Control.Monad
import Criterion.Measurement
import Data.Function ((&))
import Data.IORef
import Data.Typeable
import Test.Framework (Test, defaultMain, testGroup)
import Test.Framework.Providers.HUnit (testCase)
import Test.HUnit ((@?=))
data MyException = MyException
deriving (Show, Typeable)
instance Exception MyException
main :: IO ()
main = do
cap <- getNumCapabilities
putStrLn ""
putStrLn $ "Cap = " ++ show cap
defaultMain tests
tests :: [Test.Framework.Test]
tests =
[ testGroup "1st Test Group"
[ testCase "1st Test" test1 ]
]
test1 :: IO ()
test1 = do
let conf = defaultTimerConf & timerConfSetInitDelay 0
& timerConfSetInterval 1000 -- ms
noOfTicks = 5
counter <- newIORef 0
times <- newIORef []
withAsyncTimer conf $ \ timer ->
forM_ [1..noOfTicks] $ \_ -> do
timerWait timer
void $ forkIO $ myAction counter times
threadDelay (5 * 10^5)
n <- readIORef counter
n @?= noOfTicks
ts <- readIORef times
let deltas = case ts of
[] -> []
_ : tsTail -> zipWith (-) ts tsTail
avgDiff = sum (map (subtract 1) deltas) / fromIntegral (length deltas)
forM_ deltas (\ dt -> putStrLn $ "dt = " ++ show dt)
putStrLn $ "average dt = " ++ show avgDiff
return ()
where myAction :: IORef Int -> IORef [Double] -> IO ()
myAction counter times = do
t <- getTime
n <- readIORef counter
let n' = n + 1
writeIORef counter n'
modifyIORef times (t :)
putStrLn $ "Tick no. " ++ show n' ++ " (t = " ++ show t ++ ")"
threadDelay 500000