[Haskell-cafe] Timeout exceptions sometimes don't work, even in pure (non FFI) code
job.vranish at gmail.com
Tue Feb 1 18:02:03 CET 2011
Hmm, that's good to know.
It looks like it also works for most data dependency cases.
works = let
a = b
b = 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
Thanks for your help,
On Tue, Feb 1, 2011 at 11:18 AM, Daniel Fischer <
daniel.is.fischer at googlemail.com> 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
> 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
> > I'm using ghc 6.12.2
> > Thanks,
> > - Job
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Haskell-Cafe