--- 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";
  }
};


Reply via email to