module Main where import Control.Concurrent hiding (Chan) import Control.Concurrent.GoChan import Control.Monad import System.IO.Unsafe import Weigh main :: IO () main = mainWith (do io "creating a channel" chanConstruction () io "unbuffered send & recv" unbufferedSendRecv chanUnbuffered io "unbuffered select send & recv" unselectSendRecv chanUnbuffered io "unbuffered recv" simpleRecv chanUnbufferedAlreadySent io "unbuffered select recv" unbufferedSendRecv chanUnbufferedAlreadySent io "buffered send" simpleSend chanBufferedEmpty io "buffered recv" simpleRecv chanBufferedAlreadySent io "buffered select send" selectSend chanBufferedEmpty io "buffered select recv" selectRecv chanBufferedAlreadySent) chanConstruction :: () -> IO () chanConstruction = const (void (chanMake 0 :: IO (Chan Int))) unbufferedSendRecv :: Chan Int -> IO () unbufferedSendRecv c = do forkIO $ chanSend c 0 chanRecv c return () unselectSendRecv :: Chan Int -> IO () unselectSendRecv c = do forkIO $ chanSelect [Send c 0 (return ())] Nothing chanSelect [Recv c (const (return ()))] Nothing return () simpleSend :: Chan Int -> IO () simpleSend c = chanSend c 0 simpleRecv :: Chan Int -> IO () simpleRecv c = void (chanRecv c) selectSend :: Chan Int -> IO () selectSend c = chanSelect [Send c 0 (return ())] Nothing selectRecv :: Chan Int -> IO () selectRecv c = chanSelect [Recv c (const (return ()))] Nothing -------------------------------------------------------------------------------- -- We don't want these to show up in allocations, so carefully unsafePerformIO -- here. The threading is scary, but I can't think of any other way to test -- this, given the concurrent nature of this library. {-# NOINLINE chanUnbuffered #-} chanUnbuffered :: Chan Int chanUnbuffered = unsafePerformIO (chanMake 0) {-# NOINLINE chanUnbufferedAlreadySent #-} chanUnbufferedAlreadySent :: Chan Int chanUnbufferedAlreadySent = unsafePerformIO $ do c <- chanMake 0 forkIO $ chanSend c 0 return c {-# NOINLINE chanBufferedEmpty #-} chanBufferedEmpty :: Chan Int chanBufferedEmpty = unsafePerformIO (chanMake 1) {-# NOINLINE chanBufferedAlreadySent #-} chanBufferedAlreadySent :: Chan Int chanBufferedAlreadySent = unsafePerformIO $ do c <- chanMake 1 chanSend c 0 return c