--- Dave Whipp <[EMAIL PROTECTED]> wrote:
> "Austin Hastings" <[EMAIL PROTECTED]> wrote:
> > 1. C<yield> always acts the same way -- stores args in
> CurThread.result
> > and gives up control to [?something?].
>
> I think you want a fifo on the output there -- at least conceptually.
> "Stores args in .result" might overly block the producer thread.
Why would it "overly" block? If you say C<yield>, I assume you I<want>
to block -- else, why not use a shared var?
> "gives up control to" -- the "something" would be the scheduler
> that's associated with the fifo. When you have a fifo, you don't
> need to switch control on every iteration. In fact, if you're a
> thread on a multi-cpu machine, you might never yield control.
Of course you will -- *IF* you say C<yield>. Using a fifo is different
from being a coro. If you want to say
loop {
$res = compute();
@fifo.unshift $res;
}
that's fine -- but it has nothing to do with being a coro or a thread
(although it's kind of destined to be a thread...).
If you say C<yield> in a _thread_, then you're relinquishing control to
the scheduler and optionally setting the result of the thread. If the
scheduler is a round robin preempter, well, no big deal -- some time
goes by and you start again. If the scheduler considers yield to be
synonymous with snap, then the thread is snapped until someone
C<resume>s it. (Frankly, I have no earthly idea why anyone would yield
in a preemptively scheduled thread, unless they are spinwaiting, in
which case they deserve whatever they get. But the behavior is
documented for both.)
> But at the other end of the spectrum, a coro would optimize out the
> fifo and switch contexts every time.
Exactly, save for the context switch: It's not a thread, but a
continuation. A coroutine executes in the same control sequence and the
same variable "environment" as its coroutine. (Look, reflexive noun!
Argh!) Even in a threaded environment, a simple coro should guarantee
sequence of execution with its caller.
That makes me think that the notion of a "cothread" is a valid one -- a
thread that runs in apparent parallel, but suspends completely when it
calls yield. Probably this requires implementing a new thread
scheduler, which can be implemented in perl, not core. This, at least,
should make Simon happy.
> Has any given thought to how the pipeline syntax of A6 might interact
> with this stuff? How would we attach multiple output fifos to a
> "cothread"? Multiple inputs?
>
> cothread foo is input($a,$b,$c) is output($x,$y,$z)
> {
> when $a { $x.yield $a+1 }
> when $b & $c { $y.yield $b+$c; $z.yield $b-$c }
> }
According to me:
my @a, @b, @c;
my @x, @y, @z;
sub foo {
loop {
given wait any(@a, all(@b, @c)) {
when @a { @x.unshift @a.pop; }
default { my $b = @b.pop; my $c = @c.pop;
@y.unshift $b + $c;
@z.unshift $b - $c; }
}
}
}
thread foo;
thread {
for (0..Inf) { ($_ % 7 ?? $_ % 3 ?? @a :: @b :: @c).push $_; }
};
thread {
loop {
wait @x;
print "X: ", @x.pop, "\n";
}
};
thread {
loop {
wait @y;
print "Y: ", @y.pop, "\n";
}
};
thread {
loop {
wait @z;
print "Z: ", @z.pop, "\n";
}
};