caf 0.0.1 → 0.0.2
raw patch · 16 files changed
+472/−30 lines, 16 files
Files
- Control/Concurrent/Futures.hs +0/−10
- Control/Concurrent/Futures/BChan.hs +1/−1
- Control/Concurrent/Futures/Buffer.hs +5/−14
- Control/Concurrent/Futures/Chan.hs +1/−1
- Control/Concurrent/Futures/Futures.hs +1/−1
- Control/Concurrent/Futures/HQSem.hs +8/−1
- Control/Concurrent/Futures/QSem.hs +1/−1
- Examples/Example01.hs +33/−0
- Examples/Example02.hs +39/−0
- Examples/Example03.hs +29/−0
- Examples/Example04.hs +40/−0
- Examples/Example05.hs +29/−0
- Examples/Example06.hs +42/−0
- Examples/Example07.hs +32/−0
- Examples/Examples.hs +201/−0
- caf.cabal +10/−1
Control/Concurrent/Futures.hs view
@@ -59,7 +59,6 @@ module Control.Concurrent.Futures.HQSem, module Control.Concurrent.Futures.BChan, module Control.Concurrent.Futures.Barrier,- module Control.Concurrent.Futures.Examples, ) where import Control.Concurrent.Futures.Futures@@ -69,12 +68,3 @@ import Control.Concurrent.Futures.HQSem import Control.Concurrent.Futures.BChan import Control.Concurrent.Futures.Barrier-import Control.Concurrent.Futures.Examples----- internal function---wait :: Bool -> IO Bool---wait x = do--- case x of--- True -> return x--- otherwise -> return x
Control/Concurrent/Futures/BChan.hs view
@@ -1,7 +1,7 @@ {- | Module : <File name or $Header$ to be replaced automatically> Description : This module implements a bounded channel concurrency primitive using channels and quantity semaphores-Maintainer : mwillig@gmx.de+Maintainer : willig@ki.informatik.uni-frankfurt.de Stability : experimental Portability : non-portable (requires Futures)
Control/Concurrent/Futures/Buffer.hs view
@@ -1,7 +1,7 @@ {- | Module : <File name or $Header$ to be replaced automatically> Description : This module implements a buffer with cells and futures.-Maintainer : mwillig@gmx.de+Maintainer : willig@ki.informatik.uni-frankfurt.de Stability : experimental Portability : non-portable (requires Futures) @@ -11,10 +11,6 @@ -} module Control.Concurrent.Futures.Buffer ( Buffer,--- Cell,--- cell,--- testAndSet,- wait, newBuf, putBuf, getBuf@@ -24,7 +20,9 @@ import Control.Concurrent.MVar import System.IO --- -- The buffer type contains of 3 cells and a handle.+-- | The buffer type contains of 3 cells and a handle. The first 2 cells are for+-- communication of either a put or get is allowed. The thrist cell is the storage+-- cell, the last cell contains a the active handle. type Buffer a = (Cell Bool, Cell Bool, Cell a, Cell (Bool -> IO ())) -----------------------------------------------------------------------@@ -49,16 +47,9 @@ False -> do code exchange cell False---- | A test on cells---tsExample = do--- c <- Buffer.cell False--- code <- (\x -> do putStrLn "The code." return x)--- Buffer.testAndSet c code--- return c ------------------------------------------------------------------------------- --- | Waits its argument to become true+-- | Waits its argument to become true. wait :: Bool -> IO Bool wait x = do case x of
Control/Concurrent/Futures/Chan.hs view
@@ -1,7 +1,7 @@ {- | Module : <File name or $Header$ to be replaced automatically> Description : This module implements a channel concurrency primitive using Buffers.-Maintainer : mwillig@gmx.de+Maintainer : willig@ki.informatik.uni-frankfurt.de Stability : experimental Portability : non-portable (requires Futures)
Control/Concurrent/Futures/Futures.hs view
@@ -1,7 +1,7 @@ {- | Module : <File name or $Header$ to be replaced automatically> Description : This module implements several kinds of futures using Concurrent Haskell-Maintainer : sabel@ki.cs.uni-frankfurt.de+Maintainer : sabel@ki.cs.uni-frankfurt.de; willig@ki.cs.uni-frankfurt.de Stability : provisional Portability : portable
Control/Concurrent/Futures/HQSem.hs view
@@ -1,7 +1,7 @@ {- | Module : <File name or $Header$ to be replaced automatically> Description : This module implements a quantity semaphores with handles-Maintainer : mwillig@gmx.de+Maintainer : willig@ki.informatik.uni-frankfurt.de Stability : experimental Portability : non-portable (requires Futures) @@ -65,3 +65,10 @@ False -> do putBuf qsem (cnt-1,ls) return True++-- | Waits its argument to become true.+wait :: Bool -> IO Bool+wait x = do+ case x of+ True -> return x+ otherwise -> return x
Control/Concurrent/Futures/QSem.hs view
@@ -1,7 +1,7 @@ {- | Module : <File name or $Header$ to be replaced automatically> Description : This module implements a quantity semaphores with buffers-Maintainer : mwillig@gmx.de+Maintainer : willig@ki.informatik.uni-frankfurt.de Stability : experimental Portability : non-portable (requires Futures)
+ Examples/Example01.hs view
@@ -0,0 +1,33 @@++module Control.Concurrent.Futures.Example01 where+import qualified Control.Concurrent.Futures.Buffer as Buffer+import qualified Control.Concurrent.Futures.Futures as Futures+import Control.Concurrent++-- local finals+oneSecond = 1000000++-- | Producer Consumer example with buffers demonstrating 'Futures.withFuturesDo'.+bufferExampleF:: IO ()+bufferExampleF = Futures.withFuturesDo bufferExample++-- | Producer Consumer example with buffers.+bufferExample :: IO ()+bufferExample = do+ putStrLn $ "Producer-Consumer example with buffers"+ b <- Buffer.newBuf+ Control.Concurrent.forkIO $ (writeBufferThread b)+ Control.Concurrent.forkIO $ (readBufferThread b)+ Control.Concurrent.threadDelay $ 10 * oneSecond++writeBufferThread b = do+ Buffer.putBuf b 1+ Buffer.putBuf b 2+ Control.Concurrent.threadDelay oneSecond+ Buffer.putBuf b 3++readBufferThread b = do + val <- Buffer.getBuf b+ putStrLn $ "read: " ++ show val+ Control.Concurrent.threadDelay oneSecond+ readBufferThread b
+ Examples/Example02.hs view
@@ -0,0 +1,39 @@++module Control.Concurrent.Futures.Example02 where++import qualified Control.Concurrent.Futures.Chan as Chan+import qualified Control.Concurrent.Futures.Futures as Futures+import Control.Concurrent++-- local finals+oneSecond = 1000000+--------------------------------------------------------------------------------+-- | Producer Consumer Example for channels using 'Futures.withFuturesDo'.+channelExampleF :: IO ()+channelExampleF = Futures.withFuturesDo channelExample++-- | Producer Consumer Example for channels.+channelExample :: IO ()+channelExample = do+ putStrLn $ "Producer-Consumer example with channels"+ channel <- Chan.newChan+ Control.Concurrent.forkIO $ (produce 10 channel)+ Control.Concurrent.forkIO $ (consume channel)+ Control.Concurrent.threadDelay $ 10 * oneSecond++consume :: (Show a) => Chan.Chan a -> IO b+consume chan = do+ putStrLn $ "Trying to read..."+ val <- Chan.readChan chan+ putStrLn $ "read new value: " ++ show val+ --Control.Concurrent.threadDelay oneSecond+ consume chan++produce :: (Num a) => a -> Chan.Chan a -> IO ()+produce n chan = do+ case n of+ 0 -> Chan.writeChan chan n+ otherwise -> do+ Chan.writeChan chan n+ Control.Concurrent.threadDelay oneSecond+ produce (n-1) chan
+ Examples/Example03.hs view
@@ -0,0 +1,29 @@++module Control.Concurrent.Futures.Example03 where+import qualified Control.Concurrent.Futures.QSem as QSem+import qualified Control.Concurrent.Futures.Futures as Futures+import Control.Concurrent++-- local finals+oneSecond = 1000000++ --------------------------------------------------------------------------------+-- | Scenario Example for quantity semaphores using 'Futures.withFuturesDo'.+qsemExampleF :: IO ()+qsemExampleF = Futures.withFuturesDo qsemExample++-- | Scenario Example for for quantity semaphores.+qsemExample :: IO ()+qsemExample = do+ putStrLn $ "Scenario example with quantity semaphores"+ qsem <- QSem.newQSem 1+ Control.Concurrent.forkIO $ (useQSem qsem)+ Control.Concurrent.forkIO $ (useQSem qsem)+ Control.Concurrent.threadDelay $ 10 * oneSecond++useQSem ::QSem.QSem -> IO ()+useQSem q = do+ QSem.down q+ putStrLn $ "Entered."-- ++ show Control.Concurrent.myThreadId+ Control.Concurrent.threadDelay $ 2 * oneSecond+ QSem.up q
+ Examples/Example04.hs view
@@ -0,0 +1,40 @@++module Control.Concurrent.Futures.Example04 where+import qualified Control.Concurrent.Futures.BChan as BChan+import qualified Control.Concurrent.Futures.Futures as Futures+import Control.Concurrent++-- local finals+oneSecond = 1000000++ --------------------------------------------------------------------------------+-- | Producer Consumer Example for bounded channels using 'Futures.withFuturesDo'.+bchannelExampleF :: IO ()+bchannelExampleF = return () --Futures.withFuturesDo bchannelExample++-- | Producer Consumer Example for bounded channels.+bchannelExample :: IO ()+bchannelExample = do+ putStrLn $ "Producer-Consumer example with channels"+ channel <- BChan.newBChan 5+ Control.Concurrent.forkIO $ (produceb 10 channel)+ Control.Concurrent.forkIO $ (consumeb channel)+ Control.Concurrent.threadDelay $ 10 * oneSecond++--consumeb :: (Show a) => BChan.BChan a -> IO b+consumeb chan = do+ putStrLn $ "Trying to read..."+ val <- BChan.readBChan chan+ putStrLn $ "read new value: " ++ show val+ Control.Concurrent.threadDelay oneSecond+ consumeb chan+ return ()++--produceb :: (Num a) => a -> BChan.BChan a -> IO ()+produceb n chan = do+ case n of+ 0 -> BChan.writeBChan chan n+ otherwise -> do+ BChan.writeBChan chan n+ Control.Concurrent.threadDelay oneSecond+ produceb (n-1) chan
+ Examples/Example05.hs view
@@ -0,0 +1,29 @@++module Control.Concurrent.Futures.Example05 where+import qualified Control.Concurrent.Futures.HQSem as HQSem+import qualified Control.Concurrent.Futures.Futures as Futures+import Control.Concurrent++-- local finals+oneSecond = 1000000+ + --------------------------------------------------------------------------------+-- | Scenario Example for quantity semaphores using 'Futures.withFuturesDo'.+hqsemExampleF :: IO ()+hqsemExampleF = Futures.withFuturesDo hqsemExample++-- | Scenario Example for for quantity semaphores.+hqsemExample :: IO ()+hqsemExample = do+ putStrLn $ "Scenario example with quantity semaphores"+ qsem <- HQSem.newHQSem 1+ Control.Concurrent.forkIO $ (useQSem qsem)+ Control.Concurrent.forkIO $ (useQSem qsem)+ Control.Concurrent.threadDelay $ 10 * oneSecond++useQSem :: HQSem.HQSem -> IO ()+useQSem q = do+ HQSem.downHQSem q+ putStrLn $ "Entered."-- ++ show Control.Concurrent.myThreadId+ Control.Concurrent.threadDelay $ 2 * oneSecond+ HQSem.upHQSem q
+ Examples/Example06.hs view
@@ -0,0 +1,42 @@++module Control.Concurrent.Futures.Example06 where+import Control.Concurrent.Futures.Buffer+import Control.Concurrent+import IO+import Data.List++-- | a binary tree data structure+data BTree a = BLeaf a + | BNode a+ (BTree a)+ (BTree a)++-- | sum of all nodevalues of a binary tree+concSumB :: (Num a) => BTree a -> IO a+concSumB t = do + putStrLn $ "Sum of nodes and leafs of a binary tree example using buffers"+ result <- newBuf+ case t of+ BLeaf a -> putBuf result a; -- own value+ BNode a t1 t2 -> sumB result t -- calculate recursivly+ out <- getBuf result+ return out++sumB :: (Num a) => Buffer a -> BTree a -> IO ()+sumB mvar tree = do + case tree of + BLeaf a -> putBuf mvar a -- own value+ BNode a t1 t2 -> do+ sem <- newBuf+ forkIO (sumB sem t1) -- compute left section beam+ forkIO (sumB sem t2) -- compute right section beam+ erg1 <-getBuf sem -- get result of left computation+ erg2 <-getBuf sem -- get result of right computation+ putBuf mvar (erg1 + erg2 + a) --return left + right + own value++--test data+treeb = BNode 1 (BNode 24 (BLeaf 2) (BNode 6 (BLeaf 24) (BLeaf 3)))(BNode 33 (BLeaf 7) (BLeaf 8))++--test function +test_concSumB :: IO Integer+test_concSumB = concSumB treeb
+ Examples/Example07.hs view
@@ -0,0 +1,32 @@++module Control.Concurrent.Futures.Example07 where+import qualified Control.Concurrent.Futures.Barrier as Barrier+import qualified Control.Concurrent.Futures.Futures as Futures+import Control.Concurrent++-- local finals+oneSecond = 1000000+ + --------------------------------------------------------------------------------+-- | Example for barrier using 'Futures.withFuturesDo'.+barExampleF :: IO ()+barExampleF = Futures.withFuturesDo barExample++-- | Example for barrier: 4 threads syncinc on the barrier.+barExample :: IO ()+barExample = do+ putStrLn $ "4 Threads syncing on a barrier. This demo takes a bit time."+ bar <- Barrier.newBar 4+ Control.Concurrent.forkIO $ (doSomething 2 bar)+ Control.Concurrent.forkIO $ (doSomething 7 bar)+ Control.Concurrent.forkIO $ (doSomething 10 bar)+ Control.Concurrent.forkIO $ (doSomething 5 bar)+ Control.Concurrent.threadDelay $ 10 * oneSecond++--doSomething :: Int -> Barrier.Bar a -> IO ()+doSomething time bar = do+ Control.Concurrent.threadDelay $ time * oneSecond+ i <- Control.Concurrent.myThreadId+ putStrLn $ show i ++ " syncing."+ Barrier.syncBar bar+ return ()
+ Examples/Examples.hs view
@@ -0,0 +1,201 @@+{- |+Module : <File name or $Header$ to be replaced automatically>+Description : This module provides examples on concurrency abstractions with futures.+Maintainer : mwillig@gmx.de+Stability : experimental+Portability : non-portable (requires Futures)++This module provides examples for concurrency abstractions using futures.+For each abstractions there is one example using 'do' and one+with 'Futures.withFuturesDo'. In the case without 'Futures.withFuturesDo' the +main thread terminates after a while. If we use 'Futures.withFuturesDo' as recommended,+the main thread never stops before its child-threads.+-}++module Control.Concurrent.Futures.Examples (+ bufferExampleF,+ bufferExample,+ channelExampleF,+ channelExample,+ bchannelExampleF,+ bchannelExample,+ qsemExampleF,+ qsemExample,+ hqsemExampleF,+ hqsemExample,+ barExampleF,+ barExample+-- tsExample+ ) where++import qualified Control.Concurrent.Futures.Futures as Futures+import qualified Control.Concurrent.Futures.Buffer as Buffer+import qualified Control.Concurrent.Futures.Chan as Chan+import qualified Control.Concurrent.Futures.BChan as BChan+import qualified Control.Concurrent.Futures.QSem as QSem+import qualified Control.Concurrent.Futures.Barrier as Barrier+import qualified Control.Concurrent.Futures.HQSem as HQSem+import Control.Concurrent++import Data.List++-- local finals+oneSecond = 1000000++-- | Producer Consumer example with buffers demonstrating 'Futures.withFuturesDo'.+bufferExampleF:: IO ()+bufferExampleF = Futures.withFuturesDo bufferExample++-- | Producer Consumer example with buffers.+bufferExample :: IO ()+bufferExample = do+ putStrLn $ "Producer-Consumer example with buffers"+ b <- Buffer.newBuf+ Control.Concurrent.forkIO $ (writeBufferThread b)+ Control.Concurrent.forkIO $ (readBufferThread b)+ Control.Concurrent.threadDelay $ 10 * oneSecond++writeBufferThread b = do+ Buffer.putBuf b 1+ Buffer.putBuf b 2+ Buffer.putBuf b 3++readBufferThread b = do + val <- Buffer.getBuf b+ putStrLn $ "read: " ++ show val+ Control.Concurrent.threadDelay oneSecond+ readBufferThread b++--------------------------------------------------------------------------------+-- | Producer Consumer Example for channels using 'Futures.withFuturesDo'.+channelExampleF :: IO ()+channelExampleF = Futures.withFuturesDo channelExample++-- | Producer Consumer Example for channels.+channelExample :: IO ()+channelExample = do+ putStrLn $ "Producer-Consumer example with channels"+ channel <- Chan.newChan+ Control.Concurrent.forkIO $ (produce 10 channel)+ Control.Concurrent.forkIO $ (consume channel)+ Control.Concurrent.threadDelay $ 10 * oneSecond++consume :: (Show a) => Chan.Chan a -> IO b+consume chan = do+ putStrLn $ "Trying to read..."+ val <- Chan.readChan chan+ putStrLn $ "read new value: " ++ show val+ Control.Concurrent.threadDelay oneSecond+ consume chan++produce :: (Num a) => a -> Chan.Chan a -> IO ()+produce n chan = do+ case n of+ 0 -> Chan.writeChan chan n+ otherwise -> do+ Chan.writeChan chan n+ Control.Concurrent.threadDelay oneSecond+ produce (n-1) chan+ + --------------------------------------------------------------------------------+-- | Scenario for quantity semaphores using 'Futures.withFuturesDo'.+qsemExampleF :: IO ()+qsemExampleF = Futures.withFuturesDo qsemExample++-- | Scenario for for quantity semaphores with buffers.+qsemExample :: IO ()+qsemExample = do+ putStrLn $ "Scenario example with quantity semaphores"+ qsem <- QSem.newQSem 1+ Control.Concurrent.forkIO $ (useQSem qsem)+ Control.Concurrent.forkIO $ (useQSem qsem)+ Control.Concurrent.threadDelay $ 10 * oneSecond++useQSem ::QSem.QSem -> IO ()+useQSem q = do+ QSem.down q+ i <- Control.Concurrent.myThreadId+ putStrLn $ show i ++ " entered."+ Control.Concurrent.threadDelay $ 2 * oneSecond+ QSem.up q+ + --------------------------------------------------------------------------------+-- | Scenario for handled quantity semaphores using 'Futures.withFuturesDo'.+hqsemExampleF :: IO ()+hqsemExampleF = Futures.withFuturesDo hqsemExample++-- | Scenario for handled quantity semaphores.+hqsemExample :: IO ()+hqsemExample = do+ putStrLn $ "Scenario with quantity semaphores with handles"+ qsem <- HQSem.newHQSem 1+ Control.Concurrent.forkIO $ (useHQSem qsem)+ Control.Concurrent.forkIO $ (useHQSem qsem)+ Control.Concurrent.threadDelay $ 10 * oneSecond++useHQSem :: HQSem.HQSem -> IO ()+useHQSem q = do+ HQSem.downHQSem q+ i <- Control.Concurrent.myThreadId+ putStrLn $ show i ++ " entered."+ Control.Concurrent.threadDelay $ 2 * oneSecond+ HQSem.upHQSem q+++ + --------------------------------------------------------------------------------+-- | Example for barrier using 'Futures.withFuturesDo'.+barExampleF :: IO ()+barExampleF = Futures.withFuturesDo barExample++-- | Example for barrier: 4 threads syncinc on the barrier.+barExample :: IO ()+barExample = do+ putStrLn $ "4 Threads syncing on a barrier. This demo takes a bit time."+ bar <- Barrier.newBar 4+ Control.Concurrent.forkIO $ (doSomething 7 bar)+ Control.Concurrent.forkIO $ (doSomething 12 bar)+ Control.Concurrent.forkIO $ (doSomething 2 bar)+ Control.Concurrent.forkIO $ (doSomething 20 bar)+ Control.Concurrent.threadDelay $ 10 * oneSecond++--doSomething :: Int -> Barrier.Bar a -> IO ()+doSomething time bar = do+ Control.Concurrent.threadDelay $ time * oneSecond+ i <- Control.Concurrent.myThreadId+ putStrLn $ show i ++ " syncing."+ Barrier.syncBar bar+ return ()++ + --------------------------------------------------------------------------------+-- | Producer Consumer Example for bounded channels using 'Futures.withFuturesDo'.+bchannelExampleF :: IO ()+bchannelExampleF = return () --Futures.withFuturesDo bchannelExample++-- | Producer Consumer Example for bounded channels.+bchannelExample :: IO ()+bchannelExample = do+ putStrLn $ "Producer-Consumer example with channels"+ channel <- BChan.newBChan 5+ Control.Concurrent.forkIO $ (produceb 10 channel)+ Control.Concurrent.forkIO $ (consumeb channel)+ Control.Concurrent.threadDelay $ 10 * oneSecond++--consumeb :: (Show a) => BChan.BChan a -> IO b+consumeb chan = do+ putStrLn $ "Trying to read..."+ val <- BChan.readBChan chan+ putStrLn $ "read new value: " ++ show val+ Control.Concurrent.threadDelay oneSecond+ consumeb chan+ return ()++--produceb :: (Num a) => a -> BChan.BChan a -> IO ()+produceb n chan = do+ case n of+ 0 -> BChan.writeBChan chan n+ otherwise -> do+ BChan.writeBChan chan n+ Control.Concurrent.threadDelay oneSecond+ produceb (n-1) chan
caf.cabal view
@@ -1,5 +1,5 @@ Name: caf-Version: 0.0.1+Version: 0.0.2 Description: This library contains implementations of several kinds of futures and concurrency abstractions. License: BSD3 License-file: LICENSE@@ -9,8 +9,17 @@ Stability: experimental Synopsis: A library of Concurrency Abstractions using Futures. Category: Concurrency+homepage: http://sites.google.com/site/cafwiki/ Cabal-Version: >= 1.2 Extra-Source-Files: README+ Examples/Example01.hs+ Examples/Example02.hs+ Examples/Example03.hs+ Examples/Example04.hs+ Examples/Example05.hs+ Examples/Example06.hs+ Examples/Example07.hs+ Examples/Examples.hs library Exposed-Modules: Control.Concurrent.Futures Control.Concurrent.Futures.Futures