[m-rev.] for second review: Add future datatype for concurrent and parallel programming

Peter Wang novalazy at gmail.com
Thu Oct 9 15:30:21 AEDT 2014


Hi,

Just some minor things.

> +:- impure pred run_future(future(T), (func) = T).
> +:-        mode run_future(in, ((func) = out) is det) is cc_multi.
> +
> +run_future(future(Future), Func) :-
> +    (
> +        try [] (
> +            Result = apply(Func)
> +        )
> +        then (
> +            impure signal(Future, ok(Result))
> +        )
> +        catch_any Exp -> (
> +            impure signal(Future, 'new exception'(Exp))
> +        )
> +    ).

I think it looks better like this:

run_future(future(Future), Func) :-
    ( try []
	Result = apply(Func)
      then
        impure signal(Future, ok(Result))
      catch_any Excp ->
        impure signal(Future, 'new exception'(Excp))
    ).

> +
> +:- type future_io(T)
> +    --->    future_io(
> +                f_ready         :: mutvar(ready),
> +                    % f_ready is used to optimistically avoid locking.  It
> +                    % is also used to try to detect multiple calls to
> +                    % signal/2.
> +
> +                f_wait          :: semaphore,
> +                f_value         :: mutvar(T)
> +            ).

Unindent the comment.

> +%-----------------------------------------------------------------------------%
> +
> +:- pragma promise_pure(signal/4).
> +
> +signal(Future, Value, !IO) :-
> +    impure signal(Future, Value).
> +
> +:- impure pred signal(future_io(T)::in, T::in) is det.
> +
> +signal(future_io(MReady, Wait, MValue), Value) :-
> +    impure get_mutvar(MReady, Ready),
> +    (
> +        Ready = not_ready,
> +        impure set_mutvar(MValue, Value),
> +        % TODO: Implement signal_all.
> +        impure semaphore.impure_signal(Wait),
> +        impure set_mutvar(MReady, ready)

Add a comment for why MReady must be set after signalling Wait.

> +    ;
> +        Ready = ready,
> +        % It is possible that another thread has called signal/2 but we read
> +        % Ready before it wrote it, resulting in multiple calls to signal/2.
> +        % Therefore we do not guarantee that we will always detect multiple
> +        % calls and will not always throw this exception.
> +        error("Multiple calls to thread.future.signal/2")
> +    ).
> +

> diff --git a/library/thread.m b/library/thread.m
> index 154a268..9864cf6 100644
> --- a/library/thread.m
> +++ b/library/thread.m
> @@ -1,8 +1,9 @@
>  %-----------------------------------------------------------------------------%
>  % vim: ft=mercury ts=4 sw=4 et
>  %-----------------------------------------------------------------------------%
> -% Copyright (C) 2000-2001, 2003-2004, 2006-2008, 2010-2011, 2014 The
> -% University of Melbourne.
> +% Copyright (C) 2000-2001, 2003-2004, 2006-2008, 2010-2011 The % University
> +% of Melbourne.
> +% Copyright 2014 The Mercury Team.

Extra %

Peter



More information about the reviews mailing list