[m-dev.] for review: stream I/O
Fergus Henderson
fjh at cs.mu.OZ.AU
Tue Oct 3 13:06:00 AEDT 2000
On 03-Oct-2000, Fergus Henderson <fjh at cs.mu.OZ.AU> wrote:
> > > - one to use when you don't care about the order of side
> > > effects, even though they may influence the result
> >
> > :- pred io__join(io__state::di, io__state::di, io__state::uo) is cc_multi.
> >
> > Okay, this needs a bit of work...
>
> Well, `spawn' in extras/concurrency/spawn.m provides one way of doing this.
> And if you just want
(Sorry, that was incomplete. Here's what I meant to say:)
If you want a way of doing this without introducing multiple threads,
i.e. you just want to give the compiler permission to reorder the
operations without actually forcing it to create a new thread,
then we could provide something like this:
:- pred io__split(pred(T, io__state, io__state, io__state, io__state),
T, io__state, io__state).
:- mode io__split(pred(out, di, uo, di, uo) is cc_multi,
out, di, uo) is cc_multi.
:- mode io__split(pred(out, di, uo, di, uo) is det,
out, di, uo) is cc_multi.
%
% Operationally, io__split(Pred, Result, ...) just calls
% Pred(Result, ...), passing it two pairs of io__states.
% The side effects of the operations on each pair
% occur in the order that those operations are called.
% So if the strict sequential operational semantics is
% requested, the order is completely specified, but in
% general the order will be unspecified.
% io__split does not create a new thread.
%
% Declaratively, io__split(Pred, Result, IO0, IO) is true
% iff Pred(Result, IOA0, IOA, IOB0, IOB) is true, where
% IOA0 and IOB0 are identical to IO0 except that they
% each reflect the fact that the io__state has been split
% (and hence operations on IOB0 can affect the results of
% operations on IOA0 and vice versa),
% and where IO is formed from IO0 by interleaving in any order
% the two sequences of I/O actions that were applied to get
% (1) from IOA0 to IOA and (2) from IOB0 to IOB.
%
:- implementation.
:- pred io__fork_states(io__state::di, io__state::uo, io__state::uo) is det.
:- pred io__join_states(io__state::di, io__state::di, io__state::uo) is cc_multi.
:- pragma c_code(io__fork_states(_IO0::di, _IOA0::uo, _IOB0::uo),
[thread_safe, will_not_call_mercury], "").
:- pragma c_code(io__join_states(_IOA::uo, _IOB::uo, _IO::di),
[thread_safe, will_not_call_mercury], "").
io__split(Pred, Result, IO0, IO) :-
io__fork_states(IO0, IOA0, IOB0),
Pred(Result, IOA0, IOA, IOB0, IOB),
io__join_states(IOA, IOB, IO).
Note that it's not safe to export io__fork_states and io__join_states,
since that would lead to semantic problems if io__fork_states is
called without a corresponding call to io__join_states, just like the
problem with stream__init/stream__destroy.
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3 | -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to: mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions: mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------
More information about the developers
mailing list