> On Apr 19, 2017, at 2:34 AM, Daniel Gaspary <dgasp...@gmail.com> wrote:
> 
> Using  SetJmp and LongJmp?
> 
> I believe some months ago it was a discussion on the list on why this
> was not really the way to implement coroutines.
> 
> Searching for longjmp/setjmp you can find the thread, I guess.

I never heard of those functions and I did find a thread about them but it 
seemed inconslusive. 

Here’s a little test I made not knowing exactly how those functions work. I 
expected the stack to be restored and “i” incremented but that’s not what 
happens. The program jumps in and out of the loop but “i” remains the same each 
time. Is this not how to use those functions?

type
        TCoroutine = class (TObject)
                public
                        procedure Start;
                        procedure Yield;
                        procedure Resume;
                private
                        entry: jmp_buf;
                        env: jmp_buf;
                        passes: longint;
                        yieldNext: boolean;
        end;
        
procedure TCoroutine.Start;
var
        i: integer = 0;
begin
        Setjmp(entry);
        if passes > 0 then
                exit;
        writeln('start');
        while i < 10 do
                begin
                        writeln('loop ', i);
                        i += 1;
                        Setjmp(env);
                        if not yieldNext then
                                Yield;
                        yieldNext := false;
                end;
end;

procedure TCoroutine.Yield;
begin
        writeln('yield');
        passes += 1;
        yieldNext := false;
        Longjmp(entry, 1);
end;

procedure TCoroutine.Resume;
begin
        writeln('resume');
        yieldNext := true;
        Longjmp(env, 1);
end;
        
procedure CoroutineTest; 
var
        co: TCoroutine;
        i: integer;
begin
        co := TCoroutine.Create;
        co.Start;
        writeln('stepped out');
        for i := 0 to 4 do
                co.Resume;
        writeln('finished');
end;


========

start
loop 0
yield
stepped out
resume
loop 1
yield
resume
loop 1
yield
resume
loop 1
yield
resume
loop 1
yield
resume
loop 1
yield
finished


Regards,
        Ryan Joseph

_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply via email to