| 1 | {- |
|---|
| 2 | Run with |
|---|
| 3 | dist/dist/tcb-bug <test> <timeout> |
|---|
| 4 | -} |
|---|
| 5 | module Main where |
|---|
| 6 | |
|---|
| 7 | import Foreign |
|---|
| 8 | import Foreign.C |
|---|
| 9 | import Control.Concurrent |
|---|
| 10 | import Graphics.UI.GLUT |
|---|
| 11 | |
|---|
| 12 | main :: IO () |
|---|
| 13 | main = do |
|---|
| 14 | (_,[testNo:_,tl]) <- getArgsAndInitialize |
|---|
| 15 | |
|---|
| 16 | initialWindowPosition $= Position 0 0 |
|---|
| 17 | initialWindowSize $= Size 400 400 |
|---|
| 18 | mainWindow <- createWindow "TCB - Bug Test" |
|---|
| 19 | |
|---|
| 20 | displayCallback $= return () |
|---|
| 21 | |
|---|
| 22 | let tickLength = read tl |
|---|
| 23 | |
|---|
| 24 | case testNo of |
|---|
| 25 | '1' -> test1 tickLength |
|---|
| 26 | '2' -> test2 tickLength |
|---|
| 27 | '3' -> test3 tickLength |
|---|
| 28 | |
|---|
| 29 | mainLoop |
|---|
| 30 | |
|---|
| 31 | test1 tickLength = do |
|---|
| 32 | addTimerCallback (tickLength * 1) (putTicks 0) |
|---|
| 33 | addTimerCallback (tickLength * 2) (putTicks 1) |
|---|
| 34 | addTimerCallback (tickLength * 3) (putTicks 2) |
|---|
| 35 | addTimerCallback (tickLength * 4) (putTicks 3) |
|---|
| 36 | addTimerCallback (tickLength * 5) (putTicks 4) |
|---|
| 37 | |
|---|
| 38 | test2 tickLength = do |
|---|
| 39 | addTimerCallback tickLength (doTick2 tickLength 0 0) |
|---|
| 40 | addTimerCallback tickLength (doTick2 tickLength 0 1) |
|---|
| 41 | addTimerCallback tickLength (doTick2 tickLength 0 2) |
|---|
| 42 | addTimerCallback tickLength (doTick2 tickLength 0 3) |
|---|
| 43 | addTimerCallback tickLength (doTick2 tickLength 0 4) |
|---|
| 44 | addTimerCallback tickLength (doTick2 tickLength 0 5) |
|---|
| 45 | addTimerCallback tickLength (doTick2 tickLength 0 6) |
|---|
| 46 | addTimerCallback tickLength (doTick2 tickLength 0 7) |
|---|
| 47 | addTimerCallback tickLength (doTick2 tickLength 0 8) |
|---|
| 48 | addTimerCallback tickLength (doTick2 tickLength 0 9) |
|---|
| 49 | |
|---|
| 50 | test3 tickLength = addTimerCallback tickLength (doTick3 tickLength 0) |
|---|
| 51 | |
|---|
| 52 | putTicks t = do |
|---|
| 53 | usecs <- getUSecs |
|---|
| 54 | let t' = show t |
|---|
| 55 | let t'' = (replicate (2 - (length t')) ' ') ++ t' |
|---|
| 56 | putStrLn $ "tick: " ++ t'' ++ ", " ++ show usecs |
|---|
| 57 | |
|---|
| 58 | putTicks2 t l = do |
|---|
| 59 | usecs <- getUSecs |
|---|
| 60 | let t' = show t |
|---|
| 61 | let t'' = (replicate (2 - (length t')) ' ') ++ t' |
|---|
| 62 | putStrLn $ "tick: " ++ t'' ++ ", line: " ++ (show l) ++ ", " ++ show usecs |
|---|
| 63 | |
|---|
| 64 | |
|---|
| 65 | doTick2 :: Timeout -> Int -> Int-> IO () |
|---|
| 66 | doTick2 tickLength t l = do |
|---|
| 67 | putTicks2 t l |
|---|
| 68 | if t < 4 |
|---|
| 69 | then |
|---|
| 70 | addTimerCallback tickLength (doTick2 tickLength (t + 1) l) |
|---|
| 71 | else |
|---|
| 72 | return () |
|---|
| 73 | |
|---|
| 74 | doTick3 :: Timeout -> Int -> IO () |
|---|
| 75 | doTick3 tickLength t = do |
|---|
| 76 | if t < 5 |
|---|
| 77 | then |
|---|
| 78 | do |
|---|
| 79 | forkIO f |
|---|
| 80 | yield |
|---|
| 81 | else |
|---|
| 82 | return () |
|---|
| 83 | where |
|---|
| 84 | f = do putTicks t |
|---|
| 85 | addTimerCallback tickLength (doTick3 tickLength (t + 1)) |
|---|
| 86 | |
|---|
| 87 | getUSecs :: IO Integer |
|---|
| 88 | getUSecs = allocaArray 2 $ \buf -> do |
|---|
| 89 | result <- gettimeofday buf nullPtr |
|---|
| 90 | if (result == 0) |
|---|
| 91 | then do tv_sec <- peekElemOff buf 0 |
|---|
| 92 | tv_usec <- peekElemOff buf 1 |
|---|
| 93 | return $ fromIntegral tv_sec * 1000000 + fromIntegral tv_usec |
|---|
| 94 | else error "gettimeofday failed" |
|---|
| 95 | |
|---|
| 96 | -- slight hack, CLong is not really portable |
|---|
| 97 | foreign import ccall unsafe "sys/time.h gettimeofday" gettimeofday :: Ptr CLong -> Ptr () -> IO CInt |
|---|