unamb 0.2.4 → 0.2.5
raw patch · 6 files changed
+9/−108 lines, 6 filesdep ~base
Dependency ranges changed: base
Files
- Makefile +0/−3
- README +0/−25
- src/Data/Unamb.hs +6/−6
- tests/TestRace.hs +0/−35
- unamb.cabal +3/−3
- wikipage.tw +0/−36
− Makefile
@@ -1,3 +0,0 @@-extra-configure-args = -ftest--include ../cho-cabal-make.inc
− README
@@ -1,25 +0,0 @@-unamb [1] contains the "unambiguous choice" operator "unamb" [2], which-wraps thread racing up in a purely functional, semantically simple-wrapper. Given any two arguments u and v that agree unless bottom, the-value of unamb u v is the more terminating of u and v. Operationally, the-value of unamb u v becomes available when the earlier of u and v does.-The agreement precondition ensures unamb's referential transparency.--unamb was originally a part of Reactive [3]. I moved it to its own-package in order to encourage experimentation.--Please share any comments & suggestions on the discussion (talk) page at-[1].--You can configure, build, and install all in the usual way with Cabal-commands.-- runhaskell Setup.lhs configure- runhaskell Setup.lhs build- runhaskell Setup.lhs install--References:--[1] http://haskell.org/haskellwiki/unamb-[2] http://conal.net/papers/simply-reactive-[3] http://haskell.org/haskellwiki/reactive
src/Data/Unamb.hs view
@@ -39,7 +39,7 @@ import System.IO.Unsafe import Control.Monad.Instances () -- for function functor import Control.Concurrent-import Control.Exception+import Control.Exception hiding (unblock) import Data.Typeable -- Drop the unsafeIsEvaluated optimization for now. See comments below.@@ -141,7 +141,7 @@ retry act = act `catch` \ (SomeException e) -> do myThreadId >>= flip throwTo e- unblock $ retry act+ mask_ $ retry act -- | n-ary 'unamb'@@ -216,9 +216,9 @@ -- This version kills descendant threads when killed, but does not restart -- any work if it's called by unamb. That code is left in unamb. -race a b = block $ do+race a b = mask_ $ do v <- newEmptyMVar- let f x = forkIO $ putCatch (unblock x) v+ let f x = forkIO $ putCatch (mask_ x) v ta <- f a tb <- f b let cleanup = throwTo ta DontBother >> throwTo tb DontBother@@ -226,7 +226,7 @@ loop t = do x <- takeMVar v case x of Nothing -> loop (t-1) Just x' -> return x'- unblock (loop (2 :: Int) `finally` cleanup)+ mask_ (loop (2 :: Int) `finally` cleanup) -- A thread can bottom-out efficiently by throwing that exception.@@ -363,7 +363,7 @@ {-# INLINE pmax #-} -- | Parallel multiplication with 0 short-circuit, and 1 identity-pmult :: Num a => a -> a -> a+pmult :: (Eq a, Num a) => a -> a -> a pmult = parAnnihilatorIdentity (*) 0 1 {-# INLINE pmult #-}
− tests/TestRace.hs
@@ -1,35 +0,0 @@-{-# OPTIONS_GHC -Wall #-}---- TestRace.hs. Compile & run:--- ghc --make -threaded TestRace.hs--- ./TestRace +RTS -N2---- Before http://hackage.haskell.org/trac/ghc/ticket/2910 was resolved,--- the mapM_ test printed consecutive natural numbers for a while, and--- then got stuck. Seemed to run fine without -threaded/N2--import Prelude hiding (catch)--import Data.Unamb--import System.IO.Unsafe--- import Control.Monad.Instances () -- for function functor-import Control.Concurrent--- import Control.Exception--test :: Int -> Int-test x = f (f x) where f v = (x `unamb` v) `seq` v--main :: IO ()--- main = print sparse--main = mapM_ (print . test) [0..]----- Luke Palmer's stress test-sparse :: ()-sparse =- foldr1 unamb [ if x == (10000 :: Integer) then () else blockForever | x <- [0..] ]- where- blockForever = unsafePerformIO $- newEmptyMVar >>= takeMVar
unamb.cabal view
@@ -1,5 +1,5 @@ Name: unamb-Version: 0.2.4+Version: 0.2.5 Cabal-Version: >= 1.2 Synopsis: Unambiguous choice Category: Concurrency, Data, Other@@ -11,7 +11,7 @@ . Project wiki page: <http://haskell.org/haskellwiki/unamb> .- © 2008 by Conal Elliott; BSD3 license.+ © 2008-2012 by Conal Elliott; BSD3 license. . Contributions from: Luke Palmer, Spencer Janssen, Sterling Clover, Bertram Felgenhauer, Peter Verswyvelen, Svein Ove Aas, and Edward Kmett.@@ -20,7 +20,7 @@ Maintainer: conal@conal.net Homepage: http://haskell.org/haskellwiki/unamb Package-Url: http://code.haskell.org/unamb-Copyright: (c) 2008 by Conal Elliott+Copyright: (c) 2008-2012 by Conal Elliott License: BSD3 Stability: experimental build-type: Simple
− wikipage.tw
@@ -1,36 +0,0 @@-[[Category:Packages]]-[[Category:Concurrency]]--== Abstract ==--'''unamb''' is a package containing the ''unambiguous choice'' operator <hask>unamb</hask>, which wraps thread racing up in a purely functional, semantically simple wrapper.-Given any two arguments <hask>u</hask> and <hask>v</hask> that agree unless bottom, the value of <hask>unamb u v</hask> is the more terminating of <hask>u</hask> and <hask>v</hask>.-Operationally, the value of <hask>unamb u v</hask> becomes available when the earlier of <hask>u</hask> and <hask>v</hask> does.-The agreement precondition ensures unamb's referential transparency.-For more info about <hask>unamb</hask> and its use, see the paper ''[http://conal.net/papers/simply-reactive/ Simply Efficient Functional Reactivity]'', sections 10 and 11.--<hask>unamb</hask> was originally a part of [[Reactive]]. I moved it to its own package in order to encourage experimentation.--Besides this wiki page, here are more ways to find out about unamb:-* Visit the [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/unamb Hackage page] for library documentation and to download & install.-* Read [http://conal.net/blog/tag/unamb/ related blog posts].-* Or install with <tt>cabal install unamb</tt>.-* Get the code repository: <tt>darcs get http://code.haskell.org/unamb</tt>.-<!-- * See the [[unamb/Versions| version history]]. -->--<!-- Please leave comments at the [[Talk:unamb|Talk page]]. -->-See also the [[lub]] package, which extends unamb's usefulness with non-flat types.--== Issues ==--Although semantically very simple, unamb has been quite tricky to implement correctly and efficiently.--As of version 0.1.1, unamb requires ghc 6.10 or better.--As of version 0.1.6, unamb correctly handles recursive termination of sub-efforts and automatic restarting, but only with the GHC RTS fixes that first appeared (stably, by my testing) in GHC HEAD version 6.11.20090115.-The problems and solution can be found in a few places:-* Email thread: ''[http://n2.nabble.com/problem-with-unamb----doesn%27t-kill-enough-threads-tt1674917.html Problem with unamb -- doesn't kill enough threads]''-* Blog post: ''[http://conal.net/blog/posts/smarter-termination-for-thread-racing/ Smarter termination for thread racing]''-* Email thread: ''[http://n2.nabble.com/Re%3A-black-hole-detection-and-concurrency-td2016290.htm Black hole detection and concurrency]''--unamb seems to be working well in version 0.2.2, under GHC 6.10.3.