awaitEval in Concurrent Haskell
Colin Runciman
colin@cs.york.ac.uk
Thu, 06 Feb 2003 17:52:28 +0000
Simon,
>Next idea is to have a function
> await :: a -> b -> b
>which is rather like 'seq' except that it waits for its first argument
>to be evaluated, whereas 'seq' evaluates it. Then you could write a new
>version of 'length' which used await before every case expression. Is
>that what you had in mind? A bit fragile, isn't it?
>
Something like await would be enough I think. It would not be
necessary to write new
versions of all the functions to be data driven, just a single
(overloaded) function
to convert a demanding function into a data-driven one. Something like this:
asEvaluated xs = await xs (case xs of
(x:xs) -> asEvaluated x :
asEvaluated xs
[] -> [])
dataDriven f = f . asEvaluated
assert p xs = thread (... dataDriven p xs ...) xs
>How to implement 'await'. We thought of three ways:
>
>1. Implement a primitive checkEval :: a -> Bool, which tells whether
>something is evaluated; if not, it yields to other threads, as well as
>returning False. So now you can have a busy-wait version of await thus:
>
> await x y = case checkEval x of
> True -> y
> False -> await x y
>
>2. Implement await directly, by putting the thread in a pool of threads
>that the scheduler checks at regular intervals. They each just "watch" a
>thunk. Still a busy-waiting solution.
>
>3. Do the "right thing": implement 'await' by copying the thunk,
>replacing it by a "smart indirection" which also points to the
>non-suspended thread. When the indirection is evaluated, it just puts
>the suspended thread in the runnable pool before entering the thunk.
>Actually, this is probably no harder than (2).
>
I agree that 2 seems the most straightfoward, and not quite so busy as 1.
Unless I am misunderstanding 3 it could lead to problems if scheduling
can occur before evaluation of the thunk reaches a normal form.
>Now, it's true that it would take Simon or I less time to implement one
>of these than it would take your student to do, but we have so *many*
>things to implement, and each takes time. And you will probably change
>your mind several times about what the right design should be (that's
>what research is like). So there's a lot to be said for the wading in
>yourself.
>
The formula for implementation time is roughly
initiationRites + inherentDifficulty / skillLevel
and I am pretty sure we could get by with just the await primitive.
So if there is any way you could find an early slot to do a
basic implementation of await, it would be much appreciated.
>What I can promise is that we'd turn around questions rapidly.
>
If we do end up trying to define await for ourselves, which source
files should we expect to modify and are there any likely pitfalls
in the subsequent rebuilding?
Thanks
Colin R