Hmm, that's good to know. It looks like it also works for most data dependency cases.
works = let a = b b = a in a main = timeout 1 $ evaluate $ works This terminates even with optimizations. So I think I'll be able to work around it. I wish timeout worked a little more consistently. This behavior is quite annoying. Thanks for your help, - Job On Tue, Feb 1, 2011 at 11:18 AM, Daniel Fischer < [email protected]> wrote: > On Tuesday 01 February 2011 16:40:43, Job Vranish wrote: > > I'm trying to test some properties with quickcheck. If these tests fail, > > they will almost certainly fail by nontermination. > > I've been using the 'within' function to catch these nontermination > > cases. However, I was surprised to find that this doesn't always work. > > 'within' uses the 'timeout' function under the hood. Here is an example > > that demonstrates the problem: > > > > import System.Timeout > > import Control.Exception > > > > works :: Int -> Int > > works x = sum $ cycle [x] > > > > doesntWork :: Int -> Int > > doesntWork x = last $ cycle [x] > > > > test1 = timeout 1 $ evaluate $ works 5 == 5 -- terminates > > test2 = timeout 1 $ evaluate $ doesntWork 5 == 5 -- never terminates > > > > > > test1 returns Nothing as expected, but test2 never terminates. Why? > > When compiled with optimisations, works doesn't terminate either. > > I believe it's because works actually does some work and allocations > (without optimisations), while doesntWork is a non-allocating loop. > GHC only makes context switches on allocations, so with a non-allocating > loop, the timeout thread never gets to run to see whether the time limit is > exceeded. > Without optimisations, sum allocates thunks, with optimisations it becomes > a tight loop not hitting the heap. `last $ cycle [x]' becomes a tight loop > even without optimisations. > > > > > I thought timeout exceptions are supposed to always work with pure (non > > FFI) Haskell code. > > Is there any way I can work around this? > > Make sure your tests always allocate, or write them as IO stuff and call > yield (or threadDelay) within the loops to let GHC make some context > switches. > > > > > I'm using ghc 6.12.2 > > > > Thanks, > > > > - Job > >
_______________________________________________ Haskell-Cafe mailing list [email protected] http://www.haskell.org/mailman/listinfo/haskell-cafe
